Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi Probleme mit WM_CopyData (https://www.delphipraxis.net/163392-probleme-mit-wm_copydata.html)

runningsoft 27. Sep 2011 13:46

Probleme mit WM_CopyData
 
Hallo,

warum funktioniert folgender, aus einem Tut abgeschriebener einfacher Code nicht? (Erzeugt mit Delphi 2010 auf Win7 64-bit)

Sender:

Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var
  aCopyData: TCopyDataStruct;
  p: PChar;
begin
  p := 'String To send';

  with aCopyData do begin
    dwData := 0;
    cbData := StrLen(p) + 1;
    lpData := p;
  end;

  SendMessage(FindWindow('TFormRecv', nil), WM_COPYDATA, Longint(Handle),
              Longint(@aCopyData));
end;

Empfänger:

Delphi-Quellcode:
type
  TFormRecv = class(TForm)
    ListBox1: TListBox;
  private
    { Private-Deklarationen }
    procedure WMCopyData(var Msg: TWMCopyData); message WM_COPYDATA;
  public
    { Public-Deklarationen }
  end;

var
  FormRecv: TFormRecv;

implementation

{$R *.dfm}

procedure TFormRecv.WMCopyData(var Msg: TWMCopyData);
var s : string;
begin
s := String(PChar(Msg.CopyDataStruct.lpData)) ;
ShowMessage(s);
end;
Beim Empfänger kommt nach den ersten Buchstaben nur noch Müll an: 'String T....' Die letzten Buchstaben werden in irgendwelche Sonderzeichen umgewandelt.

Bin für jeden Hinweis dankbar.

Steffen

mkinzler 27. Sep 2011 13:51

AW: Probleme mit WM_CopyData
 
p ist ein Zeiger ins Nirvana

DeddyH 27. Sep 2011 13:53

AW: Probleme mit WM_CopyData
 
Delphi-Quellcode:
with aCopyData do begin
    dwData := 0;
    cbData := (StrLen(p) + 1) * SizeOf(Char); //Größe in Bytes
    lpData := p;
  end;

runningsoft 27. Sep 2011 13:57

AW: Probleme mit WM_CopyData
 
@Detlef

Danke für den Tipp. Genau die Größendefinition war es. Seltsam nur, dass der fehlerhafte Code früher einmal funktioniert haben muss. Ich glaube, das Beispiel stammt von 2003. Weiß aber nicht, mit welcher Delphi-Version erstellt.

Steffen

DeddyH 27. Sep 2011 13:59

AW: Probleme mit WM_CopyData
 
Das war mit Sicherheit eine Ansi-Version (also bis Delphi 2007 einschließlich). In der jetzigen Fassung sollte es aber mit jeder Version passen.

p80286 27. Sep 2011 14:02

AW: Probleme mit WM_CopyData
 
weil Pchar auf 16Bit Char zeigt (D2010). Nimm Pansichar und es klappt wieder.

Gruß
K-H

DeddyH 27. Sep 2011 14:04

AW: Probleme mit WM_CopyData
 
Wozu PAnsiChar? Jetzt klappt es ja auch, nachdem die übergebene Größe richtig angegeben wurde.

Luckie 27. Sep 2011 14:11

AW: Probleme mit WM_CopyData
 
Zitat:

Zitat von p80286 (Beitrag 1127014)
weil Pchar auf 16Bit Char zeigt (D2010). Nimm Pansichar und es klappt wieder.

:wall:
Früher wurde immer nach Unicode Unterstützung geschrien. Jetzt ist sie da und jetzt gibt es immer wieder die Ratschläge alles wieder auf Ansi zurückzustutzen. :roll:

p80286 27. Sep 2011 14:42

AW: Probleme mit WM_CopyData
 
Entweder man arbeitet mit Ansichar (8Bit) oder mit Char (16Bit)aber das sollte man dann auch sauber durchziehen.
Und wenn es eine saubere Typbezeichnung gäbe, wie z.B. Char8 oder Char16 dann würden sich auch viele nicht so schwertun.
Aber ich glaube das hatten wir hier schon alles einmal.

Gruß
K-H

DeddyH 27. Sep 2011 14:48

AW: Probleme mit WM_CopyData
 
Zitat:

Zitat von p80286 (Beitrag 1127033)
Char (16Bit)

:?: Char ist entweder 8 oder 16 Bit, je nach Delphi-Version. Und explizite Typbezeichnungen gibt es auch, nämlich AnsiChar und WideChar. Alles kein Problem, solange man nicht davon ausgeht, dass die Bytegröße eines Strings seiner Länge entspricht, was ja hier der Fall war.

Bernhard Geyer 27. Sep 2011 14:51

AW: Probleme mit WM_CopyData
 
Bedenke auch das eine WM_COPYDATA im eigenen Programm zur Kommunikation Programmintern nicht funktioniert bzw. zufällig funktioniert wenn NView installiert ist. Dieser Hook WM_COPYDATA-Events und reicht sie nicht mehr weiter wenn das Event nicht zwischen Prozessen verwendet wird.

himitsu 27. Sep 2011 14:54

AW: Probleme mit WM_CopyData
 
Wobei PAnsiChar kein sooo schlechter Rat war.

Aber ich würde da eher auf PWideChar gehn.

Also WideString/UnicodeString, SizeOf(WideChar) und PWideChar.

Denn wenn man jetzt ein altes Ansi-Programm mit einem neuen Unicode-Programm reden läßt, dann kommt wieder nur Müll raus.


Beim Abspeichern und beim Datenübertragen niemals dynamisch Typen ala Integer, NativeInt, Pointer, String, PChar und Char verwenden (außer man speichert die Größe mit ab),
denn dabei kann man schnell Probleme bekommen, wenn sich diese Typen mal ändern. (siehe "früher ging es mal")



PS: Auch aufpassen, wen die beiden Programme mit unterschiedlichen Rechten arbeiten.
Ein Programm im Benutzerkontekt kann einem Programm mit höheren Rechten (Admin) keine Messages schicken.

DeddyH 27. Sep 2011 14:58

AW: Probleme mit WM_CopyData
 
Sender- und Empfänger-Programm sind ja wohl laut Ausgangspost beide vom TE. Solange er also in beiden die selben Typen (und dieselbe Delphi-Version) benutzt, sollte es bezüglich Ansi oder Unicode keine Probleme geben.

himitsu 6. Dez 2015 09:25

AW: Probleme mit WM_CopyData
 
Mir ist auch grade aufgefallen, daß hier Pointer nach LongInt (32-Bit) gecastet werden.
Da kann es in einem 64 Bit-Programm natürlich auch wunderbar knallen.
In Win64 sind zwar viele Handle immernoch 32 Bit, auch wenn der Typ 64 Bit ist, als Tribut an die IPC zu 32 Bit, aber Zeiger aus dem Delphi-Speichermanager sind da natürlich nicht begrenzt, außer es wird explizit so verlangt.

PS: Für SendMessage gibt es auch extra die zugehörigen Typen, also WPARAM, LPARAM und LRESULT.

Blup 5. Jan 2016 11:28

AW: Probleme mit WM_CopyData
 
Bei unterschiedlichen Prozessen ist die Adresse nur so lange gültig, bis die Nachricht verarbeitet wurde.
An dieser Stelle muss ein neuer String mit einer Kopie der Zeichenkette angelegt werden:
Delphi-Quellcode:
..
s := PChar(Msg.CopyDataStruct.lpData);
..
Der zusätzlichen Cast auf String ist ungültig, denn lpData verweist nur auf einen Puffer mit einer 0-terminierten Zeichenkette.
Bei einem String liegt ein Teil der Daten (z.B. Referenzzähler) vor dieser Adresse.


Alle Zeitangaben in WEZ +1. Es ist jetzt 16:13 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