10

In wenigen Worten Haken: Win bis nach Win + Tab macht Windows-denken Win noch nach unten ist blockiert, so dann S mit dem Win drücken Taste oben öffnet zum Beispiel den Suchzauber, anstatt einfach "s" einzugeben ... bis der Benutzer erneut Win drückt. Nicht blockiert es bedeutet das Windows-Startmenü wird angezeigt. Ich bin in einem Rätsel!Wie Win + Tab mit LowLevelKeyboardHook


Ich habe keine Probleme in Verknüpfungen Einhaken RegisterHotKey mit Alt + Tab mit LowLevelKeyboardHook oder Win + Einige Ubounded Key verwenden. Das Problem tritt nur mit dem Win Schlüssel unter Verwendung LowLevelKeyboardHook auf.

Im Beispiel unten, ich nehme über den Win Ereignis, wenn die Win + Tab Kombination erkannt wird. Dies führt dazu, dass sich alle folgenden Tastenanschläge so verhalten, als ob der Schlüssel Win noch nicht gedrückt ist.

 private static IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam) 
     { 
      if (nCode != HC_ACTION) 
       return CallNextHookEx(_hookID, nCode, wParam, lParam); 

      var keyInfo = (Kbdllhookstruct)Marshal.PtrToStructure(lParam, typeof(Kbdllhookstruct)); 

      if (keyInfo.VkCode == VK_LWIN) 
      { 
       if (wParam == (IntPtr)WM_KEYDOWN) { 
        _isWinDown = true; 
       } else { 
        _isWinDown = false; 

        if (_isWinTabDetected) { 
         _isWinTabDetected = false; 
         return (IntPtr)1; 
        } 
       } 
      } 
      else if (keyInfo.VkCode == VK_TAB && _isWinDown) { 
       _isWinTabDetected = true; 

       if (wParam == (IntPtr)WM_KEYDOWN) { 
        return (IntPtr)1; 
       } else { 
        _isWinTabDetected = true; 
        Console.WriteLine("WIN + TAB Pressed"); 
        return (IntPtr)1; 
       } 
      } 

      return CallNextHookEx(_hookID, nCode, wParam, lParam); 
     } 
    } 
} 

Sie können den vollständigen Code finden Sie hier (beachten Sie, dass es Ihre Program.cs in einem leeren WinForms Projekt ersetzen soll laufen): https://gist.github.com/christianrondeau/bdd03a3dc32a7a718d62 - Presse Win + Tab und der Form Titel sollte jedes Mal aktualisieren, um die Verknüpfung wird gedrückt.

beachte, dass die Absicht in diese spezifische Kombination von Einhaken ist Alt ohne Ersetzen eine Alt + Tab Alternative bereitzustellen + Tab selbst. Eine Antwort mit der Möglichkeit, benutzerdefinierten Code unter Verwendung von Win + Tab zu starten, wird ebenfalls akzeptiert.

Hier sind meine Ideen, für die ich keine Dokumentation finden konnten. Alle würden möglicherweise meine Frage erfolgreich beantworten.

  • Sagen Sie Windows "Abbrechen", um den Win, ohne es tatsächlich auslösende
  • Prevent Windows von dem Startmenü starten, sobald
  • Haken direkt in dem Win Windows- + Ereignis statt manuell Einhaken die Tastenanschläge in (Dies würde bei weitem meine erste Wahl sein, wenn diese vorhanden ist)

Antwort

2

Dies scheint genau das zu tun, was Sie wollen (weglassen RWin wenn Sie möchten) .

Bitte seien Sie rücksichtsvoll und entfernen Sie die Registrierung dieses KB-Hooks, wenn Ihre App den Fokus verliert!

[DllImport("user32.dll")] 
    static extern short GetAsyncKeyState(System.Windows.Forms.Keys vKey); 

    private static IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam) 
    { 
     if (nCode == HC_ACTION) 
     { 
      var keyInfo = (Kbdllhookstruct) Marshal.PtrToStructure(lParam, typeof (Kbdllhookstruct)); 
      if ((int) wParam == WM_KEYDOWN 
       && keyInfo.VkCode == VK_TAB 
       && (GetAsyncKeyState(Keys.LWin) < 0 || GetAsyncKeyState(Keys.RWin) < 0)) 
      { 
       _mainForm.Text = "Win + Tab was pressed " + (++_winTabPressCounter) + " times"; 
       return (IntPtr) 1; 
      } 
     } 

     return CallNextHookEx(_hookID, nCode, wParam, lParam); 
    } 

Ich versuchte mehrere Dinge vor der Entdeckung dieser Technik. Dieser Beitrag die nützlichste https://stackoverflow.com/a/317550/55721

+0

Also kurz gesagt: haken Sie die Win-Taste nach unten, anstelle der Win-Taste nach oben, und andere Tastenanschläge nicht verhindern :) Ich entfernte 'if (wParam == (IntPtr) WM_KEYDOWN) {Zurück (IntPtr) 1; } 'und das andere' return (IntPtr) 1; 'im' if (keyInfo.VkCode == VK_LWIN) 'Block, und das hat auch funktioniert, obwohl ich denke, dass dein Code einfacher und sauberer ist. Ich bin seit 9 Monaten dabei, also herzlichen Dank dafür, dass Sie sich die Zeit genommen haben, sich das genauer anzusehen! (Und die Lösung war einfach, offensichtlich ...) –

+0

Hmm, ich habe nicht versucht, was Sie vorschlagen. Ich habe darüber nachgedacht, aber angenommen, dass das Einfangen von Winkey Down andere Winkey-Funktionen wie Winkey + R beeinträchtigen würde. Erlaubt das Ihre Herangehensweise? – dss539

+0

Ja, tut es. Mit anderen Worten, ich "registriere" den "Win Down", anstatt den "Win Down" -Zustand zu prüfen, wenn das "Tab Down" passiert. Dies machte den Code für das gleiche Verhalten schwerer lesbar, also ... dein ist besser! –

4

-System wissen müssen Sie rele ase die Windows-Taste. prüfe ich den Unterschied zwischen meinem eigenen Haken, der dieses Problem nicht hat und die einzige diffence zwischen Ihrem und ich ist diese Zeile:

if (_isWinTabDetected) { 
    _isWinTabDetected = false; 
    return (IntPtr)1; //THIS LINE 
} 
+0

Diese Lösung wird nicht funktionieren, war, weil, wenn Windows den Win, ohne eine Verknüpfung empfängt, startet es das Windows-Startmenü. Der einzige Grund, warum Sie das im Beispiel nicht sehen, ist, weil ich eine 'MessageBox' verwendet habe, und es scheint, dass' MessageBox' das Windows-Menü abbricht. Ich werde das Beispiel ändern, um etwas in die "Form1" stattdessen schreiben ... –