WindowProc + Haupt-Thread



  • Dadurch das die WindowProc zu jedem beliebigen Zeitpunkt den eigentlichen
    Programmcode unterbrechen kann, wird es doch zu Problemen kommen können,
    wenn WindowProc und der eigentliche Programmcode beide auf gleichen
    Variablen arbeiten.

    Mit "mutex machen" meinte ich, das ich diese Variablen unter gegenseitigen
    Ausschluss stellen muss (http://de.wikipedia.org/wiki/Mutex),
    da mir die WindowProc ja quasi wie ein nebenläufiger Thread die gemeinsam
    verwendeten Variablen zu ungewollten Zeitpunkten verändern kann.



  • Wenn du Variable threatübergreifend benutzen willst würde ich dir CriticalSection empfehlen.


  • Mod

    Es gibt keine willkürliche Unterbrechung und alle Aufrufe in einer WndProc geschehen immer innerhalb eines Thread Contextes und erfolgen synchron.
    Zum einfachen Verständnig stell Dir einfach vor, dass SendMessage nichts anderes ist als der Aufruf Deiner WndProc. Also eine simple Subroutine. Hier wird nichts unterbrochen sondern alles geschieht schon synchron.

    I/O Nachrichten wie Tastatur und Maus werden die Messagequeue gepackt und nur von der Messgeloop abgearbeitet.

    Ein Mutex/CriticalSection in einer WndProc macht Null Sinn, denn per Defiition ist eine WndProc threadafin, das heißt: Sie wird nur in einem Thread Conmtext genutzt.

    Sicherlich kann eine WndProc rekursiv aufgerufen werden. Das geschieht sogar sehr häufig.



  • Martin Richter schrieb:

    Es gibt keine willkürliche Unterbrechung

    Hallo Martin,

    Windows kann doch zu beliebigen Zeitpunkten eine "Nonqueued Messages"
    an mein Programm schicken und damit meinen Programmcode unterbrechen.

    Gruß


  • Mod

    Nein! Eben nicht.
    Wenn Du Code ausführst dann führt Dein Thread eben Code aus. Es gibt keinerlei Möglichkeit in diesem Moment an ein Fenster Deines Thread eine Nachricht zu senden, außer Dein Code tut es selbst durch Funktionen wie SetWindowText, SetFocus, CreateWindow etc.



  • Non-queued messages sind einfach Nachrichten, die nicht auf die Ausführung von anderen Nachrichten warten müssen. Wenn du also SendMessage(...) aufrufst, wird deine Window Procedure mit den gegebenen Parametern aufgerufen _ohne_ vorher bereits gesendete noch nicht verarbeitete Nachrichten zuerst abzuarbeiten.

    Gruß
    Don06



  • Martin Richter schrieb:

    Es gibt keinerlei Möglichkeit in diesem Moment an ein Fenster Deines Thread eine Nachricht zu senden, außer Dein Code tut es selbst

    Hallo,

    ich weiß das ich diese "nonqueued messages" auch selbst auslösen kann,
    aber sie können auch einfach durch windows ausgelöst werden:

    http://msdn.microsoft.com/en-us/library/ms644927.aspx
    "The system typically sends nonqueued messages to notify a window of events
    that affect it. For example, when the user activates a new application window,
    the system sends the window a series of messages, including WM_ACTIVATE,
    WM_SETFOCUS, and WM_SETCURSOR. These messages notify the window that it has
    been activated, that keyboard input is being directed to the window, and that
    the mouse cursor has been moved within the borders of the window. Nonqueued
    messages can also result when an application calls certain system functions."

    Hier steht eindeutig, dass diese Nachrichten sowohl vom Programmierer
    selbst aber auch vom System ausgelöst werden können!


  • Mod

    Aber sie passieren eben nicht asynchron!!!
    Das steht doch da auch. Und auf die entsprechenden Funktionen habe ich ja auch schon hingewiesen.

    Solch eine Nachricht passiert nur wenn Du eine Windows API Funktion mit entsprechender Funktionsweise ausführst! Und das auch nur wenn es ein Fenster aus Deinem Thread betrifft.

    Wenn Du eine Schleife baust, in der keinerlei Windows API Funktion vorkommt, dann wird an kein Fenster dieses Threads irgend eine Nachricht ausgeliefert! Punkt!!! Das ist z.B. der Moment in dem im Taskmanger angezeigt wird, dass die Applikation nicht reagiert.

    Betrifft es ein Fenster aus einem anderen Thread gibt es erst recht keine Unterbrechung! Dann muss sogar die Nachrichtenschleife laufen, sonst blockiert solch eine Funktion sogar, die SendMessage verwendet.

    Es gibt keine asynchronen SendMessage Aufrufe, außer man führt eine Nachrichtenschleife aus, oder führt eine COM Funktion aus einem STA in einem anderen Appartment aus.

    SendMessage ist nichts anderes als ein Gosub in Deine Nachrichtenschleife (wenn das Fenster im selen Thread liegt)!



  • Ok also wenn das wirklich so ist, das "nonqueued messages"
    niemals von windows alleine aus eintrudeln sondern nur
    durch den eigenen aufruf von winapi funktionen, dann
    brauch ich da ja nichts absichern. danke!


  • Mod

    So ist es!
    Man muss sich in einer Single Thread GUI Applikation nur gewahr sein, dass der Aufruf einer API Funktion eben auch zu einem beliebigen rekursiven Aufruf von Fensterprozeduren auswirken kann. Und wenn man es geschickt anstellt, kriegt man dann auch leicht einen Stack Overflow hin 😉

    Aber eine Fensterprozedurwird immer nur in einem Threadkontext aufgerufen. Mutexe, CriticalSections und Semaphoren hätten also nie eine Wirkung...


Anmelden zum Antworten