2010-07-01 28 views
6

Tôi đã tạo một DLL móc khóa GLOBAL, sử dụng mã nguồn được tìm thấy trên internet. Đối với phần tốt nhất nó hoạt động rực rỡ, ngoại trừ khi nói đến trình duyệt.Bàn phím toàn cầu của Windows Hook - Delphi

Nó chọn mọi phím trong trình duyệt ngoại trừ, có vẻ như, khi trình duyệt được lấy nét, nó sẽ mất khóa đầu tiên được nhấn. Thử nghiệm điều này trong IE và Firefox và nó có vẻ giống nhau cho cả hai.

Ví dụ: nếu tôi mở IE và bắt đầu nhập www. , Tôi chỉ quay lại thôi. Nếu cửa sổ trình duyệt vẫn ở trong tiêu điểm thì không còn khóa nào nữa. Ngay sau khi trình duyệt mất tập trung và lấy lại tiêu điểm, khóa đầu tiên lại bị thiếu.

Có thể vì chỉ sử dụng WH_KEYDOWN thay vì WH_KEYPRESS/WH_KEYUP? Có ai có thể làm sáng tỏ điều này không?

Cảm ơn bạn

PS: Chức năng móc chính nó là dưới đây: Các DLL được gửi một hộp ghi nhớ và ứng dụng xử lý để Mà các DLL sẽ gửi tin nhắn cũng như một usermessage.

function KeyHookFunc(Code, VirtualKey, KeyStroke: Integer): LRESULT; stdcall; 
var 
    KeyState1: TKeyBoardState; 
    AryChar: array[0..1] of Char; 
    Count: Integer; 
begin 
    Result := 0; 
    if Code = HC_NOREMOVE then Exit; 

    Result := CallNextHookEx(hKeyHook, Code, VirtualKey, KeyStroke); 
    {I moved the CallNextHookEx up here but if you want to block 
    or change any keys then move it back down} 
    if Code < 0 then 
    Exit; 
    if Code = HC_ACTION then 
    begin 
    if ((KeyStroke and (1 shl 30)) <> 0) then 
     if not IsWindow(hMemo) then 
     begin 
     {I moved the OpenFileMapping up here so it would not be opened 
     unless the app the DLL is attatched to gets some Key messages} 
     hMemFile := OpenFileMapping(FILE_MAP_WRITE, False, 'NetParentMAP');//Global7v9k 
     PHookRec1 := MapViewOfFile(hMemFile, FILE_MAP_WRITE, 0, 0, 0); 
     if PHookRec1 <> nil then 
     begin 
      hMemo := PHookRec1.MemoHnd; 
      hApp := PHookRec1.AppHnd; 
     end; 
     end; 
    if ((KeyStroke AND (1 shl 31)) = 0) then //if ((KeyStroke and (1 shl 30)) <> 0) then 
    begin 
     GetKeyboardState(KeyState1); 
     Count := ToAscii(VirtualKey, KeyStroke, KeyState1, AryChar, 0); 
     if Count = 1 then 
     begin 
     SendMessage(hMemo, WM_CHAR, Ord(AryChar[0]), 0); 
     {I included 2 ways to get the Charaters, a Memo Hnadle and 
     a WM_USER+1678 message to the program} 
     PostMessage(hApp, WM_USER + 1678, Ord(AryChar[0]), 0); 
     end; 
    end; 
    end; 
end; 
+2

Mẫu mã của bạn giúp rất nhiều người cố gắng trả lời mã của bạn. –

+0

Vâng tôi biết, vấn đề là tôi sẽ phải đưa lên toàn bộ dự án như tôi không biết nơi mà vấn đề có thể được. Những gì tôi có thể nói là tôi sử dụng lệnh sau để đặt móc: hKeyHook: = SetWindowsHookEx (WH_KEYBOARD, KeyHookFunc, hInstance, 0); Nhưng tôi đã nhìn thấy một dự án C# có vẻ như sử dụng WH_KEYBOARD_LL, điều đó có tạo nên sự khác biệt không? – Paul

+0

Ít nhất bạn có thể hiển thị cho chúng tôi nguồn bạn đã tìm thấy trên internet. Có lẽ mã này không chính xác ... – bepe4711

Trả lời

8

Bạn chưa chỉ định các giá trị hMemohApp của mình đủ sớm. Bạn đang đợi cho đến khi thông báo có cờ "trạng thái trước" là 1, cho biết khóa đã được giữ lại ít nhất 1 lần lặp lại hoặc đang được phát hành, tùy điều kiện nào xảy ra trước. Do đó, hMemohApp chưa khả dụng khi móc của bạn phát hiện thông báo khóa đầu tiên. Đó là lý do tại sao bạn bỏ lỡ các nhân vật. Hãy thử thay vào đó:

function KeyHookFunc(Code, VirtualKey, KeyStroke: Integer): LRESULT; stdcall; 
var 
    KeyState1: TKeyBoardState; 
    AryChar: array[0..1] of Char; 
    Count: Integer; 
begin 
    Result := CallNextHookEx(hKeyHook, Code, VirtualKey, KeyStroke); 
    if Code <> HC_ACTION then Exit; 

    { a key notification had occured, prepare the HWNDs 
    before checking the actual key state } 
    if (hMemo = 0) or (hApp = 0) then 
    begin 
    if hMemFile = 0 then 
    begin 
     hMemFile := OpenFileMapping(FILE_MAP_WRITE, False, 'NetParentMAP'); 
     if hMemFile = 0 then Exit; 
    end; 
    if PHookRec1 = nil then 
    begin 
     PHookRec1 := MapViewOfFile(hMemFile, FILE_MAP_WRITE, 0, 0, 0); 
     if PHookRec1 = nil then Exit; 
    end; 
    hMemo := PHookRec1.MemoHnd; 
    hApp := PHookRec1.AppHnd; 
    if (hMemo = 0) and (hApp = 0) then Exit; 
    end; 

    if ((KeyStroke and (1 shl 31)) = 0) then // a key is down 
    begin 
    GetKeyboardState(KeyState1); 
    Count := ToAscii(VirtualKey, KeyStroke, KeyState1, AryChar, 0); 
    if Count = 1 then 
    begin 
     if hMemo <> 0 then SendMessage(hMemo, WM_CHAR, Ord(AryChar[0]), 0); 
     if hApp <> 0 then PostMessage(hApp, WM_USER + 1678, Ord(AryChar[0]), 0); 
    end; 
    end; 
end; 
+3

dude bạn là một ngôi sao. có lẽ là sai lầm ngu ngốc, nhưng không ít hơn. Cảm ơn bạn – Paul

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