10

Trong một vài từ: chặn Win lên sau khi Win + Tab làm cho Windows nghĩ Win vẫn là xuống, do đó sau đó nhấn S với Win Ví dụ, khóa sẽ mở ra tìm kiếm quyến rũ thay vì chỉ nhập "s" ... cho đến khi người dùng nhấn Giành chiến thắng một lần nữa. Không chặn nó có nghĩa là menu Bắt đầu của Windows sẽ hiển thị. Tôi đang ở trong một câu hỏi hóc búa!Làm thế nào để treo Win + Tab sử dụng LowLevelKeyboardHook


Tôi không có rắc rối hooking vào các phím tắt sử dụng Alt +Tab sử dụng LowLevelKeyboardHook, hoặc Win + Một số Ubounded chính sử dụng RegisterHotKey. Sự cố chỉ xảy ra với phím Thắng bằng cách sử dụng LowLevelKeyboardHook.

Trong ví dụ dưới đây, tôi đang tham gia trong Win lên sự kiện khi Win + Tab kết hợp được phát hiện. Điều này dẫn đến việc thực hiện tất cả các lần nhấn phím sau hoạt động như thể phím Giành chiến thắng vẫn tiếp tục hoạt động.

 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); 
     } 
    } 
} 

Bạn có thể tìm mã hoàn chỉnh ở đây (lưu ý rằng nó nên thay thế của bạn Program.cs trong một dự án WinForms trống để chạy): https://gist.github.com/christianrondeau/bdd03a3dc32a7a718d62 - nhấn Win + Tab và danh hiệu Form nên cập nhật mỗi lần phím tắt được nhấn.

Lưu ý rằng ý định của hooking vào sự kết hợp cụ thể này là cung cấp một Alt +Tab thay thế mà không cần thay thế Alt +Tab riêng của mình. Câu trả lời cung cấp khả năng khởi chạy mã tùy chỉnh bằng cách sử dụng Thắng + Tab cũng sẽ được chấp nhận.

Dưới đây là ý tưởng của tôi, mà tôi không thể tìm thấy tài liệu. Tất cả sẽ có khả năng trả lời câu hỏi của tôi thành công.

  • Nói với Windows để "hủy bỏ" các Win lên mà không thực sự kích hoạt nó
  • Ngăn chặn Windows từ tung ra menu Start một lần
  • Hook trực tiếp trong Windows Win + sự kiện chứ không phải bằng tay hooking vào tổ hợp phím (Điều này sẽ là bởi đến nay lựa chọn đầu tiên của tôi nếu điều đó tồn tại)

Trả lời

2

này dường như thực hiện chính xác những gì bạn muốn (bỏ qua RWIN nếu bạn muốn) .

Vui lòng cân nhắc và hủy đăng ký móc KB này khi ứng dụng của bạn bị mất tiêu điểm!

[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); 
    } 

Tôi đã thử một vài điều trước khi khám phá kỹ thuật này. bài này là hữu ích nhất https://stackoverflow.com/a/317550/55721

+0

Vì vậy, trong ngắn hạn: móc phím Win xuống, thay vì phím Win lên, và không ngăn chặn các tổ hợp phím khác :) Tôi loại bỏ' if (wParam == (IntPtr) WM_KEYDOWN) {return (IntPtr) 1; } 'và' trả về khác (IntPtr) 1; 'trong khối' if (keyInfo.VkCode == VK_LWIN) ', và nó cũng làm việc, mặc dù tôi nghĩ mã của bạn đơn giản và rõ ràng hơn. Tôi đã bị mắc kẹt trong 9 tháng về điều này, vì vậy cảm ơn chân thành của tôi đã dành thời gian để xem xét điều này! (Và giải pháp rất đơn giản, rõ ràng ...) –

+0

Hmm, tôi không thử những gì bạn đề nghị. Tôi đã xem xét nó, nhưng giả định rằng việc đặt cược winkey xuống sẽ can thiệp vào các chức năng winkey khác, như winkey + R. Cách tiếp cận của bạn có cho phép điều đó không? – dss539

+0

Có. Nói cách khác, tôi "ghi" Win Down thay vì kiểm tra trạng thái Win Down khi Tab Down xảy ra. Điều này chỉ đơn giản là làm cho mã khó đọc hơn cho cùng một hành vi, vì vậy ... của bạn là tốt hơn! –

4

Hệ thống cần biết bạn rời đi ase phím Windows. tôi kiểm tra sự khác biệt giữa các móc của riêng tôi những người không có vấn đề này và diffence duy nhất giữa bạn và của tôi là dòng này:

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

Giải pháp này sẽ không làm việc, bởi vì khi Windows nhận được Win lên mà không có một phím tắt, nó sẽ khởi động menu Start của Windows. Lý do duy nhất bạn không thấy điều đó trong ví dụ này là vì tôi đã sử dụng 'MessageBox' và có vẻ như 'MessageBox' sẽ hủy menu Windows. Tôi sẽ thay đổi ví dụ để viết một cái gì đó trong 'Form1' thay vì ... –

Các vấn đề liên quan