鼠标钩子-冻结程序

发布于 2024-12-26 18:08:48 字数 1802 浏览 0 评论 0原文

我下载了一个鼠标钩示例,但没有用。所以我剥离了所有不必要的东西,并想知道其中出了什么问题。当我启动程序时,它和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;

Lib:

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,如果有帮助的话。感谢您进行故障排除


编辑:我使用 stdcall;HookMouse 和 UnhookMouse 编辑了调用; code> 和要查找的窗口类的名称。现在似乎工作得很好,它显示了正确的值,但只有当鼠标光标不在应用程序窗口中时 - 当我将鼠标移动到窗口时,它会更改为 HourGlass 和标签标题停止更新。什么可能导致这种情况?

I downloaded a mouse hook sample, which didn't work. So I stripped all the unnecessary stuff and would like to know what is wrong in it. When I start the program, both it and Delphi freeze and I have to close it through taskmgr.

App:

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;

Lib:

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.

I think this is as simple as it gets. The freeze happens at the call of HookMouse, when this line is executed, the whole IDE freezes and I can't debug further. But I can't see anything wrong in that procedure.

I am using XE2, if that helps. Thanks for the troubleshooting


Edit: I edited the calls of HookMouse and UnhookMouse with stdcall; and the name of the window class to find. It seems to be working nice now, it shows correct values, BUT only if the mouse cursor is not in the app window - when I move the mouse to the window, it changes to the HourGlass and the Label caption stops updating. What could cause this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

月亮邮递员 2025-01-02 18:08:48

您的代码存在一些问题

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);

You have a few problems with your code

1.You are missing the stdcall calling convention:

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

2.You are changing the caption in the main form. so FindWindow (in the DLL) will find the window only once. you can use TMemo to debug:

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

2.1.The class name MainHookTestForm is not correct. should be:

FindWindow('TMainHookTestForm', 'Main')

Note the T MainHookTestForm

3.in the HookProc you must use:

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);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文