2010-01-16 22 views
6

Trong móc nối bàn phím của tôi, mỗi phím bấm sẽ nhận được một lá cờ cho biết nó có được tiêm hay không. http://msdn.microsoft.com/en-us/library/ms644967(VS.85).aspxLàm cách nào để sử dụng cờ 8 bit cấp thấp làm điều kiện?

Tôi đã cất một KBDLLHOOKSTRUCT từ lParam. Tôi có thể truy cập kbd.flags.XXX. Tôi chỉ không biết cách chuyển đổi cờ 8 bit này thành một loại điều kiện loại if (injected) {... mà tôi biết cách sử dụng.

Nếu một trong các bạn loại khoa học máy tính thông minh sẽ giúp tôi hiểu tôi thực sự đánh giá cao nó.

private static IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam) 
    { 
     KBDLLHOOKSTRUCT kbd = new KBDLLHOOKSTRUCT(); 
     Marshal.PtrToStructure(lParam, kbd); 

     //if (injected) {... 

Chúc mừng!

Trả lời

7

Bạn cần phải bitwise và nó có mặt nạ. Ví dụ, bit được tiêm là bit 4. Đó là số nhị phân 00010000, hex 0x10. Vì vậy, bạn Bitwise-và nó với 0x10, và xem nếu trái bất cứ điều gì của:

bool isInjected = ((kbd.flags & 0x10) != 0); 

(Tất nhiên, như mỗi câu trả lời của Andrew, nó sẽ là một ý tưởng tốt để xác định một hằng số LLKHF_INJECTED cho điều này chứ không phải là bao gồm giá trị hex ! trực tiếp trong mã của bạn)

+0

này (và những người khác ở đây mà tôi đã cố gắng) đang ném một 'Một ngoại lệ cơ hội đầu tiên của loại 'System.ArgumentException' xảy ra trong foofoo.exe' Có vẻ là rối tung lên mã móc nối bàn phím trước đó tôi đã có là tốt. Đưa cái gì? Nó cũng không biên dịch trừ khi tôi thêm dấu ngoặc đơn: 'bool isInjected = ((kbd.flags & LLKHF_INJECTED)! = 0);' ... là việc thay đổi mã? – cksubs

+0

Các parens bổ sung không thay đổi mã - chúng chỉ sửa lỗi ưu tiên ngớ ngẩn của tôi. Đã cập nhật câu trả lời. – itowlson

+0

Không biết ArgumentException đến từ đâu, vì bạn chỉ đọc từ trường cờ. Là một ngoại lệ thực sự được ném hoặc là nó chỉ là một thông báo gỡ lỗi về một ngoại lệ cơ hội đầu tiên (tức là bị bắt và xử lý nội bộ trong CLR)? Nếu trước đây, dấu vết ngăn xếp của ngoại lệ là gì? Bạn vẫn nhận được nó nếu bạn chỉ Console.WriteLine (kbd.flags)?Khi bạn đã xem xét những điều này, bạn có thể muốn tạo một câu hỏi riêng biệt vì có thể không liên quan đến câu hỏi bit-twiddling thuần túy "làm cách nào để sử dụng cờ bitwise trong C#?", Nhiều khả năng là vấn đề marshalling. – itowlson

3

Sử dụng các phép toán AND điều hành để kiểm tra xem các bit có liên quan được thiết lập trong cờ biến:

if (kbd.flags & LLKHF_INJECTED) 
{ 
    ... 
} 
+0

Sẽ không biên dịch. Trong C#, biểu thức 'if' phải là một bool; kbd.flags & LLKHF_INJECTED là một int. (Nó sẽ hoạt động trong C/C++.) – itowlson

2

bạn cần phải xem xét rằng việc bitflag được thiết lập. Dễ dàng thực hiện với các thao tác bitwise. Tài liệu nói rằng bit bốn được sử dụng cho cờ tiêm, bit 4 (hoặc 5 nếu bạn đếm bit đầu tiên là 1) bằng 16, vì vậy bạn có thể thực hiện bitwise AND so với cờ.

if ((kbd.flags & 16) == 16) 
{ 
    FireTorpedoes(); 
} 

Bạn có thể tìm hiểu thêm về hoạt động Bitwise đây:

+1

Bit 4 bằng 16. (Bit 4 là bit thứ năm, đếm từ 0 đến 7.) – LukeH

+0

Cuộc gọi tốt, không thấy rằng chúng không được lập chỉ mục trong tài liệu. – Skurmedel

11

NET hỗ trợ này với [Flags] thuộc tính:

[Flags] 
enum KbdHookFlags { 
    Extended = 0x01, 
    Injected = 0x10, 
    AltPressed = 0x20, 
    Released = 0x80 
} 

sử dụng mẫu:

KBDLLHOOKSTRUCT info = (KBDLLHOOKSTRUCT)Marshal.PtrToStructure(lParam, typeof(KBDLLHOOKSTRUCT)); 
    if ((info.flags & KbdHookFlags.Released) == KbdHookFlags.Released) { 
    // Key was released 
    // etc.. 
    } 
2

Lý do mọi người đang nói đến sử dụng một Bitwise & và sau đó so sánh với số không hay cờ:

0111 1000  // kbd.flags 
& 0001 0000  // Injected 
      = 
    0001 0000  // (!= 0 or ==Injected) 
Các vấn đề liên quan