(WinAPI) Wie funktioniert die Messagequeue unter Windows?

Hier kannst du häufig gestellte Fragen/Antworten und Tutorials lesen und schreiben.
Benutzeravatar
Danilo
-= Anfänger =-
Beiträge: 2284
Registriert: 29.08.2004 03:07

(WinAPI) Wie funktioniert die Messagequeue unter Windows?

Beitrag 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.
cya,
...Danilo
"Ein Genie besteht zu 10% aus Inspiration und zu 90% aus Transpiration" - Max Planck
Benutzeravatar
Danilo
-= Anfänger =-
Beiträge: 2284
Registriert: 29.08.2004 03:07

Beitrag 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)
cya,
...Danilo
"Ein Genie besteht zu 10% aus Inspiration und zu 90% aus Transpiration" - Max Planck
Benutzeravatar
Falko
Admin
Beiträge: 3531
Registriert: 29.08.2004 11:27
Computerausstattung: PC: MSI-Z590-GC; 32GB-DDR4, ICore9; 2TB M2 + 2x3TB-SATA2 HDD; Intel ICore9 @ 3600MHZ (Win11 Pro. 64-Bit),
Acer Aspire E15 (Win11 Home X64). Purebasic LTS 6.0
Kontaktdaten:

Beitrag 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:
Bild
Win10 Pro 64-Bit, PB_5.4,GFA-WinDOS, Powerbasic9.05-Windows, NSBasic/CE, NSBasic/Desktop, NSBasic4APP, EmergenceBasic
Benutzeravatar
Danilo
-= Anfänger =-
Beiträge: 2284
Registriert: 29.08.2004 03:07

Beitrag 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. ;)
cya,
...Danilo
"Ein Genie besteht zu 10% aus Inspiration und zu 90% aus Transpiration" - Max Planck
Benutzeravatar
Falko
Admin
Beiträge: 3531
Registriert: 29.08.2004 11:27
Computerausstattung: PC: MSI-Z590-GC; 32GB-DDR4, ICore9; 2TB M2 + 2x3TB-SATA2 HDD; Intel ICore9 @ 3600MHZ (Win11 Pro. 64-Bit),
Acer Aspire E15 (Win11 Home X64). Purebasic LTS 6.0
Kontaktdaten:

Beitrag 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
Bild
Win10 Pro 64-Bit, PB_5.4,GFA-WinDOS, Powerbasic9.05-Windows, NSBasic/CE, NSBasic/Desktop, NSBasic4APP, EmergenceBasic
Benutzeravatar
Danilo
-= Anfänger =-
Beiträge: 2284
Registriert: 29.08.2004 03:07

Beitrag 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)
cya,
...Danilo
"Ein Genie besteht zu 10% aus Inspiration und zu 90% aus Transpiration" - Max Planck
Benutzeravatar
Lebostein
Beiträge: 674
Registriert: 13.09.2004 11:31
Wohnort: Erzgebirge

Beitrag von Lebostein »

Danke für den Hinweis! Scheint ja wirklich ein gutes Buch zu sein, habs mir gleich mal bestellt....
traumatic
Beiträge: 478
Registriert: 27.11.2004 15:42

Beitrag 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 ;)
Benutzeravatar
benny
Beiträge: 383
Registriert: 29.08.2004 09:18
Wohnort: Am Ende des www's
Kontaktdaten:

Beitrag 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:
So long,
benny!
.
nur t0te f1sche schw1mmen m1t dem str0m - 00100 !
Benutzeravatar
Rings
Beiträge: 971
Registriert: 29.08.2004 08:48

Beitrag 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.
Rings hat geschrieben:ziert sich nich beim zitieren
Antworten