![]() |
Pointer auf Record in eigener Windows Message übergeben
Hi,
ich habe folgendes Problem:
Delphi-Quellcode:
es kommt leider nur schrott an. Der wParam wird korrekt erkannt, es handelt
TDeviceInfo = packed record
Vol: Shortstring; GUID: Shortstring; Event: UINT; end; PDeviceInfo = ^TDeviceInfo; //wird hier eingepackt: FillMemory(@TransferDeviceInfo, Sizeof(TransferDeviceInfo), 0); TransferDeviceInfo.Event := DBT_DeviceArrival; TransferDeviceInfo.GUID := DeviceInfo.GUID; //hier sind die Werte noch korrekt!! TransferDeviceInfo.Vol := DeviceInfo.Vol; //und losgeschickt: PostMessage(AWnd, WM_SOURCEFOUND, CCamera, Integer(@TransferDeviceInfo)); //eine andere App emfängt es: procedure TDevCheckHandler.AppMessage(var Msg: TMsg; var Handled: Boolean); begin Handled := False; case Msg.message of WM_SOURCEFOUND: begin FDeviceInfo.Event := PDeviceInfo(Msg.lParam).Event; if Msg.wParam = CVolume then FDeviceInfo.Vol := PDeviceInfo(Msg.lParam).Vol; if Msg.wParam = CCamera then FDeviceInfo.Guid := PDeviceInfo(Msg.lParam).GUID; if Assigned(FOnDevChange) then FOnDevChange; Handled := True; end; WM_PASSHANDLE: begin FDevCheckHandle := Msg.wParam; Handled := True; end; end; end; sich also um die richtige Nachricht. Ich vermute, ich habe die Pointer versaut. Sieht jemand den Fehler? Probiere schon seit einer Stunde herum. :roll: Grüße Sebastian |
Re: Pointer auf Record in eigener Windows Message übergeben
ganz einfach. Ein Pointer ist ein Cardinal (also es gibt keine negativwerte).
zum verschicken castest du das ganze auf Integer
Delphi-Quellcode:
und wenn du die Message dann nutzt
... Integer(@TransferDeviceInfo) ...
Delphi-Quellcode:
castest du "Msg.lParam" nicht zurück zu Cardinal/Pointer
PDeviceInfo(Msg.lParam).Event
|
Re: Pointer auf Record in eigener Windows Message übergeben
Ich denke ehr, das Problem liegt darin, dass jede Anwendung ihren eigenen Adressraum besitzen. Wenn du also eine Adresse von Anwendung a an Anwendung b übergibst. Dann steht an der Adresse in Anwendung b etwas anderes.
Ich weiss jetzt leider nicht wie, aber du musst Prozessübergeifenden Speicher erstellen. Irgendwie funktioniert das mit ![]() |
Re: Pointer auf Record in eigener Windows Message übergeben
Der Grund warums nicht geht:
Die veschickst in einer Funktion einen Pointer auf eine Variable, die auf dem Stack liegt. Da du mit PostMessage (asychron) arbeitest wird die Funktion aber verlassen und damit deine Stack Inhalt ungöltig, bevor die Message Schleife mit HAndle Message aufgerufen wird! DerDan |
Re: Pointer auf Record in eigener Windows Message übergeben
Richtig ist auch, das du keine Daten von einer App in eine andere App schicken kannst. bzw einen Poiter darauf.
Dazu gibts unter Windows die Msg WM_COPYDATA. Such mal danach! DerDan |
Re: Pointer auf Record in eigener Windows Message übergeben
Hi!
Vielen Dank für die Antworten. Sehr einleuchtend. Irgendwie bin ich auf den komischen Gedanken gekommen, dass ich mit FillMem Speicher im Heap alloziere. Danke, ich werde Eure Tipps mal checken. Grüße Sebastian |
Re: Pointer auf Record in eigener Windows Message übergeben
Tust du vielleicht auch, nur eben im gleichen Prozess.
PS: Es geht übrigens nur mit WM_COPYDATA, da Windows für diese spezielle Nachricht den Speicher entsprechend mapped, so dass andere Prozesse darauf zugreifen können. Ein Beispiel gibt es hier: ![]() |
Re: Pointer auf Record in eigener Windows Message übergeben
Hi nochmal,
gibt es irgendwelche bekannten Einschränkungen, wenn ich WM_COPYDATA direkt an die Applikation schicke und diese Messages dann in OnMessage behandelt werden? Ich habe mich ziemlich genau an die verfügbaren Beispiele gehalten, die WM_COPYDATA kommt einfach nicht an. :x
Delphi-Quellcode:
nochmal: WM_COPYData wird definitiv losgeschickt (bin mit dem Debugger) durch, beim Empfänger tut sich GARNICHTS. Ich bin mit meinem Latein am Ende. :roll:
//Hier der Sender:
SendMessage(TargetAppHandle, WM_COPYDATA, AWnd, Integer(@CopyDataStruct)); //Der Empfänger: Application.OnMessage := DevCheckHandler.AppMessage; (vorher natürlich initialisiert) procedure TDevCheckHandler.AppMessage(var Msg: TMsg; var Handled: Boolean); begin Handled := False; case Msg.message of WM_COPYDATA: begin FDeviceInfo.Event := PDeviceInfo(PCopyDataStruct(Msg.lParam).lpData).Event; if Msg.wParam = CVolume then FDeviceInfo.Vol := PDeviceInfo(PCopyDataStruct(Msg.lParam).lpData).Vol; if Msg.wParam = CCamera then FDeviceInfo.Guid := PDeviceInfo(PCopyDataStruct(Msg.lParam).lpData).GUID; if Assigned(FOnDevChange) then FOnDevChange; Handled := True; end; WM_PASSHANDLE: //der kommt immer an! begin FDevCheckHandle := Msg.wParam; Handled := True; end; end; end; //mit PostMessage(TargetAppHandle, WM_PASSHANDLE, AWnd, 0); //und procedure TDevCheckHandler.PassAppHandle; begin PostMessage(FDevCheckHandle, WM_PASSHANDLE, FAppHandle, 0); end; //kann ich zwischen beiden die Handles hin und her übergeben // -> Die Kommunikation steht in Grunde Grüße Sebastian |
Re: Pointer auf Record in eigener Windows Message übergeben
Die meisten Handles sind nur im eigenen Prozess gültig. Selbst bei Kindprozessen muß man extra angeben, ob die Handles vererbt werden dürfen.
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 10:22 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