Mouse Hook,鼠标钩子一问(200分)

C

cuteh

Unregistered / Unconfirmed
GUEST, unregistred user!
想要实现一个全局的Mouse Hook.使主窗体能跟踪显示当前光标的坐标.
包括光标不在主窗体内和主窗体失去焦点时.我的想法是用一个dll来
捕捉鼠标事件(找到的资料上都是这么做的),然后发消息给主窗体.但
是结果只有当鼠标在主窗体范围内的时候才有效.一但离开了主窗体,
鼠标事件仍然被捕捉到了(我在dll内设置了检测,证实了这一点),但主
窗体没有响应.我也试过用callback代替sendmessage,但结果是一样的.

下面是主要部份的源码:

主窗体:
....
type
THookForm = class(TForm)
SysHookBtn: TButton;
RemoveHookBtn: TButton;
procedure SysHookBtnClick(Sender: TObject);
procedure RemoveHookBtnClick(Sender: TObject);
procedure FormDestroy(Sender: TObject);
public
procedure HookReceiver(var Msg: TMessage); message WM_USER+100;
end;

var
HookForm: THookForm;

implementation
....

procedure THookForm.SysHookBtnClick(Sender: TObject);
begin
if not InstallHook(Handle) then
ShowMessage('Could not install mouse hook.');
end;

procedure THookForm.HookReceiver(var Msg: TMessage);
var
pt: Tpoint;
begin
if msg.Msg = WM_USER+100 then
begin
pt := PMOUSEHOOKSTRUCT(msg.LParam)^.pt;
Caption := IntToStr(pt.x) + ' '+IntToStr(pt.y);
end;
end;
.....

DLL部份:
....
var
HookHandle: HHook;
WndHandle: HWND;

function MouseHookProc(Code: integer; Msg: WPARAM; MouseHook: LPARAM): LRESU
LT; stdcall;
begin
if Code >= 0 then
if Msg = WM_MOUSEMOVE then
begin
messagebeep(1);
SendMessage(WndHandle, WM_USER + 100, Msg, MouseHook);
end;
Result := CallNextHookEx(HookHandle, Code, Msg, MouseHook);
end;

function InstallHook(SenderHandle: HWND) : boolean; export;
begin
WndHandle := SenderHandle;
Result := TRUE;
HookHandle := SetWindowsHookEx(WH_MOUSE, MouseHookProc, HInstance, 0);
if HookHandle = 0 then Result := FALSE;
end;

function RemoveHook: boolean; export;
begin
Result := UnhookWindowsHookEx(HookHandle);
end;

exports
InstallHook,
RemoveHook,
MouseHookProc;
....
 
提供链接,供参考:
http://www.delphibbs.com/delphibbs/dispq.asp?lid=1126509
 
接受答案了.
 
顶部