这是一个简单的键盘钩子程序,为什么在Form1失去焦点后,钩子就不起作用了?
还有如何把钩子响应函数中按键值传递给Form1?unit Unit1;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;type
TForm1 = class(TForm)
Memo1: TMemo;
Button1: TButton;
procedure FormCreate(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure Button1Click(Sender: TObject);
private public
{ Public declarations }
end;function MyKeyBordHook(iCode : Integer; WParam : WPARAM; lParam : LPARAM): LRESULT; stdcall;var
Form1: TForm1;
HHook: Integer;
Ch: Integer;implementation{$R *.dfm}function MyKeyBordHook(iCode : Integer; WParam : WPARAM; lParam : LPARAM): LRESULT; stdcall;
begin
Result:=CallNextHookEx(HHook,iCode,wParam,lParam);
Ch:=WParam;
end;procedure TForm1.FormCreate(Sender: TObject);
begin
HHook:=SetWindowsHookEx(WH_KEYBOARD,MyKeyBordHook,Hinstance,0);
end;procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
UnhookWindowsHookEx(HHook);
end;procedure TForm1.Button1Click(Sender: TObject);
begin //显示按键值
Memo1.Text:=IntToStr(Ch);
end;end.
还有如何把钩子响应函数中按键值传递给Form1?unit Unit1;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;type
TForm1 = class(TForm)
Memo1: TMemo;
Button1: TButton;
procedure FormCreate(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure Button1Click(Sender: TObject);
private public
{ Public declarations }
end;function MyKeyBordHook(iCode : Integer; WParam : WPARAM; lParam : LPARAM): LRESULT; stdcall;var
Form1: TForm1;
HHook: Integer;
Ch: Integer;implementation{$R *.dfm}function MyKeyBordHook(iCode : Integer; WParam : WPARAM; lParam : LPARAM): LRESULT; stdcall;
begin
Result:=CallNextHookEx(HHook,iCode,wParam,lParam);
Ch:=WParam;
end;procedure TForm1.FormCreate(Sender: TObject);
begin
HHook:=SetWindowsHookEx(WH_KEYBOARD,MyKeyBordHook,Hinstance,0);
end;procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
UnhookWindowsHookEx(HHook);
end;procedure TForm1.Button1Click(Sender: TObject);
begin //显示按键值
Memo1.Text:=IntToStr(Ch);
end;end.
解决方案 »
- 请问 raize listview 为什么不能在列头 显示 图标???????????????????????急!!!!!!!!!!!
- suiStringGrid中的问题!!![急!!!]
- 数据转换问题?(paradox7.0 to sql2000)在线等--------UP有分
- 有木有找delphi7兼职做程序的啊?
- dev Express中的dev Grid如何自动生成列?
- 关于TActionList
- 请问Hint的时间是否可以控制
- 如何将自定义的文件存为word文件(.doc)?
- !!!哪儿有关于win2000注册表教程下载?
- 如何把窗体的最大化按钮灰化?(不是没有)
- 在image控件上实现画笔功能时,窗体闪烁不停,背景越大越厉害,请问怎样解决这个问题?
- 真正的高手请进,这个问题半个月了没人解答出来:如何获得任意程序中的插入符位置?
所以直接访问变量取得钩子结果的方式是不可行的。
我是这样做的。用PostMessage把钩子结果发送给主程序。PostMessage的第一个参数是主程序窗体的Handle, 这个Handle不可以用静态变量传送,原因同前,全局钩子函数用静态变量传递信息是有困难的。所以这里的Handle我是搜寻主窗体得来的。unit HookU;interfaceuses Windows, Messages, SEShare;const
WM_CAPKEY = WM_USER + $301;
WM_CAPMOUSE = WM_USER + $302;
WM_CAPMOUSE1 = WM_USER + $303;
WM_CAPMOUSE2 = WM_USER + $304;
WM_CAP2CONTROL = WM_USER + $306;function HookAllHookEx(): Boolean; export;
procedure UnHookAllHookEx(); export;
function HookKBHookEx(): Boolean; export;
procedure UnHookKBHookEx(); export;implementationvar
kbhook: HHOOK = 0;
mshook: HHOOK = 0; HookKeyFormHandle: HWND = 0;
CtrlCapStatus: Byte = 0;var
WindowList: TList;function GetWindows(
handle: HWND; // handle to parent window
info: LPARAM // application-defined value
): Boolean; stdcall;
begin {}
Result := True;
WindowList.Add(Pointer(handle));
end;function FindPrevInstance(clssname: string; selfhandle: HWnd): HWnd;
var
i: integer;
Dest: array [0..80] of char;
begin
Result := 0;
WindowList := TList.Create();
EnumWindows(@GetWindows, 0);
for i := 0 to WindowList.Count - 1 do
if HWnd(WindowList[i]) <> selfhandle then
begin
GetClassName(Hwnd(WindowList[i]), Dest, Sizeof(Dest) - 1);
if strlen(Dest) > 0 then
if (String(Dest) = clssname) then
begin
Result := Hwnd(WindowList[i]);
Break;
end;
end;
WindowList.Free();
end;function kbhookproc(code: Integer; wparam: WPARAM; lparam: LPARAM): LRESULT stdcall;
begin
Result := CallNextHookEx(kbhook, code, wparam, lparam);
if code = HC_ACTION then
begin
if HookKeyFormHandle = 0 then
HookKeyFormHandle := FindPrevInstance('TBarSvrForm', 0); if HookKeyFormHandle <> 0 then
if (wparam <> VK_LWIN) and (wparam <> VK_RWIN) then
begin
if wparam = VK_CONTROL then
begin
if lparam and $80000000 <> 0 then //up
begin
if CtrlCapStatus = 1 then
CtrlCapStatus := 2;
end
else // down
begin
if CtrlCapStatus = 2 then
begin
CtrlCapStatus := 3;
PostMessage(HookKeyFormHandle, WM_CAP2CONTROL, 0, 0);
end
else
CtrlCapStatus := 1;
end;
end
else
CtrlCapStatus := 0;
if CtrlCapStatus >= 3 then
CtrlCapStatus := 0
else
PostMessage(HookKeyFormHandle, WM_CAPKEY, wparam, lparam);
end;
end;
end;function mshookproc(code: Integer; wparam: WPARAM; lparam: LPARAM): LRESULT stdcall;
var
pmsrec: PMOUSEHOOKSTRUCT;
begin
Result := CallNextHookEx(mshook, code, wparam, lparam);
if code = HC_ACTION then
begin
if HookKeyFormHandle = 0 then
HookKeyFormHandle := FindPrevInstance('TBarSvrForm', 0);
if HookKeyFormHandle <> 0 then
if wparam <> WM_MOUSEMOVE then
begin
pmsrec := Pointer(lparam);
PostMessage(HookKeyFormHandle, WM_CAPMOUSE1, pmsrec.pt.x, pmsrec.pt.y);
PostMessage(HookKeyFormHandle, WM_CAPMOUSE2, pmsrec.wHitTestCode, pmsrec.dwExtraInfo);
PostMessage(HookKeyFormHandle, WM_CAPMOUSE, wparam, pmsrec.hwnd);
end;
end;
end;procedure UnHookAllHookEx();
begin
if kbhook <> 0 then
begin
UnHookWindowsHookEx(kbhook);
kbhook := 0;
end;
if mshook <> 0 then
begin
UnHookWindowsHookEx(mshook);
mshook := 0;
end;
end;
function HookAllHookEx(): Boolean;
begin
kbhook := SetWindowsHookEx(WH_KEYBOARD, kbhookproc, HInstance, 0);
mshook := SetWindowsHookEx(WH_MOUSE, mshookproc, HInstance, 0);
if (kbhook <> 0) and (mshook <> 0) then
Result := True
else
begin
UnHookAllHookEx();
Result := False;
end;
end;
procedure UnHookKBHookEx();
begin
if kbhook <> 0 then
begin
UnHookWindowsHookEx(kbhook);
kbhook := 0;
end;
end;
function HookKBHookEx(): Boolean;
begin
kbhook := SetWindowsHookEx(WH_KEYBOARD, kbhookproc, HInstance, 0);
if (kbhook <> 0) then
Result := True
else
begin
UnHookKBHookEx();
Result := False;
end;
end;end.