2008-11-21 55 views
5

Cuộc gọi win32 nào có thể được sử dụng để phát hiện các sự kiện báo chí chính trên toàn cầu (không chỉ cho 1 cửa sổ, tôi muốn nhận được tin nhắn MỌI thời gian một phím được bấm), từ dịch vụ windows?Nhập bằng bàn phím mức thấp trên Windows

Trả lời

4

Bạn muốn sử dụng Win32 Hooks. Đặc biệt là móc nối bàn phím.

You can read more about it here

Các loại móc bạn muốn là WH_KEYBOARD và bạn có thể đặt nó thông qua Win32 API SetWindowsHookEx.

Về cơ bản, các cửa sổ sẽ gọi một hàm trong một dll mà bạn tạo ra mỗi lần nhấn một phím trong bất kỳ hệ thống ứng dụng nào.

Các móc sẽ gọi hàm của bạn mà sẽ có giao diện này:

LRESULT CALLBACK KeyboardProc(  
    int code, 
    WPARAM wParam, 
    LPARAM lParam 
); 

More information about this callback here.

Với móc cửa sổ, bạn không chỉ theo dõi sự kiện trên toàn hệ thống trên tất cả các quy trình, nhưng bạn cũng có thể lọc chúng và ngăn chúng hoàn toàn.

2

Hãy nhìn vào các móc bạn có thể thiết lập với SetWindowHookEx:

http://msdn.microsoft.com/en-us/library/ms644990(VS.85).aspx

Tuy nhiên, trừ khi bạn đang chạy một "tương tác" dịch vụ, bạn sẽ không có quyền truy cập vào các máy tính để bàn (và bạn shouldn sẽ không chạy một dịch vụ tương tác vì nó sẽ không hoạt động ngay trong các phiên bản Windows mới hơn). Bạn sẽ phải xem xét các API quản lý phiên làm việc và máy tính để bàn để truy cập vào máy tính để bàn/bàn điều khiển.

0

Kiểm tra các API tin nhập thô trong MSDN:

http://msdn.microsoft.com/en-us/library/ms645536(VS.85).aspx

Nó cho phép bạn để có được đầu vào từ bàn phím (trong số những thứ khác) mà không rối tung xung quanh với móc toàn cầu. Móc toàn cầu chỉ nên được sử dụng như một phương sách cuối cùng vì chúng có thể gây ra những hậu quả không mong muốn.

Hạn chế duy nhất để sử dụng Nhập liệu là nó có thể không nhận được tổ hợp phím được tạo bởi phần mềm.

0

Nếu bạn đang thực hiện điều này trong ứng dụng .net tôi muốn giới thiệu GlobalKeyboardHook, Nếu không, tôi sẽ xem nguồn của nó và lấy những gì bạn cần vì nó đang triển khai các chức năng DLLImport được đề cập ở trên.

1

Chỉ cần sử dụng hàm gốc GetKeyState hoặc GetAsyncKeyState hoặc GetKeyboardState từ user32 DLL.

Bạn có thể đọc về mỗi chức năng tôi đã đề cập ở trên trong trang web MSDN:

h ttp: //msdn.microsoft.com/en-us/library/windows/desktop/ms646301 (v = vs.85) .aspx

cho GetKeyState

h ttp: //msdn.microsoft.com/en-us/library/windows/desktop/ms646293 (v = vs.85).aspx

cho GetAsyncKeyState

h ttp: //msdn.microsoft.com/en-us/library/windows/desktop/ms646299 (v = vs.85) .aspx

cho số GetKeyboardState.

Nếu bạn lập trình bằng C# thì:

Mã của bạn phải bao gồm các dòng sau ra khỏi bất kỳ lớp, khai struct hoặc enum:

using System.Runtime.InteropServices; 

Sau đó, trong lớp mà có phương pháp ở đâu bạn muốn phát hiện các phím, xác định một trong ba chức năng ở trên cho sự lựa chọn của bạn, hoặc những gì làm việc và những gì không.

[DllImport("user32.dll")] 
static uint GetKeyState(byte virtualKeyCode); 

//or 

[DllImport("user32.dll")] 
static uint GetAsyncKeyState(byte virtualKeyCode); 

//or 

[DllImport("user32.dll")] 
static uint GetKeyboardState(byte[] virtualKeyCodes); 
//NOTE: The length of the byte array parameter must be always 256 bytes! 

Nếu bạn không thích uint như kiểu trả về, bạn cũng có thể thay đổi nó để int.

Nếu hàm gốc luôn trả về 1 là true hoặc 0 là false, thì bạn có thể thay đổi kiểu trả về thành bool thay vào đó, nhưng nếu bạn làm như vậy, tôi nghĩ bạn nên thêm một dòng mã khác định nghĩa hàm, đó là:

[MarshalAs(UnmanagedType.Bool)] 

HOẶC bạn có thể thêm các dòng sau vào giữa định nghĩa hàm mẹ đẻ (dưới mức mà từ DllImport là, và trên đường, nơi 'extern' word is):

[return: MarshalAs(UnmanagedType.Bool)] 

Trang web Pinvoke cung cấp định nghĩa tốt hơn cho các chức năng này, vì vậy bạn không phải sử dụng các số nguyên để đề cập đến một khóa cụ thể của bàn phím, nhưng dễ hiểu hơn.

Các liên kết sau đây dẫn đến định nghĩa của GetKeyState trong C#:

h ttp: //www.pinvoke.net/default.aspx/user32.getkeystate

Các liên kết sau đây dẫn đến định nghĩa của GetAsyncKeyState trong C#

h ttp: //www.pinvoke.net/default.aspx/user32.getasynckeystate

các followi ng liên kết dẫn đến định nghĩa của GetKeyboardState trong C#

h ttp: //www.pinvoke.net/default.aspx/user32.getkeyboardstate

Để phát hiện đó giữ phím (bất cứ lúc nào , ở bất kỳ đâu), sau đó gọi hàm GetKeyState hoặc GetAsyncKeyState, trong tham số đơn, đề cập đến khóa bạn muốn phát hiện và sau đó thêm: & 0x8000 hoặc & 0x80 sau cuộc gọi. Nếu phím được đề cập được giữ lại, thì giá trị trả lại của biểu thức không phải là 0, nhưng nếu không thì sẽ bằng 0. Theo số nguyên được trả về của biểu thức, bạn có thể xác định khóa nào được giữ hoặc không. Lưu ý rằng nếu bạn đặt mã bên trong nếu câu lệnh với biểu thức đó! = 0 khi nhập điều kiện, bên trong một vòng lặp, mã trong câu lệnh if sẽ được thực thi nhiều lần, thực tế là nhiều lần, khi bạn giữ khóa đó. Nếu bạn muốn một số mã được thực thi lần Khi bạn nhấn một phím và sau đó phát hành nó, sau đó đoạn mã sau là một thủ thuật mà đạt được mục tiêu này:

while (boolean exression that will return false when you want to quit this loop) 
{ 
    if (boolean expression that will return true when particular key is **held down**) //This boolean expression calls either GetKeyState or GetAsyncKeyState with the & 0x8000 or & 0x80 after the call, and then != 0 to check for **held down** key 
     while (true) //It's purpose is to wait for the same key that was held down to be released. After code execution, it will encounter the break keyword that will finish him, even though that his enter condition is true. 
      if (boolean expression that will return true when the **same** particular key is **NOT** held down! (NOT held down, means that at that time, that key was released). You can copy the same condition from the first if statement, and just change **!=**, which is next to 0, to **==**, or instead add brackets to the condition '(' and ')', and in left of '(' add '!'). 
      { 
       //Put here the code that you want to execute once, when paticular key was pressed and then released. 
       break; //the while (true), which is the only way to get out of it 
      } 
} 
Các vấn đề liên quan