Entwickler-Ecke

Windows API - Sendmessage/Getmessage einsetzen


Mike_C - Do 11.09.03 16:57
Titel: Sendmessage/Getmessage einsetzen
Hi

mit sendmessage und getmessage kann man ja nachrichten innerhalb der anwendung versenden und empfangen. mein problem dabei: woher weiß eine form, dass eine nachricht an sie gesendet wurde?
an welcher stelle von meinem programm tauchen die gesendeten nachrichten denn wieder auf? und wie fange ich sie ab?


Moderiert von user profile icontommie-lie: Topic verschoben


MSCH - Do 11.09.03 19:30

schau mal hier. Ich hab da ein Code-Rumpf dazu abgebildet.
http://www.delphi-forum.de/viewtopic.php?t=16223&highlight=
grez
msch


Mike_C - Do 11.09.03 20:12

ich weiß. in diesem coderumpf beschäftigst du dich aber damit, nachrichten zu senden, aber nicht damit sie zu empfangen


tommie-lie - Do 11.09.03 21:04
Titel: Re: Sendmessage/Getmessage einsetzen
Mike_C hat folgendes geschrieben:
woher weiß eine form, dass eine nachricht an sie gesendet wurde?

Sie "weiß" es nicht. Sie schaut einfach, ob eine Message da ist.
Wenn du dir mal eine Nachrichtenschleife (z.B. aus den nonVCL-Tutorials von Luckie und MathiasSimmack) anschaust, sieht sie folgendermaßen aus:

Delphi-Quelltext
1:
2:
3:
4:
5:
while GetMessage(msg,0,0,0do
  begin
    TranslateMessage(msg);
    DispatchMessage(msg);
  end;

GetMessage liefert solange True, bis die NAchricht WM_DESTROY war, die Schleife läuft also endlos lange weiter und schaut, ob eine Message gerade in der Message Queue ist.
Für die Application an sich gibt es in der TApplication-Klasse ein OnMessage-Event dafür. Inwieweit dieses Event auch bei Nachrichten an ein bestimmtes Fenster und nicht nur an Nachrichten an den Thread funktioniert, weiß ich nicht, das kannst du aber ja leicht ausprobieren ;-)
Wenn du eine nonVCL-Anwendung schreibst, hast du ja bereits die Nachrichtenschleife und die WndProc dazu, in der vermutlich eine lange CASE-Abfrage steckt, die die Messages durchgeht. Da kannst du deine eigene Message (z.B. WM_USER) einreihen und darauf irgendwie reagieren.


Zitat:
an welcher stelle von meinem programm tauchen die gesendeten nachrichten denn wieder auf? und wie fange ich sie ab?

Welche Daten sollen denn wieder auftauchen? Die Message kommt in eine Message-Queue, die durch GetMessage abgearbeitet wird.
Falls du im lParam oder wParam irgendwelche Zahlen übergeben hast, sind sie natürlich auch noch da drin, wenn du sie mit GetMessage aus der Queue geholt hast. Sind diese Zahlen Pointer, muss natürlich sichergestellt sein, daß der Speicher zwischenzeitlich nicht wieder freigegeben wurde, denn sonst könnte der Speicherbereich bereits mit anderen Daten gefüllt worden sein.


MSCH - Fr 12.09.03 09:17

Mike_C hat folgendes geschrieben:
ich weiß. in diesem coderumpf beschäftigst du dich aber damit, nachrichten zu senden, aber nicht damit sie zu empfangen


au weia, natürlich empfange ich sie!!!

Delphi-Quelltext
1:
    procedure WMSendMail(var Msg:TMessage);Message wm_SendMail;                    


Das ist der Empfang. Hier als Beispiel mit einer selbstdefinierten Message. Das geht auch mit Systemmessages und Events etc.

grez
msch


Mike_C - Fr 12.09.03 11:22
Titel: Re: Sendmessage/Getmessage einsetzen
tommie-lie hat folgendes geschrieben:

Für die Application an sich gibt es in der TApplication-Klasse ein OnMessage-Event dafür. Inwieweit dieses Event auch bei Nachrichten an ein bestimmtes Fenster und nicht nur an Nachrichten an den Thread funktioniert, weiß ich nicht...

Das steht aber in der Delphi-Hilfe drin. OnMessage funktioniert nur bei Messages die in die Messagequeue gesendet wurden (also nur messages von windows), nicht bei Messages, die mit Send/Postmessage gesendet wurden.
Delphi7 Hilfe zu TApplication.OnMessage hat folgendes geschrieben:

Description
Use OnMessage to trap any or all Windows messages posted to all windows in the application. OnMessage occurs when an application receives a Windows message. OnMessage only receives messages that are posted to the message queue, not those sent directly with the Windows API SendMessage function.


Gut, also das alles hier hat schonmal beantwortet, wie ich Nachrichten Sende und empfange. Aber eine Frage bleibt trotzdem noch. Die Frage nach dem wo.
ich meine, ich kann das ja auf verschiedene weise machen: über einen button (was umständlich wäre) oder an irgendeiner bestimmten stelle im porgramm, die sich praktisch automatisch darum kümmert, die MessageQueue abzuarbeiten. nur woe ist diese bestimmte stelle im programm? bei ner non-vcl anwendung hab ich dafür wndproc das ist klar. aber in ner vcl anwendung müsste ich doch sowas auch haben, oder? wenn ja, wann wird die aufgerufen?

MSCH hat folgendes geschrieben:
au weia, natürlich empfange ich sie!!!


Quelltext
1:
procedure WMSendMail(var Msg:TMessage);Message wm_SendMail;                    


Das ist der Empfang. Hier als Beispiel mit einer selbstdefinierten Message. Das geht auch mit Systemmessages und Events etc.


Sorry MSCH, wenn ich deiner meinung nach eine dumme frage gestellt haben sollte. ich hätte vielleicht früher erwähnen sollen, dass ich noch nicht viel mit messages gearbeitet habe :|


Tana´Ri - Fr 12.09.03 12:13

entweder würd ichs übers Form machen (TForm.WndProc) oder den Application.OnMessage Event dazu nutzen (der beste Ort), denn hier kannste Messages auch abblocken, lies es dir in der hilfe am besten nochmal durch. von der Hierachie würde ich das OnMessage als höchstes der Applikation bezeichnen, das form ist ja eigentich nur ein Teil der Application und soviel ich weis gehen da alle die applicationbetreffende nachrichten durch.