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 Pointer auf Record in eigener Windows Message übergeben (https://www.delphipraxis.net/35407-pointer-auf-record-eigener-windows-message-uebergeben.html)

sieppl 6. Dez 2004 18:29


Pointer auf Record in eigener Windows Message übergeben
 
Hi,

ich habe folgendes Problem:

Delphi-Quellcode:
  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;
es kommt leider nur schrott an. Der wParam wird korrekt erkannt, es handelt
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

SirThornberry 6. Dez 2004 18:35

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:
... Integer(@TransferDeviceInfo) ...
und wenn du die Message dann nutzt
Delphi-Quellcode:
PDeviceInfo(Msg.lParam).Event
castest du "Msg.lParam" nicht zurück zu Cardinal/Pointer

jim_raynor 6. Dez 2004 18:58

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 MSDN-Library durchsuchenFile Mapping frag aber bitte nicht wie. Eventuell kannst du auch GlobalAddAtom nutzen, damit können aber nur Strings (dürfen nicht $00 enthalten) übertragen werden.

DerDan 6. Dez 2004 19:02

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

DerDan 6. Dez 2004 19:05

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

sieppl 6. Dez 2004 19:59

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

Luckie 6. Dez 2004 20:07

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: http://www.luckie-online.de/Delphi/Sonstiges/

sieppl 7. Dez 2004 11:47

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:
//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
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:

Grüße

Sebastian

Mephistopheles 27. Apr 2005 19:18

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 11:46 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