Entwickler-Ecke

Open Source Units - OEMConsole - Zeichensatzkonvertierung f. Konsolenanwendungen


Martok - Mi 07.07.10 03:42
Titel: OEMConsole - Zeichensatzkonvertierung f. Konsolenanwendungen
Wer öfter mal {$APPTYPE CONSOLE} nutzt, und seine Konsole dabei auf der Standard-Rasterschriftart stehen hat, kennt bestimmt das Problem: Sonderzeichen, besonders Umlaute, gehen kaputt.

Schuld ist hier, dass Delphi Strings in ANSI-Zeichen ausgibt, die Console aber OEM (Codepage 850) will.

Diese Unit erspart einem das händische Umwandeln jeder Ausgabe, indem die Ausgabefunktionen so umgelenkt werden, dass jeder Buffer automatisch konvertiert wird.


Bugreports etc sind gern gesehen, auch wenn ich nicht glaube, dass in 104LOC so viele drin sein können :zwinker:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
begin
  Writeln('Hänschen ist müde');
  InstallOEMConsole;
  Writeln('Hänschen ist müde');
  UnInstallOEMConsole;
  Writeln('Hänschen ist müde');
  Readln;
end.

Ausgabe:

Quelltext
1:
2:
3:
Hõnschen ist m³de
Hänschen ist müde
Hõnschen ist m³de


jaenicke - Mi 07.07.10 05:38

Kleine Korrektur:

Delphi-Quelltext
1:
2:
3:
4:
procedure DoWork(var F: TTextRec);
begin
  CharToOemBuffA(F.BufPtr,F.BufPtr, F.BufPos);
end;
Sonst funktioniert es mit Delphi 2010 z.B. nicht. ;-)


delfiphan - Mi 07.07.10 09:55

Man muss aber beachten, dass, wenn man den Output in ein File umleitet, die Textdatei dann auch 850 codiert ist. -> Lösungsansatz: Liefert GetConsoleMode false zurück, dann soll InstallOEMConsole nichts ändern, da in ein File geschrieben wird.

Alternativ hätte man WriteConsole(W) (mit GetStdHandle(STD_OUTPUT_HANDLE)) verwenden können (Unicode support). WriteConsole unterstützt das Schreiben in ein File nicht. Da müsste man dann doch wieder eine Fallunterscheidung machen.


Gammatester - Mi 07.07.10 12:30

Funktioniert so erst ab Delphi6.

Ein sinnvoller Zusatz: Es wird nicht verhindert, daß man zweimal InstallOEMConsole aufruft und man sich so die geretteten Originalfunktionen zerschießt. Abhilfe mit globaler Variable OEMConsoleInstalled: boolean oder Test, ob Oldfunc bereits die neuen Funktionen enthält.


Martok - Do 08.07.10 00:01

user profile iconGammatester hat folgendes geschrieben Zum zitierten Posting springen:
Funktioniert so erst ab Delphi6.

Warum dieses?
Ich hab D7, bin aber der Meinung dass das in D4 nicht viel anders implementiert wäre.

Danke für die Hinweise, werde ich einbeziehen.

user profile icondelfiphan hat folgendes geschrieben Zum zitierten Posting springen:
Alternativ hätte man WriteConsole(W) (mit GetStdHandle(STD_OUTPUT_HANDLE)) verwenden können (Unicode support).

Stimmt, wäre eventuell sogar sinnvoller, in Zeiten, wo es auch Delphis gibt die Unicode können.
Ich wollte aber die Write()-Compiler-Magic nicht verlieren, daher diese Variante.

EDIT: und fertig, neue Version oben mit euren Hinweisen.