AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Win32/Win64 API (native code) Delphi Maus sperren während Tastatureingabe
Thema durchsuchen
Ansicht
Themen-Optionen

Maus sperren während Tastatureingabe

Ein Thema von blackdrake · begonnen am 17. Nov 2008 · letzter Beitrag vom 8. Apr 2010
Antwort Antwort
Seite 5 von 6   « Erste     345 6      
Apollonius

Registriert seit: 16. Apr 2007
2.325 Beiträge
 
Turbo Delphi für Win32
 
#41

Re: Maus sperren während Tastatureingabe

  Alt 19. Nov 2008, 22:09
Wenn du SetWindowsHookEx mit einem gültigen HInstance-Wert aufrufst, führt das dazu, dass, wann immer eine Anwendung eine entsprechende Nachricht empfängt, geprüft wird, ob die Hook-DLL geladen wird, wenn nein, wird sie geladen und DllMain aufgerufen. Anschließend wird in jedem Fall die Hook-Prozedur aufgerufen.
In jeder Anwendung, die Maus-Nachrichten empfängt, gibt es also eine eigenständige Instanz der DLL. Das ist auch der Grund, warum eine MMF nötig ist: Alle Instanzen haben einen unabhängigen Satz von globalen Variablen.

Hast du es eigentlich schon einmal mit GetAsyncKeyState versucht, um den Status der Steuerungs-Taste zu überprüfen?
Wer erweist der Welt einen Dienst und findet ein gutes Synonym für "Pointer"?
"An interface pointer is a pointer to a pointer. This pointer points to an array of pointers, each of which points to an interface function."
  Mit Zitat antworten Zitat
blackdrake

Registriert seit: 22. Aug 2003
Ort: Bammental
618 Beiträge
 
Delphi 10.3 Rio
 
#42

Re: Maus sperren während Tastatureingabe

  Alt 19. Nov 2008, 22:26
Zitat von Apollonius:
Das ist auch der Grund, warum eine MMF nötig ist: Alle Instanzen haben einen unabhängigen Satz von globalen Variablen.
Achso, das wird dann auch der Grund sein, wieso der Timer im Notepad einen Interval ("var lock_interval") von 0 statt 3000 hatte.

Also mache ich jetzt eine Planänderung:

1. Host-App startet DLL und die Hooks
2. DLL erkennt einen Tastatur-Tastendruck und sagt der Host-App "WM_ANYKEYPRESSED", die Host-App merkt sich den GetTickCount()
3. DLL erkennt einen Maus-Tastendruck und fragt Host-APP "WM_LMB_KEY_CONFIRM", was dann von der Host-App mit 10 oder 0/Irgendwas/Timeout beantwortet wird, diese Entscheidung ist abhängig vom Abstand zum zuvor gemerkten GetTickCount(), der größer oder kleinergleich 3 Sekunden ist
4a. Wird nicht 10 geantwortet, dann akzeptiert die DLL das Mausereignis
4b. Wird 10 geantwortet, dann verwirft die DLL das Mausereignis und sendet an die Host-App "WM_LMB_LOCKED"
5. Host-App reagiert auf "WM_LMB_LOCKED", in dem der Systemmauszeiger auf crNo gesetzt wird (hier mein anderes Problem)
6. In der DLL wird nun 3 Sekunden gewartet und sendet dann "WM_LMB_UNLOCKED" (da kommt wieder mein NonVCL Timer-Problem )
7. Host-App reagiert auf "WM_LMB_UNLOCKED", in dem der Systemmauszeiger wieder neutralisiert wird

Alles korrekt geplant? Ich war/bin mir unschlüssig, ob es sinnvoll ist, dass sowohl die Host-App als auch die DLL einen 3-Sekunden-Timer hat. ob der 3-Sekunden-Timer in der DLL oder in der Host-App sein sollte.

Zitat von Apollonius:
Hast du es eigentlich schon einmal mit GetAsyncKeyState versucht, um den Status der Steuerungs-Taste zu überprüfen?
Ja, hatte ich auch versucht, aber vielleicht habe ich irgendwas mit SHL o.ä. nicht beachtet. Ich habe verschiedene Sourcen gegoogelt, aber es hat keinen Erfolg erbracht (bzw. viele Beispiele gingen von einem Keycode des Ereignisses OnKeyPress aus)
Daniel Marschall
  Mit Zitat antworten Zitat
Apollonius

Registriert seit: 16. Apr 2007
2.325 Beiträge
 
Turbo Delphi für Win32
 
#43

Re: Maus sperren während Tastatureingabe

  Alt 19. Nov 2008, 22:35
Der Timer sollte in der zentralen Anwendungen sein. Ansonsten kann es zu seltsamen Ergebnissen kommen, wenn erst Applikation A ein Mausereignis erhält und nach einer gewissen Zeit Applikation B. Vom letzten Ereignis hat Applikation A aber keine Kenntnis, sodass der Timer zu früh auslöst. Wenn du einen zentralen Waitable Timer hast, ist das kein Problem. Außerdem ist das deutlich ressourcenschonender.
Wer erweist der Welt einen Dienst und findet ein gutes Synonym für "Pointer"?
"An interface pointer is a pointer to a pointer. This pointer points to an array of pointers, each of which points to an interface function."
  Mit Zitat antworten Zitat
blackdrake

Registriert seit: 22. Aug 2003
Ort: Bammental
618 Beiträge
 
Delphi 10.3 Rio
 
#44

Re: Maus sperren während Tastatureingabe

  Alt 19. Nov 2008, 22:50
Achso, langsam blicke ich durch. Vielen Dank.

Hier der aktualisierte Plan für morgen:

1. Host-App startet DLL und die Hooks
2. DLL erkennt einen Tastatur-Tastendruck (Ausnahme Strg oder Shift) und sagt der Host-App "WM_ANYKEYPRESSED", die Host-App merkt sich den GetTickCount()
3. DLL erkennt einen Maus-Tastendruck und fragt Host-APP "WM_LMB_KEY_CONFIRM", was dann von der Host-App mit 10 oder 0/Irgendwas/Timeout beantwortet wird, diese Entscheidung ist abhängig vom Abstand zum zuvor gemerkten GetTickCount(), der größer oder kleinergleich 3 Sekunden ist
4a. Wird nicht 10 geantwortet, dann akzeptiert die DLL das Mausereignis
4b. Wird 10 geantwortet, dann verwirft die DLL das Mausereignis und sendet an die Host-App "WM_LMB_LOCKED"
5. Host-App reagiert auf "WM_LMB_LOCKED" und setzt den Systemmauszeiger auf crNo (hier mein anderes Problem)
6. Die Host-App setzt den 3-Sekunden-VCL-Timer zurück bzw. startet ihn neu.
7. Schlägt der VCL-Timer zu, deaktiviert er sich selbst und der Systemmauszeiger wird wieder neutralisiert. Zu diesem Zeitpunkt ist dann auch der Abstand zwischen den GetTickCount() wieder größer als 3 Sekunden und somit kann der Benutzer auch wieder klicken (VCL-Timer ist unabhängig von der Entscheidung, ob Klick erlaubt ist oder nicht und ist GUI Bestandteil)


Ereignisse, die wegfallen: WM_LMB_UNLOCKED (-> nun im Timer der Host-App) und WM_LMB_BLOCKED (Host-App reagiert auf WM_LMB_KEY_CONFIRM und führt selbst ein grafisches Ereignis aus, wenn ein Klick verboten ist), WM_LMB_LOCKED (Die Host-App erkennt den illegalen Klick und sendet die Antwort 10 für die Unterbindung, deswegen kennt sie zu diesem Zeitpunkt schon, dass jetzt eine Sperrphase eingetreten ist)

Hey, irgendwie taucht das NonVCL-Timer-Problem nicht mehr in meinem Plan auf

Weiterer Vorteil: Die DLL muss nun die Information mit den (variablen) 3 Sekunden nicht mehr kennen
Daniel Marschall
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#45

Re: Maus sperren während Tastatureingabe

  Alt 19. Nov 2008, 23:05
Hallo blackdrake,

hier schon mal die App, die das tut. Ich nenne sie 'Mouse Takes A Nap When Typing'.

- Anzeige des Maus-Status im Tray
- Ctrl und Shift können mit der Maus zusammen verwendet werden.
- Delay ist auf 3000 Millisekunden gestellt.

Eine Einschränkung hat das Prog ... erst ab NT4 ... wird nicht abgefangen ... !

Ich poste den Quelltext mal noch nicht, weil sonst ist der ganze Spaß für Dich ja dahin

cu

Oliver
Angehängte Dateien
Dateityp: zip mtanwt_156.zip (294,5 KB, 21x aufgerufen)
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
blackdrake

Registriert seit: 22. Aug 2003
Ort: Bammental
618 Beiträge
 
Delphi 10.3 Rio
 
#46

Re: Maus sperren während Tastatureingabe

  Alt 19. Nov 2008, 23:20
Hallo,

danke für das Prog, jetzt schreibe ich in der Zwischenzeit endlich mal wieder nicht mehr wie der erste Mensch. (Mein altes Notebook hatte nämlich ein 1 mm abgesenktes, nicht ganz so super empfindliches Touchpad, mit dem ein solcher omni-presenter ausversehenklick nie vorgekommen ist)

Ich habe bei meiner Variante die grafische Lösung etwas anders geplant, z.B. das verschwinden der Maus bei dir ist bei mir das ersetzen mit crNo. Außerdem sollen bei mir rechtsklicks erlaubt sein, da nur linksklicks von Touchpads ausgelöst werden können.

Mit dem Strg und/oder Shift habe ich aber wie oben beschrieben irgendwie ein Problem. Darf ich erfahren, wie du das gelöst hast? Wie stelle ich fest, ob NUR die Strg-Taste und/oder NUR die Shift Taste gedrückt ist, um die Ausnahme zu realisieren? (Das natürlich im Hook-Ereignis, nicht in einem OnPress-Ereignis, was man so oft bei seiner Google-Recherche findet)
Daniel Marschall
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#47

Re: Maus sperren während Tastatureingabe

  Alt 19. Nov 2008, 23:32
Zuerst brauchst du das:
Delphi-Quellcode:
type
  ULONG_PTR = ^DWORD;

  PKBDLLHOOKSTRUCT = ^TKBDLLHOOKSTRUCT;
  TKBDLLHOOKSTRUCT = packed record
    vkCode : DWORD;
    scanCode : DWORD;
    flags : DWORD;
    time : DWORD;
    dwExtraInfo : ULONG_PTR;
  end;
Umsetzung von KBDLLHOOKSTRUCT

Das Gleiche gibt es für die Maus auch MSLLHOOKSTRUCT
(aber nur für WM_MOUSE_LL ab NT4 s.u.)

und dann so
Delphi-Quellcode:
      if
        ( wParam = WM_KEYDOWN )
      then
        begin
          KHSp := PKBDLLHOOKSTRUCT( lParam );
          KHSd := KHSp^;
          if
            not
              (
                ( KHSd.vkCode = 160 ) and ( KHSd.scanCode = 42 ) or // Shift Left
                ( KHSd.vkCode = 162 ) and ( KHSd.scanCode = 29 ) or // Ctrl Left
                ( KHSd.vkCode = 161 ) and ( KHSd.scanCode = 54 ) or // Shift Right
                ( KHSd.vkCode = 163 ) and ( KHSd.scanCode = 29 ) // Ctrl Right
              )
          then
das geht dann, wenn Du den Hook so implementierst:
Delphi-Quellcode:
        KeyboardHookHandle :=
          SetWindowsHookEx(
            WH_KEYBOARD_LL,
            @KeyboardHookProc,
            HInstance,
            0 );
und das geht erst ab NT4.

Vor NT4 musst du WH_KEYBOARD nehmen und dann hast du anhand wParam z.B. VK_xxx abprüfen.

cu

Oliver
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
blackdrake

Registriert seit: 22. Aug 2003
Ort: Bammental
618 Beiträge
 
Delphi 10.3 Rio
 
#48

Re: Maus sperren während Tastatureingabe

  Alt 19. Nov 2008, 23:40
Hallo.

Ich habe ja bereits einen vollständigen Mouse- und Key-Hook, der in den vorherigen Seiten und meinem Snapshot auch auftaucht. Mich interessiert genau der Abschnitt, den du nur kurz erwähnst:

"dann hast du anhand wParam z.B. VK_xxx abprüfen."

WIE prüfe ich anhand des wParam, ob es ein VK_CONTROL oder VK_SHIFT ist? (Anmerkung: Möglichst, die Taste als solches, also nicht Strg+A = Strg)

Das mit dem vkCode und dem ScanCode hilft mir momentan leider nicht weiter, da ich beim Hook nur lParam und wParam - mit was die auch gefüllt sein mögen - kenne. Aus diesen 2 Infos muss ich entscheiden, ob es nun ein einzelnen Strg oder ein einzelnes Shift ist, oder nicht.

Gruß
blackdrake
Daniel Marschall
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#49

Re: Maus sperren während Tastatureingabe

  Alt 19. Nov 2008, 23:49
Du erstellst doch irgendwo dein KeyboardHookHandle ... dort setzt du statt WM_KEYBOARD einfach WM_KEYBOARD_DLL rein.

Dann holst Du Dir die TKBDLLHOOKSTRUCT aus dem Parameter lParam und kannst das wunderbar auswerten.

Ich habe hier Vista laufen und da werden bei der Verwendung von WM_KEYBOARD nur die Ereignisse, die direkt an die App geschickt werden gehookt.
Also ist das auf jeden Fall besser, vor allem weil du dann auch unterscheiden kannst zwischen der rechten und linken Shift/Strg-Taste.

Und das habe ich Dir in dem Thread davor alles geschickt.

Die HookProc ist eigentlich fast genau wie bei Dir nur das die Parameter eine andere Information enthalten.

cu

Oliver
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
blackdrake

Registriert seit: 22. Aug 2003
Ort: Bammental
618 Beiträge
 
Delphi 10.3 Rio
 
#50

Re: Maus sperren während Tastatureingabe

  Alt 20. Nov 2008, 21:26
Hallo.

Ich habe jetzt wieder die Kontrolle der Sperrzeit über die Host-App laufen lassen.

Das Strg und Shift Problem ist nun auch gelöst.

Jetzt habe ich nur noch das große Problem mit dem Cursor.

Ist die Maustaste gesperrt, soll der Cursor crNo zeigen (logischerweiße für alle Anwendungen). Und das scheint gar nicht so einfach zu funtkionieren.

Folgender Code, den ich so ähnlich im Internet fand:

Delphi-Quellcode:
var
  cursor_backup: HCursor;
begin
  cursor_backup := GetCursor;
  SetSystemCursor(Screen.Cursors[crNo], OCR_NORMAL);

  // ...

  SetSystemCursor(cursor_backup);
end;
Das große Problem: SetSystemCursor verändert direkt den Zeiger und überschreibt diesen. Wenn die Anwendung abstürzt, dann hat der Benutzer ein schönes crNo als Standardmauszeiger - das hat irgendwie was . Das cursor_backup wird übrigens auch nicht zurückgespielt. Der Cursor bleibt auf crNo.

SetCursor() verändert hingegen nur innerhalb der Anwendung. Ist also auch nichts. Tippe ich im Notepad, bleibt der Cursor beim Windows-Standard?

Außerdem habe ich den Effekt, dass ich innerhalb der WndProc den Mauszeiger nicht so einfach verändern kann, da er durch die anderen Ereignisse in kürzester Zeit wieder rückgängig gemacht wird.

Gibt es einen Befehl, der bewirkt, dass ich Systemweit auf OCR_NO umstelle? Ich denke, OCR_NORMAL zu überschreiben ist ein falscher und unsauberer Weg.

Thema http://www.delphipraxis.net/internal...ct.php?t=23787 zeigt bisher keine Lösung - das kann doch irgendwie nicht sein, dass Microsoft nicht daran gedacht hat, den Mauszeiger global zu verändern, ohne das man alle Standardtypen überschreibt...

// Edit: Da das ursprüngliche Problem mit dem Programm gelöst ist und das crNo-Mauszeiger-Problem unabhängig behandelt werden kann, habe ich das Thema als gelöst markiert und frage in den jeweiligen Themen weiter. Ich werde den Automatic-Touchpad-Locker bald OpenSource veröffentlichen, sobald ich eine schöne GUI geschaffen habe. Ich danke euch sehr herzlich für die Unterstützung.



Gruß
blackdrake
Daniel Marschall
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 5 von 6   « Erste     345 6      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 02:03 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz