![]() |
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! |
Alle Zeitangaben in WEZ +1. Es ist jetzt 01:28 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