[WinAPI] Mausposition bei Klick

Programmiersprachen, APIs, Bibliotheken, Open Source Engines, Debugging, Quellcode Fehler und alles was mit praktischer Programmierung zu tun hat.
Antworten
Benutzeravatar
Krishty
Establishment
Beiträge: 8267
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

[WinAPI] Mausposition bei Klick

Beitrag von Krishty »

The Old New Thing — Paint messages will come in as fast as you let them
There is a class of messages which are generated on demand rather than explicitly posted into a message queue. If you call Get­Message or Peek­Message and the queue is empty, then the window manager will look to see if one of these generated-on-demand messages is due, messages like WM_TIMER, WM_MOUSE­MOVE, and WM_PAINT.
WM_MOUSEMOVE-Nachrichten erreichen einen Thread also nur, wenn der gerade nicht ausgelastet (seine Nachrichtenschleife leer) ist. Nehmen wir jetzt an, der Anwender klickt auf das Fenster, während der Thread voll ausgelastet ist.

Würde das nicht bedeuten, dass der Klick das Fenster erreicht, ohne dass dies zuvor eine WM_MOUSEMOVE-Nachricht erhalten hat?

Ich speichere normalerweise in meinen WM_MOUSEMOVEs die Zeigerposition, und z.B. beim Picking, über welchem Objekt sich der Zeiger augenblicklich befindet. Das würde unter Last dazu führen, dass ein Klick an der falschen Stelle registriert würde.

Liege ich da richtig, oder hat jemand weiterführende Links dazu? Ist das schonmal einem von euch passiert?
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Helmut
Establishment
Beiträge: 237
Registriert: 11.07.2002, 15:49
Wohnort: Bonn
Kontaktdaten:

Re: [WinAPI] Mausposition bei Klick

Beitrag von Helmut »

Sowas lässt sich ja leicht testen. Bau einen Timer ein der jede Sekunde WM_TIMER aufruft und mach da Sleep(500).
Ich würde aber wetten, dass WM_MOUSEMOVE immer vor Mausklicknachrichten gesendet wird. Ein interner Cursorpositionswert müsste also immer mit GetMessagePos übereinstimmen. Allerdings würde ich bei ner Klicknachricht trotzdem nochmal den MOUSEMOVE Handler aufrufen. Allein schon falls sich die anklickbaren Objekte geändert haben.
gdsWizard
Establishment
Beiträge: 237
Registriert: 04.02.2005, 09:12
Benutzertext: www.gamedevstudio.com
Echter Name: Thomas Mittelsdorf
Wohnort: Meiningen
Kontaktdaten:

Re: [WinAPI] Mausposition bei Klick

Beitrag von gdsWizard »

Also in der Praxis braucht man kein WM_MOUSEMOVE vor einem Mauseklick. Zumindest bin ich bei meinem GUI ohne dies ausgekommen. Wenn ich mich richtig entsinne kannst du sogar ein WM_LBUTTONUP ohne ein WM_LBUTTONDOWN bekommen, nämlich dann wenn bei einem Mausklick sich ein Fenster schliesst, dann geht das Loslassen der Taste an das jetzt vorne liegende Fenster und das da ein WM_MOUSEMOVE gesendet wird ist auch fraglich (die Maus wurde ja nicht bewegt).
Benutzeravatar
Krishty
Establishment
Beiträge: 8267
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: [WinAPI] Mausposition bei Klick

Beitrag von Krishty »

Helmut hat geschrieben:Sowas lässt sich ja leicht testen. Bau einen Timer ein der jede Sekunde WM_TIMER aufruft und mach da Sleep(500).
Ich würde aber wetten, dass WM_MOUSEMOVE immer vor Mausklicknachrichten gesendet wird. Ein interner Cursorpositionswert müsste also immer mit GetMessagePos übereinstimmen.
Ja, richtig. Ich sehe bei hoher künstlicher Auslastung, dass jeder Klick von einem zusätzlichen WM_MOUSEMOVE an der Klick-Koordinate vorbereitet wird. Zumindest auf Windows 7. Praktisch; ich hoffe, dass es auf alten Systemen ähnlich ist.
Helmut hat geschrieben:Allerdings würde ich bei ner Klicknachricht trotzdem nochmal den MOUSEMOVE Handler aufrufen. Allein schon falls sich die anklickbaren Objekte geändert haben.
Ja; das ist aber ein anderes Problem.
gdsWizard hat geschrieben:Also in der Praxis braucht man kein WM_MOUSEMOVE vor einem Mauseklick. Zumindest bin ich bei meinem GUI ohne dies ausgekommen.
Du brauchtest es nicht, oder hat Windows es nicht geschickt?
Wenn ich mich richtig entsinne kannst du sogar ein WM_LBUTTONUP ohne ein WM_LBUTTONDOWN bekommen, nämlich dann wenn bei einem Mausklick sich ein Fenster schliesst, dann geht das Loslassen der Taste an das jetzt vorne liegende Fenster und das da ein WM_MOUSEMOVE gesendet wird ist auch fraglich (die Maus wurde ja nicht bewegt).
Doch – immer, wenn die Maus ein neues Fenster betritt, wird ein WM_MOUSEMOVE gesendet um das anzukündigen. Siehe The Old New Thing – Why is there no WM_MOUSEENTER message? und Why do I get spurious WM_MOUSEMOVE messages?:
Often, Windows wants to do that follow-on work even though the mouse hasn't actually moved. The most obvious example is when a window is shown, hidden or moved. When that happens, the mouse cursor may be over a window different from the window it was over previously (or in the case of a move, it may be over a different part of the same window). Windows needs to recalculate the mouse cursor (for example, the old window may have wanted an arrow but the new window wants a pointy finger), so it artificially sets the "The mouse moved, in case anybody cares" flag.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
gdsWizard
Establishment
Beiträge: 237
Registriert: 04.02.2005, 09:12
Benutzertext: www.gamedevstudio.com
Echter Name: Thomas Mittelsdorf
Wohnort: Meiningen
Kontaktdaten:

Re: [WinAPI] Mausposition bei Klick

Beitrag von gdsWizard »

Krishty hat geschrieben:
Du brauchtest es nicht, oder hat Windows es nicht geschickt?
Ich hatte mich ungünstig ausgedrückt. Bei meinem GUI teste ich bei einem Klick nochmal was unter der Maus ist.
Krishty hat geschrieben:
Doch – immer, wenn die Maus ein neues Fenster betritt, wird ein WM_MOUSEMOVE gesendet um das anzukündigen. Siehe The Old New Thing – Why is there no WM_MOUSEENTER message? und Why do I get spurious WM_MOUSEMOVE messages?:
Da kann ich mich ja glücklich schätzen. Ich habe nämlich WM_MOUSEENTER und WM_MOUSELEAVE ignoriert. Beim ersten WM_MOUSEMOVE generiere ich intern ein MouseEnter und capture die Maus solange wie es nötig ist. Mit WM_MOUSEMOVE prüfe ich ob ein MouseLeave notwendig ist. Das liegt allerdings daran das ich vom Amiga ausgegangen bin und der hatte kein MouseEnter und auch kein MouseLeave.
gdsWizard
Establishment
Beiträge: 237
Registriert: 04.02.2005, 09:12
Benutzertext: www.gamedevstudio.com
Echter Name: Thomas Mittelsdorf
Wohnort: Meiningen
Kontaktdaten:

Re: [WinAPI] Mausposition bei Klick

Beitrag von gdsWizard »

Mir ist aufgefallen das man auch einen Mausklick bekommen kann ohne das man ein MouseMove bekommen hat. Zumindest unter Last in der Debugversion eines Programms war das so. Wollte ich hir nur mal ergänzen.
Benutzeravatar
Krishty
Establishment
Beiträge: 8267
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: [WinAPI] Mausposition bei Klick

Beitrag von Krishty »

Das passiert nicht nur unter Last in der Debugversion, sondern kann alle Nase lang vorkommen. Siehe The Old New Thing – Why do I get spurious WM_MOUSEMOVE messages? und The Old New Thing – Sure, I can get spurious WM_MOUSEMOVE messages, but why do they keep streaming in?.

Ein Fall, den ich letztens erfahren habe, und der dort nicht erwähnt wird: Die Maus arbeitet in Windows mit Subpixelpräzision (falls die Maus über die entsprechende Auflösung verfügt). Wenn man Raw Input benutzt, kommt WM_MOUSEMOVE mit 0 und 0, wenn die Maus um weniger als einen Pixel bewegt wurde.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
BeRsErKeR
Establishment
Beiträge: 689
Registriert: 27.04.2002, 22:01

Re: [WinAPI] Mausposition bei Klick

Beitrag von BeRsErKeR »

Helmut hat geschrieben:Sowas lässt sich ja leicht testen. Bau einen Timer ein der jede Sekunde WM_TIMER aufruft und mach da Sleep(500).
Ich würde aber wetten, dass WM_MOUSEMOVE immer vor Mausklicknachrichten gesendet wird. Ein interner Cursorpositionswert müsste also immer mit GetMessagePos übereinstimmen. Allerdings würde ich bei ner Klicknachricht trotzdem nochmal den MOUSEMOVE Handler aufrufen. Allein schon falls sich die anklickbaren Objekte geändert haben.
Ist das nicht genau der falsche Test? WM_TIMER kommt laut Krishty ja auch nicht in die Queue, sondern wird auch on-demand generiert. Man müsste doch als Test dafür sorgen, dass die Queue immer voll ist.
Ohne Input kein Output.
Benutzeravatar
Krishty
Establishment
Beiträge: 8267
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: [WinAPI] Mausposition bei Klick

Beitrag von Krishty »

Wie meinst du das? Wenn der Timer ausgelöst wird, gibt er mir eine halbe Sekunde Zeit, zu klicken und die Maus wegzubewegen. Danach habe ich eine halbe Sekunde normalen Programmablaufs, um die eingehenden Nachrichten zu verarbeiten und zu prüfen, ob der Klick an der richtigen Stelle stattfand. In dieser Zeit wird keine WM_TIMER-Nachricht auftreten. Außerdem:
Krishty hat geschrieben:Ich sehe bei hoher künstlicher Auslastung, dass jeder Klick von einem zusätzlichen WM_MOUSEMOVE an der Klick-Koordinate vorbereitet wird. Zumindest auf Windows 7. Praktisch; ich hoffe, dass es auf alten Systemen ähnlich ist.
WM_MOUSEMOVE ist ein Flag mit niedriger Priorität – ich bekomme die Nachricht nur, wenn gerade alle anderen verarbeitet sind (gleiches gilt für WM_TIMER und WM_PAINT). Da ich die Nachricht aber vor WM_LBUTTONDOWN bekommen habe, obwohl das System hoch ausgelastet war und jede Menge anderer Nachrichten in der Schleife waren (wie besagtes WM_LBUTTONDOWN), bedeutet das, dass die Nachricht explizit vom Window Manager in die Schlange gesetzt worden sein muss. Sonst wäre sie ja erst viel später angekommen, wenn die Belastung abklingt und das Flag überprüft wird. Ich gehe deshalb stark davon aus, dass das fest in Windows 7 verdrahtet ist.

Zumal es mir dadurch abnimmt, einen Fehler abzudecken, der einem spontan garnicht auffällt (und das tut das Windows-Team häufiger).
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
BeRsErKeR
Establishment
Beiträge: 689
Registriert: 27.04.2002, 22:01

Re: [WinAPI] Mausposition bei Klick

Beitrag von BeRsErKeR »

Krishty hat geschrieben:Wie meinst du das? Wenn der Timer ausgelöst wird, gibt er mir eine halbe Sekunde Zeit, zu klicken und die Maus wegzubewegen. Danach habe ich eine halbe Sekunde normalen Programmablaufs, um die eingehenden Nachrichten zu verarbeiten und zu prüfen, ob der Klick an der richtigen Stelle stattfand. In dieser Zeit wird keine WM_TIMER-Nachricht auftreten. Außerdem:
Krishty hat geschrieben:Ich sehe bei hoher künstlicher Auslastung, dass jeder Klick von einem zusätzlichen WM_MOUSEMOVE an der Klick-Koordinate vorbereitet wird. Zumindest auf Windows 7. Praktisch; ich hoffe, dass es auf alten Systemen ähnlich ist.
WM_MOUSEMOVE ist ein Flag mit niedriger Priorität – ich bekomme die Nachricht nur, wenn gerade alle anderen verarbeitet sind (gleiches gilt für WM_TIMER und WM_PAINT). Da ich die Nachricht aber vor WM_LBUTTONDOWN bekommen habe, obwohl das System hoch ausgelastet war und jede Menge anderer Nachrichten in der Schleife waren (wie besagtes WM_LBUTTONDOWN), bedeutet das, dass die Nachricht explizit vom Window Manager in die Schlange gesetzt worden sein muss. Sonst wäre sie ja erst viel später angekommen, wenn die Belastung abklingt und das Flag überprüft wird. Ich gehe deshalb stark davon aus, dass das fest in Windows 7 verdrahtet ist.

Zumal es mir dadurch abnimmt, einen Fehler abzudecken, der einem spontan garnicht auffällt (und das tut das Windows-Team häufiger).
Ich versteh immer noch nicht wozu du die WM_MOUSEMOVE überhaupt brauchst. Aber wenn es vorm Klick immer generiert wird dann ist ja alles gut.
Ohne Input kein Output.
Benutzeravatar
Krishty
Establishment
Beiträge: 8267
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: [WinAPI] Mausposition bei Klick

Beitrag von Krishty »

BeRsErKeR hat geschrieben:Ich versteh immer noch nicht wozu du die WM_MOUSEMOVE überhaupt brauchst. Aber wenn es vorm Klick immer generiert wird dann ist ja alles gut.
Stell dir vor, du arbeitest an einem 3D-Editor. Das Objekt unter dem Mauszeiger soll immer farblich hervorgehoben werden, oder der Mauszeiger soll als 3D-Fadenkreuz in der Szene angezeigt werden statt als Windows-Mauscursor. In diesem Fall benutzt du WM_MOUSEMOVE, um das Picking durchzuführen, das Fadenkreuz zu setzen, und die Objektfarben zu bestimmen.

Dass im Zweifel immer ein WM_MOUSEMOVE vor dem Klick kommt, erleichtert dir dabei einiges – denn so musst du das Picking nicht beim Klick neu durchführen, sondern hast garantiert, dass der Zeiger immernoch über demselben Objekt ist wie bei der letzten Mausbewegung :-) Du musst also nicht mehr doppelt picken, und hast das Picking nur an einer einzigen Stelle im Code (bei der Mausbewegung).
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
BeRsErKeR
Establishment
Beiträge: 689
Registriert: 27.04.2002, 22:01

Re: [WinAPI] Mausposition bei Klick

Beitrag von BeRsErKeR »

Das Einzige wo das eine Rolle spielen würde ist, wenn du ein anderes Fenster in den Vordergrund holst und dann ohne Mausbewegung klickst oder wenn sich im Fenster was verändert während die Maus stehen bleibt. Beides aber eher sehr seltene Fälle die prinzipiell schwer erreicht werden. Beim ersten Fall musst du über Tastatur die Fenster switchen (Alt + Tab, Windowstaste + Tab, etc), beim zweiten Fall muss irgendwas automatisch gestartet werden. Und in jedem Fall muss die Maus absolut unangetastet bleiben. Aber ok, sicher ist natürlich sicher bzw. nun hat es sich ja glücklicherweise eh erledigt. ;)
Ohne Input kein Output.
Benutzeravatar
Krishty
Establishment
Beiträge: 8267
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: [WinAPI] Mausposition bei Klick

Beitrag von Krishty »

Nicht nur dann. Windows schickt allgemeine WM_MOUSEMOVEs NICHT wenn sich die Maus bewegt, sondern nur, wenn die Anwendung im Leerlauf ist. Schlimmstenfalls hätte also bei einer rechenintensiven Anwendung jeder Klick an der falschen Stelle stattgefunden, wenn nicht eben die garantierten Nachrichten vor jedem Klick kämen, nach denen ich hier gefragt hatte ;-)
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
BeRsErKeR
Establishment
Beiträge: 689
Registriert: 27.04.2002, 22:01

Re: [WinAPI] Mausposition bei Klick

Beitrag von BeRsErKeR »

Krishty hat geschrieben:Nicht nur dann. Windows schickt allgemeine WM_MOUSEMOVEs NICHT wenn sich die Maus bewegt, sondern nur, wenn die Anwendung im Leerlauf ist. Schlimmstenfalls hätte also bei einer rechenintensiven Anwendung jeder Klick an der falschen Stelle stattgefunden, wenn nicht eben die garantierten Nachrichten vor jedem Klick kämen, nach denen ich hier gefragt hatte ;-)
Naja Leerlauf ja nur im Sinne von leerer Nachrichtenwarteschlange. Die wirst du aber kaum permanent vollhauen können. Maximal mit WM_TIMER, aber die kommen ja auch nicht in die Warteschlange. Und falls die Warteschlange auf Grund von anderer Auslastung voll bleibt, dann läuft ja eh schon was schief und dann kommt theoretisch auch der Klick nicht zur richtigen Zeit (dann funktioniert auch der Ansatz mit automatischer WM_MOUSEMOVE + WM_LBUTTONDOWN nicht mehr korrekt). Im Normalfall wird ja eigentlich die Nachrichtenwarteschlange pro Frame durchgerattert, d.h. sie ist nach einem Frame auch leer.

Was ich mich aber vorallem frage ist, welches Szenario es geben könnte, dass bei Vollauslastung noch irgendwelche Mausklicks korrekt und vorallem überhaupt ausgewertet werden sollten. Unter Volllast versuch ich in der Regel doch nicht noch irgendwelche Sachen anzuklicken. Da freu ich mich über die kleine Sanduhr und warte auf bessere Zeiten. :)
Ohne Input kein Output.
Benutzeravatar
Krishty
Establishment
Beiträge: 8267
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: [WinAPI] Mausposition bei Klick

Beitrag von Krishty »

BeRsErKeR hat geschrieben:Und falls die Warteschlange auf Grund von anderer Auslastung voll bleibt, dann läuft ja eh schon was schief und dann kommt theoretisch auch der Klick nicht zur richtigen Zeit (dann funktioniert auch der Ansatz mit automatischer WM_MOUSEMOVE + WM_LBUTTONDOWN nicht mehr korrekt).
Der Klick kommt dann leicht verzögert, aber warum sollte es dann nicht mehr korrekt funktionieren?
BeRsErKeR hat geschrieben:Im Normalfall wird ja eigentlich die Nachrichtenwarteschlange pro Frame durchgerattert, d.h. sie ist nach einem Frame auch leer.
Die meisten Windows-Anwendungen kennen keine Frames ;-)
BeRsErKeR hat geschrieben:Was ich mich aber vorallem frage ist, welches Szenario es geben könnte, dass bei Vollauslastung noch irgendwelche Mausklicks korrekt und vorallem überhaupt ausgewertet werden sollten. Unter Volllast versuch ich in der Regel doch nicht noch irgendwelche Sachen anzuklicken. Da freu ich mich über die kleine Sanduhr und warte auf bessere Zeiten. :)
Es gibt z.B. im CAD-Bereich viele Szenarien, wo allein das Darstellen der Szene schon eine halbe Sekunde dauern kann. Natürlich muss die Anwendung dann noch korrekt funktionieren und Klicks an den richtigen Stellen und in der richtigen Reihenfolge verarbeiten, wenn auch mit Latenz. Davon, dass du vor dem Bildschirm sitzt und abwartest dass dein Level von allein schneller dargestellt wird, wird nichts fertig ;-)
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
BeRsErKeR
Establishment
Beiträge: 689
Registriert: 27.04.2002, 22:01

Re: [WinAPI] Mausposition bei Klick

Beitrag von BeRsErKeR »

Krishty hat geschrieben:
BeRsErKeR hat geschrieben:Und falls die Warteschlange auf Grund von anderer Auslastung voll bleibt, dann läuft ja eh schon was schief und dann kommt theoretisch auch der Klick nicht zur richtigen Zeit (dann funktioniert auch der Ansatz mit automatischer WM_MOUSEMOVE + WM_LBUTTONDOWN nicht mehr korrekt).
Der Klick kommt dann leicht verzögert, aber warum sollte es dann nicht mehr korrekt funktionieren?
Wenn die Warteschlange 5 Sekunden blockiert ist, ist deine Maus schon sonstwo und du kannst in der Zeit schon 3 mal woanders geklickt haben. Irgendwann kommt dann endlich mal die Nachricht vom ersten Klick. Das wäre wohl kaum im Sinne des Erfinders, wenn du dann irgendwo anders was markierst.

Krishty hat geschrieben:
BeRsErKeR hat geschrieben:Im Normalfall wird ja eigentlich die Nachrichtenwarteschlange pro Frame durchgerattert, d.h. sie ist nach einem Frame auch leer.
Die meisten Windows-Anwendungen kennen keine Frames ;-)
Ok ich vergass, dass du mit der WinAPI noch Oberflächen bastelst. ;) Aber wenn dann da was zeitkritisches läuft, dann doch hoffentlich in einem eigenen Thread und dann hast du das Problem eigentlich eh nicht mehr.

Krishty hat geschrieben:
BeRsErKeR hat geschrieben:Was ich mich aber vorallem frage ist, welches Szenario es geben könnte, dass bei Vollauslastung noch irgendwelche Mausklicks korrekt und vorallem überhaupt ausgewertet werden sollten. Unter Volllast versuch ich in der Regel doch nicht noch irgendwelche Sachen anzuklicken. Da freu ich mich über die kleine Sanduhr und warte auf bessere Zeiten. :)
Es gibt z.B. im CAD-Bereich viele Szenarien, wo allein das Darstellen der Szene schon eine halbe Sekunde dauern kann. Natürlich muss die Anwendung dann noch korrekt funktionieren und Klicks an den richtigen Stellen und in der richtigen Reihenfolge verarbeiten, wenn auch mit Latenz. Davon, dass du vor dem Bildschirm sitzt und abwartest dass dein Level von allein schneller dargestellt wird, wird nichts fertig ;-)
Naja aber man kann doch die Oberfläche auch für diese halbe Sekunde einfach sperren. Das ist allemal sicherer und wird als "korrektes Verhalten" erkannt. Mich würde es ziemlich nerven wenn mein Mauszeiger da rumruckelt oder die Klicks erst 500ms später reagieren.
Ohne Input kein Output.
Benutzeravatar
Krishty
Establishment
Beiträge: 8267
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: [WinAPI] Mausposition bei Klick

Beitrag von Krishty »

BeRsErKeR hat geschrieben:
Krishty hat geschrieben:
BeRsErKeR hat geschrieben:Und falls die Warteschlange auf Grund von anderer Auslastung voll bleibt, dann läuft ja eh schon was schief und dann kommt theoretisch auch der Klick nicht zur richtigen Zeit (dann funktioniert auch der Ansatz mit automatischer WM_MOUSEMOVE + WM_LBUTTONDOWN nicht mehr korrekt).
Der Klick kommt dann leicht verzögert, aber warum sollte es dann nicht mehr korrekt funktionieren?
Wenn die Warteschlange 5 Sekunden blockiert ist, ist deine Maus schon sonstwo und du kannst in der Zeit schon 3 mal woanders geklickt haben. Irgendwann kommt dann endlich mal die Nachricht vom ersten Klick. Das wäre wohl kaum im Sinne des Erfinders, wenn du dann irgendwo anders was markierst.
Nein. Windows speichert den Zustand von Maus, Tastatur, und Systemzeit zu jeder Nachricht. Für dein Programm befindet sich der Zeiger also immer da, wo er beim Auslösen der Nachricht war – wenn du die Nachricht fünf Sekunden später verarbeitest, bekommst du die Zeigerposition dort, wo er fünf Sekunden vorher war. (Es sei denn, man benutzt absichtlich die asynchronen Pendants der WinAPI.)
BeRsErKeR hat geschrieben:
Krishty hat geschrieben:
BeRsErKeR hat geschrieben:Was ich mich aber vorallem frage ist, welches Szenario es geben könnte, dass bei Vollauslastung noch irgendwelche Mausklicks korrekt und vorallem überhaupt ausgewertet werden sollten. Unter Volllast versuch ich in der Regel doch nicht noch irgendwelche Sachen anzuklicken. Da freu ich mich über die kleine Sanduhr und warte auf bessere Zeiten. :)
Es gibt z.B. im CAD-Bereich viele Szenarien, wo allein das Darstellen der Szene schon eine halbe Sekunde dauern kann. Natürlich muss die Anwendung dann noch korrekt funktionieren und Klicks an den richtigen Stellen und in der richtigen Reihenfolge verarbeiten, wenn auch mit Latenz. Davon, dass du vor dem Bildschirm sitzt und abwartest dass dein Level von allein schneller dargestellt wird, wird nichts fertig ;-)
Naja aber man kann doch die Oberfläche auch für diese halbe Sekunde einfach sperren. Das ist allemal sicherer und wird als "korrektes Verhalten" erkannt. Mich würde es ziemlich nerven wenn mein Mauszeiger da rumruckelt oder die Klicks erst 500ms später reagieren.
Was meinst du mit „Sperren“? Wenn ich die Oberfläche sperre, reagiert das Programm ja garnicht mehr, es gehen also Benutzereingaben verloren … das wäre ja völlig unbenutzbar. Ohne Sperre läuft die Oberfläche hingegen genau so weiter wie du es erwartest, zeigt aber alles nur mit einer halben Sekunde Verzögerung an.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
BeRsErKeR
Establishment
Beiträge: 689
Registriert: 27.04.2002, 22:01

Re: [WinAPI] Mausposition bei Klick

Beitrag von BeRsErKeR »

Krishty hat geschrieben:
BeRsErKeR hat geschrieben:
Krishty hat geschrieben:
BeRsErKeR hat geschrieben:Und falls die Warteschlange auf Grund von anderer Auslastung voll bleibt, dann läuft ja eh schon was schief und dann kommt theoretisch auch der Klick nicht zur richtigen Zeit (dann funktioniert auch der Ansatz mit automatischer WM_MOUSEMOVE + WM_LBUTTONDOWN nicht mehr korrekt).
Der Klick kommt dann leicht verzögert, aber warum sollte es dann nicht mehr korrekt funktionieren?
Wenn die Warteschlange 5 Sekunden blockiert ist, ist deine Maus schon sonstwo und du kannst in der Zeit schon 3 mal woanders geklickt haben. Irgendwann kommt dann endlich mal die Nachricht vom ersten Klick. Das wäre wohl kaum im Sinne des Erfinders, wenn du dann irgendwo anders was markierst.
Nein. Windows speichert den Zustand von Maus, Tastatur, und Systemzeit zu jeder Nachricht. Für dein Programm befindet sich der Zeiger also immer da, wo er beim Auslösen der Nachricht war – wenn du die Nachricht fünf Sekunden später verarbeitest, bekommst du die Zeigerposition dort, wo er fünf Sekunden vorher war. (Es sei denn, man benutzt absichtlich die asynchronen Pendants der WinAPI.)
Ich meine damit nicht, dass irgendwas Falsches markiert wird. Aber wenn z.B. der erste Klick mit 1 Sekunde Verzögerung kommt und der zweite Klick mit 5 Sekunden, dann wird sich der Anwender wundern, warum nun doch wieder das erste Element selektiert ist, obwohl er doch kurz danach gleich auf das Nächste geklickt hat. Objektiv sieht das dann stark nach einem Fehlverhalten aus, was ihn zu einem erneuten Klick bewegt etc. Genau deshalb würde ich hier erst gar keine Benutzereingaben akzeptieren, aber dies dem Anwender auch deutlich machen. Oder ist die Last permanent vorhanden und "normal" während der Bedienung? Selbst dann würd ich mir irgendwie was anderes überlegen, weil etwas mit permanenter Verzögerung bedienen zu müssen macht aus Usabilitysicht alles andere als Spaß.
Ohne Input kein Output.
Benutzeravatar
Krishty
Establishment
Beiträge: 8267
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: [WinAPI] Mausposition bei Klick

Beitrag von Krishty »

BeRsErKeR hat geschrieben:Oder ist die Last permanent vorhanden und "normal" während der Bedienung? Selbst dann würd ich mir irgendwie was anderes überlegen, weil etwas mit permanenter Verzögerung bedienen zu müssen macht aus Usabilitysicht alles andere als Spaß.
Ja genau; sie ist ständig da. Bedenk, dass Windows kein Echtzeitsystem ist, und es nicht zwingend deine Schuld ist wenn das Programm ewig braucht – da könnte auch der Downloadmanager im Hintergrund was extrahieren oder das System könnte gerade aus dem Standby-Modus aufwachen, so dass jeder Funktionsaufruf erstmal einen Hard Page Fault auslöst. Der häufigste Fall ist aber, dass User einfach tausend Mal so viele Daten ins Programm schmeißen wie gedacht, und dann plötzlich so Sachen wie Text-Rendering zum Flaschenhals werden. Dann kann man nicht einfach bei jedem Frame das Fenster abschalten und eine Sanduhr einblenden.

(Windows wurde damals so ausgelegt, dass Power-User ihre Tastenkombinationen reinknattern können sogar wenn das System zum Laden des geforderten Dialogs länger braucht als der User für seine Eingaben – in dem Fall würde der Dialog niemals auf dem Bildschirm erscheinen, sondern das Programm direkt zum Ergebnis springen. Sowas geht nicht mehr wenn du Faxen machst wie Input sperren.)
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
BeRsErKeR
Establishment
Beiträge: 689
Registriert: 27.04.2002, 22:01

Re: [WinAPI] Mausposition bei Klick

Beitrag von BeRsErKeR »

Krishty hat geschrieben:
BeRsErKeR hat geschrieben:Oder ist die Last permanent vorhanden und "normal" während der Bedienung? Selbst dann würd ich mir irgendwie was anderes überlegen, weil etwas mit permanenter Verzögerung bedienen zu müssen macht aus Usabilitysicht alles andere als Spaß.
Ja genau; sie ist ständig da. Bedenk, dass Windows kein Echtzeitsystem ist, und es nicht zwingend deine Schuld ist wenn das Programm ewig braucht – da könnte auch der Downloadmanager im Hintergrund was extrahieren oder das System könnte gerade aus dem Standby-Modus aufwachen, so dass jeder Funktionsaufruf erstmal einen Hard Page Fault auslöst. Der häufigste Fall ist aber, dass User einfach tausend Mal so viele Daten ins Programm schmeißen wie gedacht, und dann plötzlich so Sachen wie Text-Rendering zum Flaschenhals werden. Dann kann man nicht einfach bei jedem Frame das Fenster abschalten und eine Sanduhr einblenden.
Wenn der Downloadmanager im Hintergrund läuft ist das in der Regel schon meine Schuld. Wenn ich sowas laufen hab oder irgenwelche aufwendigen Sachen nebenher laufen, dann versuche ich nicht irgendwas nebenbei zu bedienen. Wenn ich auf Arbeit ein paar Tools auf habe ist das Visual Studio auch nicht mehr bedienbar und dann warte ich bis die anderen Tools durch sind bevor ich weiter mache. Ansonsten besteht sogar die Gefahr, dass es abraucht. Und das ist mit vielen Programmen so. Unter Last ein Programm bedienbar zu halten finde ich einfach nicht sinnvoll. Es mag Sonderfälle geben, aber schön ist es trotzdem nicht.

Wenn der User die Möglichkeit hat zu viele Daten reinzukippen, dann hat man ja auch schon was falsch gemacht. Ich würde das erst gar nicht zulassen. Wie gesagt wird das nicht immer möglich sein, aber in den meisten Fällen schon. Für manche Fälle gibt es auch einfach Streaming-Ansätze für Daten, je nach Aufgabe/Programm halt.

Ich will dir da nicht reinreden. Du wirst wissen was du tust. Aber ich finds halt einfach unschön.
Ohne Input kein Output.
Antworten