Entwickler-Ecke

Windows API - Text per SendMessage senden und empfangen


Hybrid666 - Mi 04.02.09 09:40
Titel: Text per SendMessage senden und empfangen
Servus,

ich versuche grade eine kleine API für ein Programm von mir zu schreiben und will das über sendmessage realisieren.

Unter anderem soll das programm auch per SendMessage text empfangen und senden.

Das heißt wenn ich z.B. an das Programm per SendMessage folgendes sende:

Delphi-Quelltext
1:
SendMessage (MyHandle, WM_USER+2,19,0)                    

So soll aus edit1 der text als result zurückgegeben werden. laut google geht das mit

Delphi-Quelltext
1:
msg.Result := Integer (PChar (edit1.text));                    


Text senden an die applikation ginge dann auch laut google:

Delphi-Quelltext
1:
SendMessage (MyHandle, WM_USER+220, Integer (PChar (edit1.text)));                    


Das ganze hab ich zum testen mal in ein Programm implementiert (also Senden und empfangen in das gleiche app). Da funktioniert das ganze auch, wenn ich das nun allerdings mache wie gedacht, und zwar das ein anderes programm mit meinem kommunizieren kann, so kommt es entweder zu einer Access Violation oder der resultierende String den ich mit

Delphi-Quelltext
1:
ShowMessage (String (PChar (SendMessage (MyHandle, WM_USER+2,20,0))));                    

anzeigen will ist einfach nur totaler crap.

Meine vermutung liegt drin, das der PChar, denn ich mit dem typecast erhalte einfach auf einen nicht zugewiesenen speicher zeigt. Woran kann das liegen? bzw wie kann ich den fehler wegbekommen, das ich den text korrekt typecasten kann, damit auch wieder ein anfangsstring rauskommt?

Danke schonmal für jede Hilfe!

P.S.: Der WParam ist bei mir einfach eine Zahl, um festzustellen, welche API funktion meines programms aufgerufen wird, der LParam ist jeweils einfach der Parameter für die API Funktion, also in dem Fall ein String (bzw. PChar).

MfG Hybrid666


delfiphan - Mi 04.02.09 12:17

Verschiedene Programme teilen sich nicht den virtuellen Speicher, weswegen es keinen Sinn macht, einen Pointer an einen anderen Prozess zu schicken. Versuch's mal mit WM_COPYDATA. Daten direkt zurückgeben kannst du allerdings nicht.


JayEff - Mi 04.02.09 12:53

user profile icondelfiphan hat folgendes geschrieben Zum zitierten Posting springen:
Verschiedene Programme teilen sich nicht den virtuellen Speicher
Das dachte ich mir, aber die Tatsache, dass man mit WM_SETTEXT einen Pointer schicken kann, hat mich davon abgehalten, das zu erwähnen. Ich vermute mal, dass im Fall WM_SETTEXT die Zielanwendung/Das Zielfenster garnicht erst auf die Nachricht reagiert...?


delfiphan - Mi 04.02.09 13:22

Bei gewissen Messages (wenn ich mich richtig erinnere alle unterhalb einer Grenze) werden Daten hinter Pointern automatisch von Windows "gemarshallt". So ist das auch bei WM_GETTEXT und WM_SETTEXT der Fall.


Delete - Mi 04.02.09 14:44

user profile icondelfiphan hat folgendes geschrieben Zum zitierten Posting springen:
Bei gewissen Messages (wenn ich mich richtig erinnere alle unterhalb einer Grenze) werden Daten hinter Pointern automatisch von Windows "gemarshallt". So ist das auch bei WM_GETTEXT und WM_SETTEXT der Fall.

Das hat historische Gründe. Unter 16-Bit Windows konnte man noch ohne weiteres auf den Adressraum anderer Prozesse zugreifen. Man konnte also auch Pointer hin und her schicken. Unter NT sind die Adressräume der Prozesse strikt von einander getrennt. Damit jetzt aber noch die alten Programme laufen, werden Nachrichten wie WM_SETTEXT in einen Speicherbereich gemappt, auf den beide Prozesse Zugriff habe.

Un daten zwischen Prozessen auszutauschen sollte man, wenn man es mit Nachrichten machen will, WM_COPYDATA nehmen. Andere Möglichkeiten der Interprozesskommunikation wären Memory Mapped Files, Pipes, Mailslots oder TCP/IP. Ein Beispiel, wie es mit MMF geht, habe ich hier auf meiner Homepage: http://www.michael-puff.de/Developer/Delphi/Code-Snippets/MMF.shtml


Hybrid666 - Do 05.02.09 14:53

gut ok, WM_COPYDATA ist gut, aber das problem ist, das das programm, welches meine API verwenden will eine anfrage über sendmessage schickt, und wenn ich über WM_COPYDATA antworten würde, bräuchte ich das window handle von dem fenster, das über sendmessage die anfrage geschickt hat :(. Bekomm ich irgendwie raus, von welchem handle eine message kommt?

MfG


Delete - Do 05.02.09 14:56

Pack diese Info doch ins CopyDataStruct.


delfiphan - Do 05.02.09 15:46

user profile iconDeddyH hat folgendes geschrieben Zum zitierten Posting springen:
Pack diese Info doch ins CopyDataStruct.

Nein. Den schickt man üblicherweise als wParam. Siehe msdn für alle weiteren Details.


Delete - Do 05.02.09 16:04

Trotzdem würde der Rechner dann nicht explodieren.


delfiphan - Do 05.02.09 16:11

Wollte nur darauf hinweisen, dass das Feld extra dafür vorgesehen ist.

Du darfst es selbstverständlich anders machen, wenn das dich reizt ;)