Entwickler-Ecke

Windows API - Sonderzeichen auf der Console


Martok - Mo 05.07.10 20:47
Titel: Sonderzeichen auf der Console
Hallo,

altes Thema und auch schon mehrfach beantwortet, aber leider nie so wirklich ;)

Wenn man per WriteLn versucht, auf die Console zu schreiben, gehen ja Umlaute üblicherweise kaputt.
Abhilfe schafft hier ein SetConsoleOutputCP(1252) WENN man nicht die Rasterschriftart verwendet, oder alternativ jeden einzelnen String durch CharToOEM zu jagen.

Gibts da echt nix anderes?

Wenn ja, hat schonmal jemand einen Runtime-RTL-Patch gebaut, der diese Funktion in _WriteBytes-Aufrufe einbaut?

Grüße,
Martok


jaenicke - Mo 05.07.10 21:04

Schreib dir doch einfach eine eigene WriteLn Funktion. ;-)

Dann reicht es die entsprechende Unit in die uses einzubinden.

ConsoleUtils.pas
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
unit ConsoleUtils;

interface

uses
  Windows;

procedure WriteLn(const Value: string);

implementation

procedure WriteLn(const Value: string);
var
  AsciiValue: string;
begin
  SetLength(AsciiValue, Length(Value));
  CharToOem(PChar(Value), PChar(AsciiValue));
  System.WriteLn(AsciiValue);
end;

end.


BenBE - Mo 05.07.10 21:13

Mal so grob ins Blaue gehackt (ungetestet):


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
function(var t: TTextRect; const b; cnt: Longint): Pointer;
var
  buf: string;
begin
  SetLength(buf, cnt+1);
  CharToOem(PChar(b), PChar(buf));
  asm //Call to some hidden System Procedure ;-)
    mov eax, t
    mov edx, buf
    mov ecx, cnt
    call System.@WriteBytes
  end;
end;


Kann CharToOEM keine Counts, oder müsste man das selber noch bauen? Das Hooken mit uallHook.HookCode sollte man ja hinbekommen. Wie man den Pointer auf die Original-Proc bekommt sieht man ja in meinem Source ;-)


Martok - Mi 07.07.10 00:06

user profile iconBenBE hat folgendes geschrieben Zum zitierten Posting springen:
Kann CharToOEM keine Counts, oder müsste man das selber noch bauen?

Müsste man.

user profile iconBenBE hat folgendes geschrieben Zum zitierten Posting springen:
Wie man den Pointer auf die Original-Proc bekommt sieht man ja in meinem Source ;-)

Nur schade, dass es nicht funktioniert:
Zitat:
[Fehler] Project1.dpr(11): Undefinierter Bezeichner: '@WriteBytes'

Der Name ist laut MapFile aber korrekt, aber: da die nicht im Interface-Teil veröffentlicht ist, will mich der Compiler die nicht im Assembler nutzen lassen. Und in Pascal eh nicht.

Shotgun-Ansatz wäre jetzt, eine Funktion zu suchen, die WriteBytes aufruft, nach deren Adresse zu fragen und von dort aus das JMP zu suchen. Muss das so?

EDIT: Patchen geht nicht (einfach), da müsste man einige near Jumps umschreiben. Bäh.

Was aber geht: die TextIOFunc von Output ändern.
Case Closed, Unit veröffentlicht [http://www.delphi-forum.de/viewtopic.php?p=610760#610760].