在使用了HOOK编个老板键功能的小程序,先做了个简单的。以下是主要代码
====================
var   hHook:integer;function KeyboardHookHandler(iCode: Integer;wParam: WPARAM; lParam: LPARAM): LRESULT;stdcall;
 const _KeyPressMask=$80000000;
begin
 result:=0;
 if iCode<0 then
   Result:=CallNextHookEx(hHook,iCode,wParam,lParam);
//侦测Ctrl+Alt+F12组合键
 if ((lParam and _KeyPressMask)=0)
    and (GetKeyState(vk_Control)<0)
    and (getKeyState(vk_menu)<0) and (wParam=vk_F12) then
    begin
      showmessage('getthis message');
    end;
 end;procedure TForm1.Button1Click(Sender: TObject);
begin
  hHook:=SetWindowsHookEx(WH_KEYBOARD, KeyboardHookHandler,Hinstance,0);
  if hHook<>0 then showmessage('Mornitor HookKeyboard')
   else begin
         button2.OnClick(self);
         showMessage('Stop HookKeyboard');
        end;
end;procedure TForm1.Button2Click(Sender: TObject);
begin
 UnHookWindowsHookEx(hHook);
 hHook:=0;
end;
====================
现在有发现两个问题:
1、在运行过此程序后,点击BUTTON1开始HOOK,然后按动‘Ctrl+Alt+F12组合键’,软件可以截取此信息出现对话框。这时候再运行一个外部带有热键的外部软件,比如金山词霸。首先让金山最小化然后点击热键,金山从任务栏跳出。这时候按动‘Ctrl+Alt+F12组合键’则不能截取此信息。如果按动BUTTON2停止HOOK,按BUTTON1重新启动HOOK,则一切正常,可以截取此信息。
2、所有截取信息的操作,只能再窗口显示的情况下完成,也就是程序为当前活动窗口,一旦窗口最小化入任务栏,或不是活动窗口,那么就没有办法截取此信息了。显然没有达到老板键的功能。请大家帮忙!

解决方案 »

  1.   

    下面是我用低级键盘钩子WH_KEYBOARD_LL做得测试代码,参考下:unit HKProc;interfaceuses
    Windows, Messages,Dialogs,iniFiles,SysUtils;var
    hNextHookProc: HHook;
    procSaveExit: Pointer;function KeyboardHookHandler(iCode: Integer; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall; export;
    function EnableHotKeyHook: BOOL; export;
    function DisableHotKeyHook: BOOL; export;implementationfunction KeyboardHookHandler(iCode: Integer;wParam: WPARAM;lParam: LPARAM): LRESULT; stdcall; export;
    var
      p: PKBDLLHOOKSTRUCT;
      IsLWINDown,IsRWINDown: boolean;
    begin
      result:= 0;
      If iCode<0 Then
      begin
        Result := CallNextHookEx(hNextHookProc, iCode, wParam, lParam);
        Exit;
      end
      else
      begin
        If iCode = HC_ACTION then
        begin
          //IsLWINDown:= GetKeyState(VK_LWIN)<0;
          //IsRWINDown:= GetKeyState(VK_RWIN)<0;
          p:= PKBDLLHOOKSTRUCT(lParam);
          case wParam of
          WM_KEYDOWN:
              if (GetKeyState(vk_Control)<0)
              and (getKeyState(vk_menu)<0)
              and (p^.vkCode = vk_F12) then showmessage('asdfs');
          WM_SYSKEYDOWN:
            result := 0;
          WM_KEYUP:
          result:= 0;
          WM_SYSKEYUP:
            result := 0;
          else exit;
          end;
        end;
      end;
    end;
    function EnableHotKeyHook: BOOL; export;
    begin
      Result := False;
      if hNextHookProc <> 0 then Exit;
      hNextHookProc := SetWindowsHookEx(WH_KEYBOARD_LL,KeyboardHookHandler,HInstance,0);
      Result := hNextHookProc <> 0;
    end;function DisableHotKeyHook: BOOL; export;
    begin
      if hNextHookProc <> 0 then
      begin
        UnhookWindowshookEx(hNextHookProc); // 解除 Keyboard Hook
        hNextHookProc := 0;
      end;
      Result := hNextHookProc = 0;
    end;end.
      

  2.   

    你的方法只能截取本程序的按钮。
    要截取其他程序的按键,应该把HOOK放到dll中实现。
      

  3.   

    楼上的谢谢了,明天把它放到DLL中试试
      

  4.   

    把它放入DLL中已经测试通过,无论窗口是否为当前活动窗口。但是现在还有个问题:
    1、这是在工程文件.dpr文件中添加的代码,有些看不懂,大概的意思应该是在DLL退出时,清理hHook的,但是具体代码意思不是很明白。
     exports
     EnableHideHook,
     DisableHideHook;begin
     hHook:=0;
     HideHook:=false;
     HideSaveExit:=ExitProc;//这句没有看懂
     ExitProc:=@HideHookExit;//这句没有看懂
    end.
    ----------
    对应在.pas中的代码:
    procedure HideHookExit;far;procedure HideHookExit;
    begin
    //如果忘了解除HOOK,自动代理解除的动作
     if hHook<>0 then DisableHideHook;
      ExitProc:=HideSaveExit;
    End;
    请那位给我解释一下上面两句的意思。