AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Console: OEM nach ANSI

Ein Thema von Zacherl · begonnen am 13. Jun 2010 · letzter Beitrag vom 13. Jun 2010
Antwort Antwort
Benutzerbild von Zacherl
Zacherl

Registriert seit: 3. Sep 2004
4.629 Beiträge
 
Delphi 10.2 Tokyo Starter
 
#1

Console: OEM nach ANSI

  Alt 13. Jun 2010, 18:10
Hey,

ich lese die Ausgabe einer Konsolenanwendung mit Pipes aus und sende ebenso Eingaben an das Programm. Jetzt muss ich die ausgelesenen Daten von OEM nach ANSI konvertieren, damit Umlaute wie öäüß richtig dargestellt werden können. Momentan versuche ich das folgendermaßen:

Delphi-Quellcode:
function OEM2Ansi(OEMString: AnsiString): AnsiString;
begin
  OEMString := OEMString + #0;
  OemToChar(PAnsiChar(OEMString), @OEMString[1]);
  Delete(OEMString, Length(OEMString), 1);
  Result := OEMString;
end;
Leider hat die Funktion, wie es scheint, einfach komplett keine Wirkung auf meinen ausgelesenen AnsiString.
Das hier ist zum Beispiel einer der Problemkandidaten:
Zitat:
S 'dir'#$D#$A' Datentr„ger in Laufwerk C: ist BOOT'#$D#$A'
In die andere Richtung funktioniert es ebenfalls nicht. Wenn ich Ansi2OEM benutze und den String dann über die Pipe an die Konsole schicke, und z.b. einen Ordner namens "ötest" mit mkdir anlege, wird das ö zu irgendeinem komischen Zeichen konvertiert.

Kennt jemand eine Lösung für dieses Problem?

Viele Grüße
Zacherl
  Mit Zitat antworten Zitat
Benutzerbild von DeddyH
DeddyH

Registriert seit: 17. Sep 2006
Ort: Barchfeld
27.541 Beiträge
 
Delphi 11 Alexandria
 
#2

AW: Console: OEM nach ANSI

  Alt 13. Jun 2010, 18:17
Unter Delphi 2007 funktioniert das hier:
Delphi-Quellcode:
function OEM2ANSI(const aStr: AnsiString): AnsiString;
begin
  Result := aStr;
  OEMToChar(PAnsiChar(Result),PAnsiChar(Result));
end;
Detlef
"Ich habe Angst vor dem Tag, an dem die Technologie unsere menschlichen Interaktionen übertrumpft. Die Welt wird eine Generation von Idioten bekommen." (Albert Einstein)
Dieser Tag ist längst gekommen
  Mit Zitat antworten Zitat
Benutzerbild von Zacherl
Zacherl

Registriert seit: 3. Sep 2004
4.629 Beiträge
 
Delphi 10.2 Tokyo Starter
 
#3

AW: Console: OEM nach ANSI

  Alt 13. Jun 2010, 18:25
Leider ebenfalls kein Effekt. Ich verstehe das nicht. Ich lese die Daten von der Pipe direkt in einen AnsiString aus. Da sollte es ja auch keine Probleme durch das Unicode Delphi geben.
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.142 Beiträge
 
Delphi 12 Athens
 
#4

AW: Console: OEM nach ANSI

  Alt 13. Jun 2010, 18:31
Wie ließt du denn die Daten genau aus? (also kompletter Code)

Seit Delphi 2009 wird blöder Weise oftmals im String direkt die CodePage gespeichert, welches Probleme bereiten kann, wenn man selber die CodePage ändert und dieses nicht anpaßt.


z.B. dieses reagiert seit D2009 nicht mehr so wie ich es mir denke (es wird kein UTF-8-kodierter Text angezeigt )
Delphi-Quellcode:
var
  A: AnsiString;
  S: String;

A := UTF8Encode('äöü');
S := A;
ShowMessage(S);
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
Benutzerbild von Zacherl
Zacherl

Registriert seit: 3. Sep 2004
4.629 Beiträge
 
Delphi 10.2 Tokyo Starter
 
#5

AW: Console: OEM nach ANSI

  Alt 13. Jun 2010, 19:00
Delphi-Quellcode:
function ShellReadThread(lpParam: Pointer): Cardinal;
var
  ExitCode: Cardinal;
  BytesRead: DWord;
  Buffer: array[0..1024 * 8 - 1] of AnsiChar;
begin
  while (not Terminated) do
  begin
    GetExitCodeProcess(FProcessInfo.hProcess, ExitCode);
    if (ExitCode <> STILL_ACTIVE) then
    begin
      Terminate;
      Break;
    end;
    if (ReadFile(hoRead, Buffer[0], Length(Buffer), BytesRead, nil)) and
      (BytesRead > 0) then
    begin
      SendPriorityCommand(ParentThread.IDTPWriter, CMDS_SHELLOUTPUT,
        @Buffer[0], BytesRead, true);
    end;
    Sleep(50);
  end;
  Result := 0;
end;
Wie man sieht landen die Daten direkt in einem ByteArray. Wenn ich die Daten an OEM2ANSI übergebe, wird das Teil halt zwangsweise kurzzeitig in einen AnsiString konvertiert.
  Mit Zitat antworten Zitat
Benutzerbild von Zacherl
Zacherl

Registriert seit: 3. Sep 2004
4.629 Beiträge
 
Delphi 10.2 Tokyo Starter
 
#6

AW: Console: OEM nach ANSI

  Alt 13. Jun 2010, 19:13
Okay fail Ich hatte das ByteArray zu Testzwecken in ein array of AnsiChar geändert. Daran lags wohl, auch wenn ich nicht verstehe warum. Allerdings gibt es nun ein weiteres Problem:

Delphi-Quellcode:
function OEM2Ansi(Value: AnsiString): String;
begin
  Result := Value;
  OEMToChar(PAnsiChar(Value), PChar(Result));
end;
Die Umlaute werden nun korrekt umgewandelt, aber als "netter" Nebeneffekt werden alle enthaltenen Zeilenumbrüche (#13#10) in irgendeinen Quatsch konvertiert

Zitat:
'dir?? Datenträger in Laufwerk C: ist BOOT??'
  Mit Zitat antworten Zitat
omata

Registriert seit: 26. Aug 2004
Ort: Nebel auf Amrum
3.154 Beiträge
 
Delphi 7 Enterprise
 
#7

AW: Console: OEM nach ANSI

  Alt 13. Jun 2010, 19:17
Also ich habe das so gelöst...
Delphi-Quellcode:
function Oem2Ansi(AText:AnsiString):AnsiString;
const cMaxLength = 255;
var PText : PAnsiChar;
begin
  Result:='';
  PText:=AnsiStrAlloc(cMaxLength);
  while AText <> 'do begin
    StrPCopy(PText, copy(AText, 1, cMaxLength-1));
    OemToAnsi(PText, PText);
    Result:=Result + StrPas(PText);
    delete(AText, 1, cMaxLength-1);
  end;
  StrDispose(PText);
end;
Und ab Delphi2009...
Delphi-Quellcode:
function Convert(Data:AnsiString):string;
begin
  Data:=Oem2Ansi(Data);
  {$WARNINGS OFF}
  Result:=AnsiToUtf8(Data);
  {$WARNINGS ON}
end;

Geändert von omata (13. Jun 2010 um 19:25 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.142 Beiträge
 
Delphi 12 Athens
 
#8

AW: Console: OEM nach ANSI

  Alt 13. Jun 2010, 19:22
Du könntest statt dem CharToOem einfach mal SetFileApisToOEM versuchen.

> MSDN-Library durchsuchenSetFileApisToOEM, MSDN-Library durchsuchenSetFileApisToANSI und MSDN-Library durchsuchenAreFileApisANSI



Meckert dein Delphi 2009+ eigentlich nicht über den Ansi-Unicode-Mischmasch?

Für AnsiString mußt du OemToCharA verwenden.
Delphi-Quellcode:
function OEM2Ansi(const OEMString: AnsiString): AnsiString;
begin
  Result := OEMString;
  if Result <> 'then
    OemToCharA(PAnsiChar(Result), PAnsiChar(Result));
end;
oder mal so versuchen:
Delphi-Quellcode:
function OEM2Ansi(const OEMString: AnsiString): AnsiString;
begin
  Result := OEMString;
  if Result = 'then Exit;
  OemToCharA(PAnsiChar(Result), PAnsiChar(Result));
  PWord(Integer(Result) - 12)^ := 0;
end;


PS
Delphi-Quellcode:
type
  PStrRec = ^StrRec;
  StrRec = packed record
    codePage: Word;
    elemSize: Word;
    refCnt: Longint;
    length: Longint;
  end;
  OEMString = type AnsiString(CP_OEMCP);

procedure TForm5.FormCreate(Sender: TObject);
var A: AnsiString;
begin
  A := UTF8Encode('äöü');
  ShowMessage(A);
  {$IF CompilerVersion >= 20.0}
    if A <> 'then PStrRec(Integer(A) - SizeOf(StrRec)).codePage := CP_NONE;
    ShowMessage(A);
  {$IFEND}

  A := 'äöü';
  UniqueString(A); // Konstante in Variable umwandeln
  CharToOemA(PAnsiChar(A), PAnsiChar(A));
  {$IF CompilerVersion >= 20.0}
  //if A <> '' then PStrRec(Integer(A) - SizeOf(StrRec)).codePage := CP_NONE;
    ShowMessage(A);
    if A <> 'then PStrRec(Integer(A) - SizeOf(StrRec)).codePage := CP_OEMCP;
  {$IFEND}
  ShowMessage(A);
end;
Delphi-Quellcode:
var S: AnsiString;

SetString(S, P, BytesRead); // von PAnsiChar
//SetString(S, @Buf[0], BytesRead); // von AnsiChar-Array
if S <> 'then PWord(Integer(S) - 12)^ := CP_OEMCP;
// und schon wandelt Delphi automatisch die Codepage um

ShowMessage(A);
Delphi-Quellcode:
var S: AnsiString;

SetString(S, P, BytesRead); // von PAnsiChar
//SetString(S, @Buf[0], BytesRead); // von AnsiChar-Array
if S <> 'then PWord(Integer(S) - 12)^ := CP_OEMCP;

ShowMessage(A);
und schon wandelt Delphi automatisch die Codepage um, wenn dieser AnsiString z.B. an einen String/UnicodeString übergeben wird.
(also ab Delphi 2009)
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
Benutzerbild von Zacherl
Zacherl

Registriert seit: 3. Sep 2004
4.629 Beiträge
 
Delphi 10.2 Tokyo Starter
 
#9

AW: Console: OEM nach ANSI

  Alt 13. Jun 2010, 20:07
Argh in der ganzen Hektik habe ich tatsächlich nicht bemerkt, dass ich die Unicode Funktion aufgerufen habe. Der Compiler hat lustigerweise auch nicht gemeckert Jetzt klappt aber alles. Vielen Dank
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 13:50 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz