Seite 1 von 2

(WinAPI) Wie funktioniert die Messagequeue unter Windows?

Verfasst: 29.08.2004 07:07
von Danilo
Die Nachrichten für Dein Programm werden von Windows in
eine Warteschlange geschickt, die erst abgearbeitet wird,
wenn Du es willst.

Bei einem reinen API-Programm ist der Message-Loop
jedesmal gleich:

Code: Alles auswählen

While GetMessage_( msg.MSG, #NULL, 0, 0 )
  TranslateMessage_(msg)
  DispatchMessage_(msg)
Wend
Das ist immer gleich... in PureBasic genauso wie auch in C/C++.

In C/C++ schreibst Du den obigen Code direkt hin, und in PureBasic
wird das zu dem Befehl WaitWindowEvent() zusammengefasst.

WindowEvent ist dann als API:

Code: Alles auswählen

While PeekMessage_( msg.MSG, #NULL, 0, 0, #PM_REMOVE )
  TranslateMessage_(msg)
  DispatchMessage_(msg)
Wend
Das heisst GetMessage_() wartet bis eine Message ankommt,
und PeekMessage_() wartet nicht, sondern arbeitet auch so
weiter.


Windows sendet tausende Nachrichten an Dein Programm, ohne
das Du das direkt merkst.
Wenn Du z.B. den Status eines Gadgets änderst (egal ob Du einen
neuen Eintrag hinzufügst oder Das Image vom ImageGadget änderst),
wird eine Nachricht an die Warteschlange Deines Programmes
versendet.

Bearbeitet werden die Nachrichten in der Warteschlange (Queue)
aber erst nachdem Du die obige Befehlssequenz aufgerufen
hast - bzw. in PureBasic mit WindowEvent() und WaitWindowEvent().

der Befehl WindowEvent() wartet nicht bis eine message eintrifft,
sondern checkt nur ob eine in der Queue ist.
Falls ja, wird die message abgearbeitet und WindowEvent() liefert
die Nummer der message zurück.
wenn keine message ansteht, so wird NULL (0) zurückgegeben.

Die Zeile:

Code: Alles auswählen

While WindowEvent():Wend
bewirkt somit Das WindowEvent() solange aufgerufen wird,
bis es 0 zurückgibt, d.h. bis alle Messages aus der Warteschlange
abgearbeitet sind.

es reicht nicht wenn man nach einem SetGadgetState()
ein simples 'WindowEvent()' macht um diese 1 message
abzuarbeiten.
Erstens könnten noch andere Nachrichten in der Schlange sein,
die schon vorher angekommen sind, und zweitens sendet Windows
auch noch etliche andere Messages um die wir uns nicht kümmern
müssen... die aber trotzdem in der Queue sind.

es gab schon Leute hier die haben nur ein WindowEvent() benutzt,
und dann lief der code auf einer Windows-Version korrekt, auf
einer anderen Version aber nicht.
die verschiedenen Windows-Versionen unterscheiden sich Intern
eben sehr stark, so daß eine Version nur 1 message schickt, aber
eine andere Windows-Version 5 Nachrichten dafür versendet.

von daher macht man zum updaten immer:
While WindowEvent():Wend

Wer möchte kann Das natürlich auch umschreiben:
Repeat : Until WindowEvent() = 0

für solche Sachen wird halt auch in anderen Sprachen immer
While...Wend genommen, von daher wirst Du so gut wie immer
diese Methode sehen.

Hoffe Das hilft als kleine Erklärung dazu.

Wer mehr darüber wissen möchte, der sollte mal ein Buch oder
Tutorial zur Windows-Programmierung lesen.

Verfasst: 29.08.2004 07:19
von Danilo
Und hier noch ein kleines Beispiel dazu, wie man komplett
WinAPI programmieren kann, ohne die PB-Libraries dabei
zu benutzen:

Code: Alles auswählen

;
; by Danilo, irgendwann 2002 oder so... ;)
;
Enumeration 1
  #Button1
  #Button2
EndEnumeration

Procedure WindowCallback(Window,Message,wParam,lParam)
   Select Message
     Case #WM_CLOSE
       If MessageBox_(Window, "Wirklich beenden?", "EXIT", #MB_YESNO) = #IDYES
         DestroyWindow_(Window)
       EndIf
     Case #WM_COMMAND
       Select (wParam >> 16) & $FFFF ; Message
         Case #BN_CLICKED            ;  -> Button Clicked
           Select (wParam & $FFFF)   ; Control ID
             Case #Button1           ;  -> Button 1
               MessageBox_(Window,"Button 1 geklickt!","INFO",0)
             Case #Button2           ;  -> Button 2
               MessageBox_(Window,"Button 2 geklickt!","INFO",0)
           EndSelect
       EndSelect
     Case #WM_DESTROY
       PostQuitMessage_(0)
     Default
       Result = DefWindowProc_(Window,Message,wParam,lParam)
   EndSelect
   ProcedureReturn Result
EndProcedure

#Style   = #WS_VISIBLE|#WS_BORDER|#WS_SYSMENU
#StyleEx = #WS_EX_TOOLWINDOW ;| #WS_EX_OVERLAPPEDWINDOW

WindowClass.s = "MeinFenster"
wc.WNDCLASSEX
wc\cbSize        = SizeOf(WNDCLASSEX)
wc\lpfnWndProc   = @WindowCallback()
wc\hCursor       = LoadCursor_(0, #IDC_CROSS)  ; #IDC_ARROW   = Arrow
                                               ; #IDC_SIZEALL = Size Arrow
                                               ; #IDC_CROSS   = Cross
wc\hbrBackground = #COLOR_WINDOW+1;CreateSolidBrush_(RGB($8F,$8F,$8F))
wc\lpszClassName = @WindowClass
RegisterClassEx_(@wc)

hWndMain = CreateWindowEx_( #StyleEx,WindowClass,"Test-Window",#Style,200,200,200,200,0,0,0,0)
  CreateWindowEx_(0,"Static","",#WS_CHILD|#WS_VISIBLE|$12,9,9,102,22,hWndMain,0,0,0)
  button1 = CreateWindowEx_(0,"Button","Button 1",#WS_CHILD|#WS_VISIBLE,10,10,100,20,hWndMain,#Button1,0,0)
  button2 = CreateWindowEx_(0,"Button","Button 2",#WS_CHILD|#WS_VISIBLE,10,40,100,20,hWndMain,#Button2,0,0)

hFont = CreateFont_(8,0,0,0,0,0,0,0,0,0,0,0,0,"MS Sans Serif")
SendMessage_(button1,#WM_SETFONT,hFont,1)
SendMessage_(button2,#WM_SETFONT,hFont,1)

ShowWindow_(hWndMain, #SW_SHOWDEFAULT)
UpdateWindow_(hWndMain); 

While GetMessage_( msg.MSG, #NULL, 0, 0 )
    TranslateMessage_(msg)
    DispatchMessage_(msg)
Wend

DeleteObject_(hFont)
Das heißt man kann mit PureBasic auch komplett WinAPI
programmieren, so wie das z.B. bei PowerBasic, C/C++ und
anderen CompilerSystemen der Fall ist.

Wer richtig WinAPI lernen möchte, der sollte diese Möglichkeit
auf jeden Fall einmal probieren!

C/C++ Codes aus WinAPI-Büchern wie z.B. dem Petzold kann
man so ganz leicht komplett nach PureBasic übersetzen:
Windows-Programmierung, m. CD-ROM
Bild

Author: Charles Petzold
Verlag: Microsoft Press Deutschland
Seiten: 1.300
ISBN: 3-86063-487-9 (5.Auflage, Dezember 2000)

Verfasst: 29.08.2004 14:12
von Falko
Und wer noch mehr wissen will, sollte mal hier hineinschauen.
http://www.cul.de/buecher.html --> http://www.cul.de/win32.html
Und wer noch GFA-BASIC "GB32" hat, der hat schon 4 API-Bände auf seiner CD. :mrgreen:

Verfasst: 29.08.2004 14:38
von Danilo
Falko hat geschrieben:Und wer noch mehr wissen will, sollte mal hier hineinschauen.
--> http://www.cul.de/win32.html
Ich habe alle 5 Win32-API-Bände hier... und nachdem ich nun
schon eine ganze Weile WinAPI code würde ich eher sagen:
Kann man sich sparen, MSDN/PSDK reicht vollkommen aus.

In den Büchern sind nur alle möglichen API-Funktionen aufgelistet
(und meist kleines Beispiel in C, C++ und Delphi dabei), aber es
ist definitiv kein Buch zum lernen.
Als Referenz OK, aber da reicht auch MSDN/PSDK... und ist immer
auf dem aktuellsten Stand (die Bücher sind schon etliche Jahre alt).

Mit der Suchfunktion in einem lokal installierten MSDN/PSDK ist
man auch 10mal schneller, als erst in 5 Büchern nach etwas zu
schauen.
Und auch in MSDN/PSDK kann man sich "Bookmarks" zum schnellen
Zugriff machen... anstatt 150 Lesezeichen in die Bücher zu legen. ;)

Verfasst: 30.08.2004 10:33
von Falko
@Danilo
Für die, die nicht so gut im englischen sind hebt sich das 10mal
schneller bzw. das Verstehen der PSDK/MSDN wohl auf.
Also bleibt dann denjenigen diese API-Refernz übrig, woraus er auch lernen kann. Eine codierte CD ist für diese 5 Bände ist auch vorhanden. Bei mir sind die 4 Bände auf der GFABASIC-CD vorhanden.

Ansonstens hast du ja recht. :wink:

MfG Falko

Verfasst: 16.03.2005 21:47
von Danilo
Danilo hat geschrieben:Windows-Programmierung, m. CD-ROM
Author: Charles Petzold
Verlag: Microsoft Press Deutschland
Seiten: 1.300
ISBN: 3-86063-487-9 (5.Auflage, Dezember 2000)
Jetzt als Sonderausgabe für nur 29,90 Euro statt 59,90 Euro:

Windows-Programmierung
Bild

Author: Charles Petzold
Verlag: Microsoft Press Deutschland
Seiten: 1.300
ISBN: 3-86063-188-8 (5.Auflage, Sonderausgabe März 2005)

Verfasst: 22.03.2005 13:33
von Lebostein
Danke für den Hinweis! Scheint ja wirklich ein gutes Buch zu sein, habs mir gleich mal bestellt....

Verfasst: 22.03.2005 13:47
von traumatic
Zum Petzold möchte ich auch mal kurz meinen Senf abgeben:
Das Standardwerk, keine Frage. Wer jedoch über ausreichend Englischkenntnise
verfügt, sollte versuchen, sich das Buch im Original zu besorgen.

Ok, auf deutsch ist es vielleicht (unfreiwillig) komischer - macht auch Sinn ;)

Verfasst: 22.03.2005 13:52
von benny
Lebostein hat geschrieben:Danke für den Hinweis! Scheint ja wirklich ein gutes Buch
zu sein, habs mir gleich mal bestellt....
Wirst es schon nicht bereuhen.

Ich habe es mir damals zu guten alten DM-Zeiten für knapp 100.-DM gekauft.
(was ja heute von der Kaufkraft her ~ 100€ wär ;-) )
Ist wirklich ein gutes Buch, in welchem man beim Programmieren immer
wieder reinschaut, um kurz was nachzulesen :!:

Bei den jetzigen Sonderpreis sollte man sich eigentlich gleich zwei von
kaufen :allright:

Verfasst: 22.03.2005 14:41
von Rings
Der gute alte Petzold..........

http://www.amazon.de/exec/obidos/ASIN/386063691X

selbst das Buch ist schon wieder über 2 Jahre alt, aber auch dort noch
eine Referenz.