chinesische Schriftzeichen nach Zurücksetzen von Komponenten

Für alles, was in den übrigen Lazarusthemen keinen Platz, aber mit Lazarus zutun hat.
Antworten
Benutzeravatar
Cineatic
Beiträge: 21
Registriert: Mo 25. Sep 2023, 10:37
OS, Lazarus, FPC: OS: Windows 10 & 11; Lazarus: 3.6; FPC: 3.2.2
CPU-Target: 64Bit

chinesische Schriftzeichen nach Zurücksetzen von Komponenten

Beitrag von Cineatic »

Hallo!

Ich schreibe derzeit an einem Programm, mit welchem man den Inhalt von Verzeichnissen / Laufwerken in einer textbasierten Datenbankdatei speichern und so zügig gewünschte Dateien wiederfinden kann, egal auf welchem Laufwerk sie liegen.

Nun habe ich auf einmal ein Phänomen, für welches ich keine Lösung finde. Eventuell kennt von euch jemand das Problem.

Die Verzeichnisse werden eingelesen und als erstes in einer TListBox-Komponente angezeigt. Gleichzeitig wird der Name des Verzeichnisses als Vorschlag in eine TLabelEdit Komponente eingetragen. Bis dahin ist alles in Ordnung.

Aber sobald ich das Ganze in einer Datei aufbereitet speichere und mittels

Code: Alles auswählen

 memoFoundFiles.Clear;
 sbReadData.Panels[0].Text := '';
 lbledtArchiv.Clear;    
 
die drei Komponenten TMemo, TStatusBatr und TLabelEdit zurücksetze, erscheinen in beiden Komponenten chinesische Schriftzeichen. Und ich finde nirgends eine Ursache dafür. Zumal diese Zeichen unmittelbar nach dem Zurücksetzen der Komponenten erscheinen. Da finden keine weiteren Befehle zwischendurch statt.

Bild

Was mich dann noch mehr irritiert ist, dass nach dem Schließen des Fensters sogar im Panel des Hauptfensters diese Zeichen auftauchen. Obwohl nirgends im Code auf diese Komponente von der 2. Unit aus zugegriffen wird.

Bild

Wenn ich versuche im Memo die Zeile mit den Schriftzeichen mittels

Code: Alles auswählen

memoFoundFiles.Lines[0] := ''
zu überschreiben, rutschen die Schriftzeichen nur nach unten. Bei den anderen Komponenten könnte ich den Anzeigefehler umgehen, wenn auch unelegant, in dem ich anstatt

Code: Alles auswählen

:= ''
ein Leerzeichen setzen würde.

Im Augenblick behelfe ich mir damit, dass ich das Fenster zum Einlesen und Speichern der Dateien direkt schließe. Aber eigentlich hatte ich es so programmiert, dass das Fenster geöffnet bleibt um direkt weitere Verzeichnisse einlesen zu können.

Als wird der "default"-Font in den Komponenten mit dem default-charset. Der Fehler existiert aber genau so bei dem "ANSI-CHARSET".

Hatte von euch auch schon mal jemand ein solches "chinesisches" Problem?

Tschüss

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6762
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Re: chinesische Schriftzeichen nach Zurücksetzen von Komponenten

Beitrag von af0815 »

Ist der TextHint leer ? Nicht das beim Löschen ein falscher TextHint bei dir auftaucht.
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

Benutzeravatar
Cineatic
Beiträge: 21
Registriert: Mo 25. Sep 2023, 10:37
OS, Lazarus, FPC: OS: Windows 10 & 11; Lazarus: 3.6; FPC: 3.2.2
CPU-Target: 64Bit

Re: chinesische Schriftzeichen nach Zurücksetzen von Komponenten

Beitrag von Cineatic »

Der Hint ist leer. Die chinesischen Zeichen sind in der LableEdit Komponente auch normal editierbar.

Benutzeravatar
Cineatic
Beiträge: 21
Registriert: Mo 25. Sep 2023, 10:37
OS, Lazarus, FPC: OS: Windows 10 & 11; Lazarus: 3.6; FPC: 3.2.2
CPU-Target: 64Bit

Re: chinesische Schriftzeichen nach Zurücksetzen von Komponenten

Beitrag von Cineatic »

Ich habe den Fehler zumindest einkreisen können. Denn da das Problem erst nach dem Speichern der Datenbank-Datei auftaucht, muss der Fehler in einem der folgenden Procedures stecken:


In der ReadAllData-Procedure wird der Inhalt der Verzeichnisse eingelesen und gespeichert:

Code: Alles auswählen

procedure TfrmReadData.ReadAllData(var Directory: String);
var
  OutputFile: TextFile;
  BaseDir, DriveLetter, DriveName: String;

  procedure ListDirectory(Dir: string; RelativePath: string);
  var
    SR: TSearchRec;
    CurrentPath: string;
  begin
    if FindFirst(Dir + DirectorySeparator + '*', faAnyFile, SR) = 0 then
    begin
      repeat
        if (SR.Name <> '.') and (SR.Name <> '..') then
        begin
          CurrentPath := RelativePath + SR.Name;
          if (SR.Attr and faDirectory) = faDirectory then
          begin
            WriteLn(OutputFile, '[V] ' + CurrentPath);
            ListDirectory(Dir + DirectorySeparator + SR.Name, CurrentPath + DirectorySeparator);
          end
          else
          begin
            WriteLn(OutputFile, '[D] ' + CurrentPath);
          end;
        end;
      until FindNext(SR) <> 0;
      FindClose(SR.FindHandle); // Verwende den korrekten Typ für FindClose
    end;
  end;

begin
  // Initialisiere `Directory`
  Directory := IncludeTrailingPathDelimiter(Directory);

  // Ermittlen der Laufwerksinformationen
  GetDriveInfo(DriveLetter, DriveName);

  BaseDir := Directory;

  AssignFile(OutputFile, frmMain.lbledtDataPath.Text + DirectorySeparator + lbledtArchiv.Text + '.cds');
  Rewrite(OutputFile);
  try
    // Laufwerksinformationen speichern
    WriteLn(OutputFile, '[Drive] ' + DriveLetter + ' ' + DriveName);
    // Speichern den gesamten Pfades vom Rootverzeichnis an
    WriteLn(OutputFile, '[Root] ' + BaseDir);
    ListDirectory(BaseDir, '');
    MessageDlg('Hinweis', 'Die Verzeichnisliste wurde erfolgreich gespeichert.', mtInformation, [mbOk], 0);
  finally
    CloseFile(OutputFile);
  end;

end;
Und in der GetDriveInfo-Procedure werden der Laufwerksbuchstabe und -name ausgelesen und an die ReadAllData-Procedure übergeben:

Code: Alles auswählen

procedure TfrmReadData.GetDriveInfo(out DriveLetter, DriveName: string);
var
  Drive: Char;
  VolumeName, FileSystem: string;
  MaxComponentLength, FileSystemFlags: DWORD;
begin
  Drive := UpCase(Directory[1]);
  VolumeName := '';
  FileSystem := '';
  MaxComponentLength := 0;
  FileSystemFlags := 0;
  GetVolumeInformation(PChar(Drive + ':\'), PChar(VolumeName), 255, nil, MaxComponentLength, FileSystemFlags, PChar(FileSystem), 255);
  DriveLetter := Drive + ':';
  DriveName := VolumeName;
end;                      
Ich sehe aber nirgends einen Zugriff auf eine Funktion, welche diese Schriftzeichen erklären würden. Zumal es immer die selben Schriftzeichen sind. Die werden also nicht durch Zufall generiert.

Die verwendeten Units sind:

Code: Alles auswählen

uses
  Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls, ExtCtrls,
  Buttons, ComCtrls, Windows;
 
Vielleicht hat so jemand eine Idee, was da los ist.

Benutzeravatar
Zvoni
Beiträge: 363
Registriert: Fr 5. Jul 2024, 08:26
OS, Lazarus, FPC: Windoof 10 Pro (Laz 2.2.2 FPC 3.2.2)
CPU-Target: 32Bit
Wohnort: BW

Re: chinesische Schriftzeichen nach Zurücksetzen von Komponenten

Beitrag von Zvoni »

Codepage der Datei selbst?
Ein System sie alle zu knechten, ein Code sie alle zu finden,
Eine IDE sie ins Dunkel zu treiben, und an das Framework ewig zu binden,
Im Lande Redmond, wo die Windows drohn.

Benutzeravatar
Cineatic
Beiträge: 21
Registriert: Mo 25. Sep 2023, 10:37
OS, Lazarus, FPC: OS: Windows 10 & 11; Lazarus: 3.6; FPC: 3.2.2
CPU-Target: 64Bit

Re: chinesische Schriftzeichen nach Zurücksetzen von Komponenten

Beitrag von Cineatic »

Da ich nicht explizit eine Codepage gesetzt habe, sollte es CP_ACP sein.

Das Problem mit den Zeichen existiert ja nicht von Anfang an, sondern erst seit dem Zeitpunkt, wo ich auch die Laufwerksinformationen mit auslese. Als ich nur die Pfade ausgelesen habe, tauchten die Schriftzeichen noch nicht auf.

Benutzeravatar
Jorg3000
Lazarusforum e. V.
Beiträge: 359
Registriert: So 10. Okt 2021, 10:24
OS, Lazarus, FPC: Win64
Wohnort: NRW

Re: chinesische Schriftzeichen nach Zurücksetzen von Komponenten

Beitrag von Jorg3000 »

Hi!
Ich glaube in GetDriveInfo() gibt es Murks mit den PChar.
Versuche mal folgendes ... (nicht getestet)

Code: Alles auswählen

procedure TfrmReadData.GetDriveInfo(out DriveLetter, DriveName: String);
var
  Drive: Char;
  DrivePath: String;
  VolumeName, FileSystem: array[0..254] of Char;
  MaxComponentLength, FileSystemFlags: DWORD;
begin
  Drive := UpCase(Directory[1]);
  DriveLetter := Drive + ':';
  DrivePath := DriveLetter +'\';
  
  FillChar(VolumeName, SizeOf(VolumeName), 0); 
  FillChar(FileSystem, SizeOf(FileSystem), 0);
  MaxComponentLength := 0;
  FileSystemFlags := 0;
  DriveName := '';

  if GetVolumeInformation(PChar(DrivePath), VolumeName, Length(VolumeName), nil, MaxComponentLength, FileSystemFlags, FileSystem, Length(FileSystem)) then
  begin 
    DriveName := StrPas(VolumeName);
  end;
end;
Grüße, Jörg

Benutzeravatar
Cineatic
Beiträge: 21
Registriert: Mo 25. Sep 2023, 10:37
OS, Lazarus, FPC: OS: Windows 10 & 11; Lazarus: 3.6; FPC: 3.2.2
CPU-Target: 64Bit

Re: chinesische Schriftzeichen nach Zurücksetzen von Komponenten

Beitrag von Cineatic »

Vielen Dank für den Tipp! "Murks" ist beim coden mein zweiter Vorname 😄

Ich werde das morgen direkt testen.

Benutzeravatar
Cineatic
Beiträge: 21
Registriert: Mo 25. Sep 2023, 10:37
OS, Lazarus, FPC: OS: Windows 10 & 11; Lazarus: 3.6; FPC: 3.2.2
CPU-Target: 64Bit

Re: chinesische Schriftzeichen nach Zurücksetzen von Komponenten

Beitrag von Cineatic »

Jorg3000 hat geschrieben: Mi 18. Dez 2024, 19:49 Hi!
Ich glaube in GetDriveInfo() gibt es Murks mit den PChar.
Versuche mal folgendes ... (nicht getestet)
...
Super! Bei den ersten Tests hatte ich keine Chinesen mehr im Computer.

Nochmals vielen Dank!

Antworten