(Maus-)Input unter Windows - wie läuft das hinter den Kulissen?



  • Hi!

    Eine Sache über die ich nicht so recht bescheid weiss ... wer generiert in Windows diverse Messages ala WM_MOUSEMOVE, WM_LBUTTONDOWN etc.? Und wer generiert dann weitere Messages ala WM_ACTIVATE wenn ein Fenster angeklickt wurde?

    Macht das ein OS Thread, oder macht das die DefaultWndProc? Oder passiert es ganz woanders?

    Also ausgehend von einem Aufruf von z.B. SendInput, wie läuft das dann weiter? Wer bekommt auf welchem Wege diese Daten als nächster, und wer kümmert sich dann darum dass die passende Nachricht an das passende Fenster geschickt wird?

    Und kann man z.B. selbst Mouseclicks irgendwie "simulieren" ohne SendInput zu verwenden (und natürlich auch ohne mouse_event() oder keybd_event() zu verwenden, und ohne einen eigenen Treiber zu schreiben etc.)? Also so dass auch alles weiterhin funktioniert, alle Controls so reagieren wie man es gewöhnt ist, und alle Messages generiert werden die auch generiert würden wenn man z.B. SendInput verwendet oder der Event ursprünglich von einem Input Treiber kommt?

    ----

    Eine andere (teilweise verwandte) Frage: angenommen am System ist ein Gerät angeschlossen welches absolute Koordinaten schickt (z.B. ein Touchscreen oder ein Digitiser Tablett ala Wacom) -- gibt es dann eine einfache Möglichkeit diese Koordinaten zu verändern bevor sie von Windows weiterverarbeitet werden? Oder muss man dazu einen Filtertreiber bemühen? Mit einem low-level Mouse Hook kann man einfach Events "fressen", aber ich hab' es bis jetzt nicht fertiggebracht die Koordinaten zu verändern wenn ich den Event "durchlassen" möchte... 😞



  • Also IMHO läuft das alles direkt über das OS, denn das OS kommuniziert ja auch mit allen Devices über die entsprechenden Treiber. Wenn Du also mit der Maus irgendwo hinklickst, sorgst Du dafür, das durch die physikalische Bewegung der Maus, der Treiber das OS über deine Aktion benachrichtigt... . Das OS prüft dann, über die Positionsinformationen vom Treiber, wo die Aktion statt fand. Anschließend wird verifiziert, welches Fenster an der entsprechenden Stelle ist/war, denn dafür waren die Aktionen ja bestimmt. Danach schickt Windows dann dem entsprechenden Programm die Nachrichten (WM_XXX).


  • Mod

    Hardware Eingaben (Mouse, Keyboard Nachrichten etc.) werden als Nachrichten in die MessageQueue platziert. Diese lösen dann auch spezielle andere Nachrichten aus. Das geschieht sehr oft in der DefWindowProc. So ist z.B. ein WM_ACTIVATE oft die einfache Folge einer WM_NCLBUTTONDOWN Nachricht, die dann direkt aus der Folge in einem SendMessage wieder an das Fenster weitergereicht wird. Gleiches gilt dann eben als Folge von WM_SETFOCUS oder WM_KILLFOCUS.

    So sind auch einige Nachrichten eben nicht gedacht, dass sie einfach frei versendet werden dürfen.

    Ebenfalls lösen Windowsfunktionen oft direkt Nachrichten aus, so z.B. SetFocus. Auch diese Nachricht erzeugt direkt WM_KILLFOCUS für das Fenster das den Focus verliert und anschliessend WM_SETFOCUS für das Fenster das den Focus bekommt.

    Nachrichten können also durch I/O ausgelöst werden oder implizit durch Funktionen ausgelöst werden. Selbst einige Windowsnachrichten können wirder in Folge andere Nachrichten nach sich ziehen.





  • Danke für die Antworten!

    Hmmm...

    Und bezüglich meiner 2. Frage -- kann ich dann davon ausgehen dass der einzig sinnvolle (bzw. mögliche) Weg Koordinaten von absoluten Input Devices zu ändern der ist, einen Filtertreiber drüberzustülpen? Wäre doof, aber wenns so ist, dann ist es eben so.

    Martin Richter schrieb:

    So ist z.B. ein WM_ACTIVATE oft die einfache Folge einer WM_NCLBUTTONDOWN Nachricht, die dann direkt aus der Folge in einem SendMessage wieder an das Fenster weitergereicht wird. Gleiches gilt dann eben als Folge von WM_SETFOCUS oder WM_KILLFOCUS.

    Bloss wer entscheidet dass WM_NCLBUTTONDOWN und nicht WM_LBUTTONDOWN geschickt wird? Ich nehme an das macht dann der Window-Manager, bzw. das passiert eben bevor irgendeine Message jemals in die Message Queue des Programmes gepostet wird, richtig?

    Hardware Eingaben (Mouse, Keyboard Nachrichten etc.) werden als Nachrichten in die MessageQueue platziert.

    Hier wieder die Frage: wer entscheidet an welches Fenster das gehen soll? Wird dann wohl auch wieder der Window-Manager sein, ...?


  • Mod

    Es wird immer WM_NCLBUTTONDOWN gesendet und aus dieser Nachricht wird erst ein WM_LBUTTONDOWN! Die meisten Nachrichten gehen auseinander hervor.

    Wer was bekommt richtet sich nach dem ActiveWindow, dem Capture und dem Focus!



  • Ah, OK, das ist schonmal was womit ich was anfangen kann 🙂
    Kann man das auch wo nachlesen? Oder muss man das wissen, bzw. Stückweise und durch Erfahrung hier und da aufklauben?

    Und: wer was bekommt richtet sich eben nicht nur nach ActiveWindow, Capture & Focus, sonst könnte man ja nie ein anderes Fenster aktivieren 😉


  • Mod

    hustbaer schrieb:

    Und: wer was bekommt richtet sich eben nicht nur nach ActiveWindow, Capture & Focus, sonst könnte man ja nie ein anderes Fenster aktivieren 😉

    Das ist korrekt. Hier spielt ja auch wieder WM_NCHITTEST eine Rolle.

    So schwer ist es nicht. Schau Dir einfach mal den Spy++ an und schau was passiert. Grundsätzlich ist das übrigends komplet in der MSDN dokumentiert. Nicht jetzt so wie Du die Frage stellst, aber die einzelnen WM_NC Nachrichten und was geschieht ist dokumentiert und es gibt ja wirklich nur ein paar Mausnachrichten, bei denen man sich dies mal zu Gemüte führen kann.
    Auch was Focus und ActiveWindow bedeuten ist dokumentiert.
    Lesen... :xmas1:



  • hustbaer schrieb:

    Mit einem low-level Mouse Hook kann man einfach Events "fressen", aber ich hab' es bis jetzt nicht fertiggebracht die Koordinaten zu verändern wenn ich den Event "durchlassen" möchte... 😞

    hi,
    wenn verändern nicht klappt, dann 'friss' doch den event und erzeuge daraufhin einen neuen mit veränderten koordinaten (mit mouse_event, SendInput o.ä.). ich nehme mal an, sowas kann zu 'ner endlosschleife führen d.h. man muss sich noch was einfallen lassen um 'echte' und selbstgemachte events zu unterscheiden...



  • net schrieb:

    hustbaer schrieb:

    Mit einem low-level Mouse Hook kann man einfach Events "fressen", aber ich hab' es bis jetzt nicht fertiggebracht die Koordinaten zu verändern wenn ich den Event "durchlassen" möchte... 😞

    hi,
    wenn verändern nicht klappt, dann 'friss' doch den event und erzeuge daraufhin einen neuen mit veränderten koordinaten (mit mouse_event, SendInput o.ä.). ich nehme mal an, sowas kann zu 'ner endlosschleife führen d.h. man muss sich noch was einfallen lassen um 'echte' und selbstgemachte events zu unterscheiden...

    Been there, done that, got the t-shirt 🙂
    Geht leider nicht wirklich. Also ein "injected" Flag gibts schon, bloss funktioniert es trotzdem nicht -- zumindest nicht so wie wir das bräuchten. Wir brauchen ja z.B. parallel noch die Maus, und im low-level mouse hook können wir z.B. nicht unterscheiden ob der Input von der Maus kommt oder nicht.


Log in to reply