2009-02-08 41 views
5

Tôi đang cố gắng viết một ứng dụng đáp ứng bất cứ khi nào phím Shift được nhấn, bất kể ứng dụng nào hiện có tiêu điểm.Trả lời bàn phím khi không lấy nét? (C#, Vista)

Tôi đã thử điều này với SetWindowsHookEx() và với GetKeyboardState(), nhưng cả hai chỉ hoạt động khi cửa sổ của ứng dụng có tiêu điểm. Tôi cần nó để làm việc trên toàn cầu.

Làm cách nào để thực hiện việc này?

Trả lời

5

Không có câu trả lời nào được cung cấp đã giúp tôi giải quyết vấn đề của mình, nhưng tôi đã tự tìm ra câu trả lời. Đây rồi.

Sử dụng SetWindowsHookEx() với WH_KEYBOARD_LL là phương pháp chính xác. Tuy nhiên, các thông số khác để SetWindowsHookEx() là unintuitive:

  • Tham số cuối cùng, dwThreadId, cần phải được 0.
  • Tham số thứ hai cuối cùng, hMod, cần để trỏ đến một số DLL. Tôi đã sử dụng User32, là một tệp DLL luôn được tải và được sử dụng bởi tất cả các quy trình bằng GUI. Tôi có ý tưởng này từ a CodeProject post about this.

Như vậy, mã trông một chút như thế này:

instance = LoadLibrary("User32"); 
hhook = SetWindowsHookEx(WH_KEYBOARD_LL, hookFunction, instance, 0); 

Các tài liệu không rõ ràng về tham số thứ hai-ngoái. Nó nói:

Tham số hMod phải được đặt thành NULL [...] nếu thủ tục móc nằm trong mã được liên kết với quy trình hiện tại.

Không nói rằng điều này chỉ áp dụng cho một số loại móc, nhưng không áp dụng cho một số loại móc, nhưng không áp dụng cho WH_KEYBOARD_LLWH_MOUSE_LL.

+0

Vâng, đó là ý nghĩa của chúng - đối với chuột hoặc móc bàn phím cấp thấp (hoặc bất kỳ móc địa phương nào khác) hMod phải là IntPtr.Zero. –

+0

Hmmm, bạn nói các bài viết khác không hữu ích sau đó tiến hành đăng câu trả lời tương tự mà nobugz đã cung cấp và đánh dấu bạn là câu trả lời chính xác. –

+0

Nobugz không nói phải làm gì về hMod, và trái với bình luận đầu tiên của bạn, câu trả lời này cho thấy hMod được đặt thành cái gì đó ** khác ** hơn IntPtr.Zero. –

5

Bạn sẽ phải sử dụng SetWindowsHookEx(). Chỉ có hai loại móc mà bạn có thể triển khai bằng ngôn ngữ được quản lý, WH_KEYBOARD_LL và WH_MOUSE_LL. Tất cả các hook khác yêu cầu một DLL có thể được tiêm vào một tiến trình khác. DLL được quản lý không thể được tiêm, CLR không thể được khởi tạo.

Điều này blog post có ví dụ chức năng.

+0

Hầu hết các móc khác cũng có thể được triển khai bằng ngôn ngữ được quản lý nhưng chỉ khi chúng bị hạn chế đối với các luồng của quy trình hiện tại. Các móc chuột và bàn phím mức thấp là những móc chỉ 'toàn cầu' duy nhất được cho phép. –

+0

Điều này chỉ làm giảm bề mặt của vấn đề và không thực sự đi sâu vào bất kỳ mức độ nào. –

+1

Đây là câu trả lời rất cụ thể cho câu hỏi cụ thể. Đó là một chút ngắn và glosses trên một số thông tin cho sự đơn giản nhưng nó chứa tất cả các thông tin mà một nhà phát triển phần mềm có thẩm quyền sẽ cần. –

2

Nếu bạn sử dụng kỹ thuật trong bài đăng được tham chiếu bởi nobugz, bạn sẽ cần đảm bảo rằng đại biểu không bị thu thập rác, ví dụ: bằng cách sử dụng GC.KeepAlive (_proc) khi thiết lập móc, nếu không sau một khoảng thời gian không xác định móc sẽ ngừng hoạt động khi delagate được GC.

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