Windows全局键盘钩 – 德尔福

前端之家收集整理的这篇文章主要介绍了Windows全局键盘钩 – 德尔福前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我使用互联网上的源代码创建了一个GLOBAL键盘钩子DLL.最好的部分是它非常出色,除了它涉及到浏览器.

它会接收浏览器中的每个键,除了看起来,当浏览器获得焦点时,它会丢失按下的第一个键.在IE和Firefox中进行了测试,两者似乎都是一样的.

例如,如果我打开IE并开始输入www.,我只回来了.如果浏览器窗口保持清晰,则不会丢失其他密钥.一旦浏览器失去焦点并重新获得焦点,第一个键就会再次丢失.

可能是因为只使用WH_KEYDOWN而不是WH_KEYPRESS / WH_KEYUP?有人可以对此有所了解吗?

谢谢

PS:钩子函数本身如下:DLL发送一个备忘录框和应用程序句柄,DLL将发送消息以及用户消息.

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,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); 
        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,0);
      end;
    end; 
  end; 
end;
您没有及早分配hMemo和hApp值.您正在等待“先前状态”标志为1的通知,该通知表示某个键已被按下至少1次重复计数,或者正在被释放,以先发生者为准.因此,当您的挂钩检测到其第一个按键通知时,hMemo和hApp尚不可用.这就是你错过角色的原因.试试这个:
function KeyHookFunc(Code,KeyStroke: Integer): LRESULT; stdcall;
var
  KeyState1: TKeyBoardState;
  AryChar: array[0..1] of Char;
  Count: Integer;
begin
  Result := CallNextHookEx(hKeyHook,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,'NetParentMAP');
      if hMemFile = 0 then Exit;
    end;
    if PHookRec1 = nil then
    begin
      PHookRec1 := MapViewOfFile(hMemFile,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,0);
    if Count = 1 then
    begin
      if hMemo <> 0 then SendMessage(hMemo,0);
      if hApp <> 0 then PostMessage(hApp,0);
    end;
  end;
end;

猜你在找的Windows相关文章