![]() |
Probleme beim Empfangen mittels WM_COPYDATA
Hallo!
Bis letzte Woche hatte ich noch Delphi 10.3 genutzt und bin jetzt auf 10.4 umgestiegen. Leider funktioniert mein Quellcode jetzt nicht mehr so, wie er eigentlich sollte. Ich will nur eine Instanz meiner Software zulassen und bei nochmaligem Aufruf einen String an die bestehende Instanz übergeben. So sieht's beim Sender aus:
Delphi-Quellcode:
Und so beim Empfänger:
// Parameter-String an Ur-Instanz senden
Data.dwData := C_KEY; Data.cbData := (Length(Parms)+1) * SizeOf(Char); Data.lpData := PChar(Parms); MyHandle:=FindWindow(nil, PChar(APP_NAME)); if MyHandle<>0 then SendMessage(MyHandle, WM_COPYDATA, LongInt(MyHandle), LongInt(@Data)); CloseHandle(MyHandle);
Delphi-Quellcode:
Im Protokoll habe ich hinterher immer folgende Fehlermeldung stehen:
procedure TForm1.WMCopyData(var Msg: TWMCopyData);
var sInput: String; begin try if Msg.CopyDataStruct.dwData = C_KEY then begin // Neue Daten empfangen sInput:=PChar(Msg.CopyDataStruct.lpData); end; except on E: Exception do Protokoll('WMCopyData;FEHLER;beim Einlesen des Strings - ' + E.Message); end; end; WMCopyData;FEHLER;beim Einlesen des Strings - Zugriffsverletzung bei Adresse 0082EBC0 in Modul 'PushService7.exe'. Lesen von Adresse 00000000 Das Senden der Daten scheint ja schonmal nicht ganz verkehrt zu sein - zumindest C_KEY als Identifier kommt ja an. Beim Senden werden auch keine Exceptions ausgelöst - nur beim Empfangen. Irgendwie stehe ich jetzt gerade ein wenig auf dem Schlauch... Hat einer von euch einen Tipp für mich? |
AW: Probleme beim Empfangen mittels WM_COPYDATA
.. ist die neue Instanz schon beendet (der pointer auf den String also nicht mehr valide)wenn die Nachricht bei der alten Instanz ankommt?
Grüße Klaus |
AW: Probleme beim Empfangen mittels WM_COPYDATA
Ja, die neue Instanz sendet den String und wird dann beendet.
|
AW: Probleme beim Empfangen mittels WM_COPYDATA
In der (recht alten, aber funktionierenden) oneinst.pas, die ich dazu verwende, wird beim Aufbau der WM_COPYDATA-Message nicht nur einfach der Pointer zum String übergeben, sondern es werden explizit die Daten kopiert. Mich wundert ehrlich gesagt ein wenig, dass dein alter Code überhaupt funktioniert ...
Delphi-Quellcode:
Ich hoffe, diese Variante funktioniert mit 10.4 weiter, wenn ich in den nächsten 30 Tagen umsteigen muss ...
Data.lpData := ParamStrToBlob(Data.cbData);
// mit function ParamStrToBlob(out cbData: DWORD): Pointer; var Loop: Integer; pStr: PChar; begin cbData := Length(ParamStr(1)) * SizeOf(Char) + 4; { gleich inklusive #0#0 } for Loop := 2 to ParamCount do cbData := cbData + DWORD(Length(ParamStr(Loop)) * SizeOf(Char) + 2); Result := GetMemory(cbData); ZeroMemory(Result, cbData); pStr := Result; for Loop := 1 to ParamCount do begin lstrcpy(pStr, PChar(ParamStr(Loop))); pStr := @pStr[lstrlen(pStr) + 1]; end; end; |
AW: Probleme beim Empfangen mittels WM_COPYDATA
Ist denn der record als packed definiert? Wenn nicht sollte die Einstellung (Ausrichtung...) von 10.4 mit 10.3 übereinstimmen.
Die Daten sollten eigentlich beim Empfang noch gültig sein, da Sendmessage und nicht Postmessage verwendet wird. |
AW: Probleme beim Empfangen mittels WM_COPYDATA
Zitat:
Zitat:
|
AW: Probleme beim Empfangen mittels WM_COPYDATA
Hmmm..
Delphi-Quellcode:
64 Bit Anwendung..
var
gCDS: COPYDATASTRUCT; gSOP: TSOP64; // my Record const dwData_GetPluginName = 6;
Delphi-Quellcode:
32 Bit Anwendung..
function GetPluginDescription(WindowHandle: HWND): string;
begin SetLength(Result, SendMessage(WindowHandle, WM_GETTEXTLENGTH, 0, 0)); if Result <> '' then SendMessage(WindowHandle, WM_GETTEXT, Length(Result) + 1, LPARAM(PWideChar(Result))); end; procedure SOP_GetPluginName; begin if (gp.hSOPlugin <> 0) then begin gCDS.dwData := dwData_GetPluginName; gCDS.cbData := SizeOf(gSOP); gCDS.lpData := @gSOP; SendMessage(gp.hSOPlugin, WM_COPYDATA, WPARAM(gP.MainHandle), LPARAM(@gCDS)); end; Description := GetPluginDescription(gP.MainHandle); end;
Delphi-Quellcode:
function GetPluginName(handle: HVIS): PWideChar; stdcall;
begin Result := ''; if handle <> 0 then begin Result := PWideChar(WideString(VisInfo^.VisPointer^.PluginName)); end; end;
Delphi-Quellcode:
var
pCDS: PCopyDataStruct;
Delphi-Quellcode:
Nur als Denkanstoß.
WM_COPYDATA:
begin pCDS := Pointer(lP); // LP pointer auf die CopyDataStruct case pCDS.dwData of dwData_GetPluginName: begin PluginName := GetPluginName(VisHandle); StrPCopy(aTemp, string(PluginName)); SendMessage(wp, WM_SETTEXT, SizeOf(aTemp), LPARAM(@aTemp)); end; end; |
AW: Probleme beim Empfangen mittels WM_COPYDATA
Zitat:
|
AW: Probleme beim Empfangen mittels WM_COPYDATA
Egal, Zeiger in anderen Prozessen sind eh da düben nichts wert.
Darum gibt es ja WM_COPYDATA, welches einen angegebenen Speicherblock in den anderen Prozess kopiert, damit man ihn drüben lesen kann. Alternatov GlobalAlloc und das Handle sharen oder MemoryMappedFiles oder Streams oder ... Zitat:
Da du vom CloseHandle die Rückgabewerte nicht prüfst und so nicht mitbekommst, dass es dir einen Fehler um die Ohren versucht zu werfen und da du zum Glück die falsche Funktion zum Freigeben von HWND benutzt, welche nämlich DestroyWindow (nicht CloseHandle) ist ... eigentlich hättest du das Fenster gelöscht, wenn es funktioniert hätte. |
AW: Probleme beim Empfangen mittels WM_COPYDATA
Manchmal steht man einfach nur wie der Ochs' vor'm Berg...
Ich hatte eine bestehende, einwandfrei funktionierende Anwendung und wollte diese weiterentwickeln. Dafür habe ich natürlich das Projekt kopiert. Um dann aber die neue Anwendung parallel zur alten testen zu können, habe ich einerseits den myGUID für den Mutex neu generiert und den C_KEY als Identifier für WM_COPYDATA. Bei letzterem habe ich wohl Mist gebaut... Mit dem ursprünglichen Wert funktioniert es wieder. Trotzdem vielen Dank für eure Hilfe! |
AW: Probleme beim Empfangen mittels WM_COPYDATA
Zitat:
Wie himitsu schon sagte ist
Delphi-Quellcode:
CloseHandle(MyHandle);
falsch! |
AW: Probleme beim Empfangen mittels WM_COPYDATA
Bei meiner Vermutung, dass das Problem mit der record Ausrichtung zu tun haben könnte, habe ich übersehen das
Data von Typ TWMCopyData ist. Dieser ist in der unit Winapi.Messages definiert ist. Hier werden alle Records mit {$ALIGN ON} ausgerichtet, wobei ich in der Hilfe von 10.4 dazu kein passende Beschreibung gefunden habe. Könnte das {$A1} entsprechen? |
AW: Probleme beim Empfangen mittels WM_COPYDATA
{$ALIGN ON} entspricht {$A+} und somit {$ALIGN 8}. Siehe hier:
![]() |
AW: Probleme beim Empfangen mittels WM_COPYDATA
@Uwe, Danke für den Link. Das Default/Vorgabe = A8 entspricht steht ja in der Hilfe. Das ON = Default ist, konnte ich nicht aus der Hilfe entnehmen. :oops:
|
AW: Probleme beim Empfangen mittels WM_COPYDATA
Zitat:
Zitat:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 05:16 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