鼠标钩 - 冻结程序

时间:2012-01-13 15:30:51

标签: delphi hook

我下载了一个鼠标钩子样本,但没有用。所以我剥掉了所有不必要的东西,想知道它有什么问题。当我启动程序时,它和Delphi都冻结了,我必须通过taskmgr关闭它。

应用:

type
...
    procedure ms(var message: tmessage); message WM_USER+1234;

  end;

var
  MainHookTestForm: TMainHookTestForm;

implementation
procedure HookMouse; stdcall; external 'MouseHook.DLL'; // Added stdcalls;
procedure UnHookMouse; stdcall; external 'MouseHook.DLL';

{$R *.dfm}    

procedure TMainHookTestForm.FormCreate(Sender: TObject);
begin
  HookMouse;
end;

procedure TMainHookTestForm.FormDestroy(Sender: TObject);
begin
  UnHookMouse;
end;

procedure TMainHookTestForm.ms(var message: tmessage);
begin
  Label1.Caption:=format('%d - %d',[message.LParam, message.WParam]); // Edited
end;

库:

library MouseHook;
uses
  Forms,
  Windows,
  Messages;

var Hook: HHOOK;
{$R *.res}

function HookProc(nCode: Integer; MsgID: WParam; Data: LParam): LResult; stdcall;
var
  mousePoint: TPoint;
begin
  mousePoint := PMouseHookStruct(Data)^.pt;
  PostMessage(FindWindow('TMainHookTestForm', 'Main'), WM_USER+1234, mousePoint.X, mousePoint.Y); // Edited class name
  Result := CallNextHookEx(Hook,nCode,MsgID,Data);
end;

procedure HookMouse; stdcall;
begin
  if Hook = 0 then Hook:=SetWindowsHookEx(WH_MOUSE,@HookProc,HInstance,0);
end;

procedure UnHookMouse; stdcall;
begin
  UnhookWindowsHookEx(Hook);
  Hook:=0;
end;

exports
  HookMouse, UnHookMouse;

begin
end.

我认为这很简单。冻结发生在调用HookMouse时,执行此行时,整个IDE冻结,我无法进一步调试。但我在这个程序中看不出任何错误。

我正在使用XE2,如果有帮助的话。感谢您的疑难解答


修改 :我使用HookMouse编辑了UnhookMousestdcall;的调用以及要查找的窗口类的名称。它现在似乎运行良好,它显示正确的值,但仅当鼠标光标不在应用程序窗口中时 - 当我将鼠标移动到窗口时,它会更改为HourGlass并且标题标题停止更新。什么可能导致这种情况?

1 个答案:

答案 0 :(得分:3)

您的代码存在一些问题

1.您错过了stdcall调用约定:

procedure HookMouse; stdcall; external 'MouseHook.DLL';
procedure UnHookMouse; stdcall; external 'MouseHook.DLL';

2.您正在更改主窗体中的标题。所以FindWindow(在DLL中)只会找到一次窗口。您可以使用TMemo进行调试:

procedure TMainHookTestForm.ms(var message: tmessage);
begin
  Memo1.Lines.Add(format('%d - %d',[message.LParam, message.WParam]));
end;

2.1。班级名称MainHookTestForm不正确。应该是:

FindWindow('TMainHookTestForm', 'Main')

请注意 T MainHookTestForm

3.在HookProc你必须使用:

if nCode = HC_ACTION then
begin
  mousePoint := PMouseHookStruct(Data)^.pt;      
  PostMessage(FindWindow('TMainHookTestForm', 'Main'), WM_USER+1234, mousePoint.X, mousePoint.Y);
end;  

Result := CallNextHookEx(Hook,nCode,MsgID,Data);