![]() |
Stringumwandlung
Hallo zusammen,
um Strings zwischen 2 Anwendungen auszutauschen verwende ich (Code aus der DP): Sender:
Delphi-Quellcode:
Empfänger:
WindowsNachrichtAn('Tx', 'x', '#TEXT#');
Delphi-Quellcode:
wobei:
procedure Tx.WMCopyData(var Msg:TWMCopyData) ;
var h: PChar; begin h:= Msg.CopyDataStruct.lpData; Showmessage(h); end;
Delphi-Quellcode:
Hat bisher unter XP und Delphi5 einwandfrei geklappt.
procedure WindowsNachrichtAn(Fensterklasse, Fenstername, Nachricht:string);
var CopyDataStruct: TCopyDataStruct; ReceiverHandle: THandle; begin CopyDataStruct.dwData:= 0; CopyDataStruct.cbData:= 1 + Length(Nachricht); CopyDataStruct.lpData:= PChar(Nachricht); // ReceiverHandle:= FindWindow(PChar(Fensterklasse),nil); ReceiverHandle:= FindWindow(PChar(Fensterklasse),PChar(Fenstername)); if ReceiverHandle<>0 then begin SendMessage(ReceiverHandle, WM_COPYDATA, Longint(Handle), Longint(@copyDataStruct)); end; end; Mit Delphi10 und win7 erhalte ich für das Beispiel '#TEXT#' im Showmessagefenster: #TEX(viereck)(chinesisches Zeichen) die Länge ist in Ordnung, nur die beiden letzten Zeichen kommen falsch an. Weiss jemand woran das liegen könnte? |
Re: Stingumwandlung
Nutze mal an Stelle von PChar, was wohl in D10 Unicode ist, PAnsiChar
PS. Editiere mal den Beitragstitel: Stingumwandlung ;) |
Re: Stringumwandlung
Wenn ich PAnsiChar verwende (CopyDataStruct.lpData:= PAnsiChar(Nachricht); und h: PAnsiChar;)
kommt nur noch '#' an. |
Re: Stringumwandlung
Jupp, D7 nutzt Ansi (AnsiString und PAnsiChar) und D2010 Unicode (UnicodeString und PWideChar)
Delphi-Quellcode:
oder
procedure WindowsNachrichtAn(Fensterklasse, Fenstername, Nachricht: WideString);
var CopyDataStruct: TCopyDataStruct; ReceiverHandle: THandle; begin CopyDataStruct.dwData:= 0; CopyDataStruct.cbData:= (Length(Nachricht) + 1) * 2; CopyDataStruct.lpData:= PWideChar(Nachricht); PWideChar(Msg.CopyDataStruct.lpData)
Delphi-Quellcode:
aus genau diesem Grund nutzt man für programmexternen Datenaustausch und Datenspeicherung nur statische Typen ... kein Integer, Cardinal, String, PChar und wenn Records, dann nur packed.
procedure WindowsNachrichtAn(Fensterklasse, Fenstername, Nachricht: AnsiString);
var CopyDataStruct: TCopyDataStruct; ReceiverHandle: THandle; begin CopyDataStruct.dwData:= 0; CopyDataStruct.cbData:= Length(Nachricht) + 1; CopyDataStruct.lpData:= PAnsiChar(Nachricht); PAnsiChar(Msg.CopyDataStruct.lpData) |
Re: Stringumwandlung
Hallo, erst mal vielen Dank für die Anwort.
Allerdings versteh ich immer weniger: Mit WideString funktioniert es fast, es kommen allerdings 2 Zeichen zuviel im Showmessagefenster. Kurioserweise ändert sich nichts, wenn ich (Length(Nachricht) + 1 in (Length(Nachricht) ändere!??? Mit AnsiString funktioniert es fast nicht, es kommt lediglich 1 Zeichen an im Showmessagefenster. |
Re: Stringumwandlung
Diese Zeile hier ist nicht die beste Art:
Delphi-Quellcode:
Wenn man das "*2" fest rein schreibt ist es kein Wunder das man beim Wechsel zwischen Delphiversionen dann wieder Probleme bekommt. Richtiger wäre hier mit sizeof zu arbeiten.
CopyDataStruct.cbData:= (Length(Nachricht) + 1) * 2;
Delphi-Quellcode:
Und das "+1" würde ich weg lassen und stattdessen lieber die Länge mit verschicken und diese dann auch beim Auslesen mit beachten.
CopyDataStruct.cbData:= (Length(Nachricht) + 1) * sizeof(Nachricht[1]);
|
Re: Stringumwandlung
Zitat:
Was auch noch zu beachten ist, dass Sender und Empfänger die gleiche String-Sprache sprechen. Denn wenn der Sender Unicode (2 Byte pro Zeichen) und der Empfänger ANSI (1 Byte pro Zeichen) spricht, dann können die beiden sich nicht unterhalten. |
Re: Stringumwandlung
Zitat:
So kenne ich Beispiele bei denen die Größe eines Record-Members ermittelt werden soll wo keine Instanz des Records vorhanden ist. Dort wird dann einfach nil auf den pointertyp des Records gecastet, dereferenziert und dann die Größe des Members ermittelt. Dies ist gängige Praxis. (Im ersten Moment sieht dies Haarstreubend aus aber es gibt kaum eine bessere Möglichkeit) |
Re: Stringumwandlung
Dann sollte man hier doch den Typen verwenden:
sizeOf(TChar) und fertig. |
Re: Stringumwandlung
TChar? Dann sollte man aber auch den Typen nutzen, welcher für die Variable verwendet wurde.
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 01:14 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz