1,183
社区成员
我现在是想,按一次鼠标右键,执行一次操作,可是现在我的情况是,按一次鼠标,一直执行,死循环了,代码如下,烦请大神帮我看看。
DLL代码如下:
library myhook;
uses
System.SysUtils,
Windows,
Messages,
System.Classes;
{$R *.res}
const WM_MyMessage = WM_USER + 1; {自定义消息}
var
hook: HHOOK;
info: string;
h: HWND; {用作外部窗口的句柄}
{获取外部窗口的句柄}
function SetHWnd(hwnd: HWND): Boolean; stdcall;
begin
h := hwnd;
Result := True;
end;
function MouseHook(nCode: Integer; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
begin
begin
case wParam of
WM_rBUTTONDOWN : info := '按下';
end;
info := Format('%s', [info]);
{通过消息把数据传递给指定窗口}
PostMessage(h, WM_MyMessage, 0, Integer(PChar(info)));
Result := CallNextHookEx(hook, nCode, wParam, lParam);
end;
end;
function SetHook: Boolean; stdcall;
const
WH_MOUSE_LL =14;
begin
hook := SetWindowsHookEx(WH_MOUSE_LL, @MouseHook, HInstance, 0);
Result := hook <> 0;
end;
function DelHook: Boolean; stdcall;
begin
Result := UnhookWindowsHookEx(hook);
end;
exports SetHook, DelHook, MouseHook, SetHWnd;
begin
end.
窗体代码如下:
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls,Vcl.ExtCtrls;
const WM_MyMessage = WM_USER + 1;
type
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure MyMessage(var msg: TMessage); message WM_MyMessage; {定义一个消息方法接受消息}
end;
function SetHook: Boolean; stdcall;
function DelHook: Boolean; stdcall;
function SetHWnd(hwnd: HWND): Boolean; stdcall;
var
Form1: TForm1;
implementation
{$R *.dfm}
function SetHook; external 'MyHook.dll';
function DelHook; external 'MyHook.dll';
function SetHWnd; external 'MyHook.dll';
procedure TForm1.Button1Click(Sender: TObject);
begin
SetHook;
SetHWnd(Handle);
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
DelHook;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
Button1.Caption := '安装钩子';
Button2.Caption := '载卸钩子';
FormStyle := fsStayOnTop; {为了测试, 让窗口一直在前面}
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
DelHook;
end;
{把接受到的内容显示在窗体}
procedure TForm1.MyMessage(var msg: TMessage);
begin
if PChar(msg.LParam)='按下' then
begin
ShowMessage('ddd'); //这里要怎么控制,让鼠标右键点击一次,执行一次,现在是死循环,一直showmessage,或者DLL里的代码要如何修改?
end;
end;
end.
谢谢大神,非常感谢!
case wParam of
WM_rBUTTONDown:
begin
info := '按下';
info := Format('%s', [info]);
PostMessage(h, WM_MyMessage, 0, Integer(PChar(info)));
end;
PostMessage(h, WM_MyMessage, 0, Integer(PChar(info)));这段代码要放在MOUSEDOWN里面。
否则任何消息被钩到都会调用PostMessage,这就使得TForm1.MyMessage会无限触发,一直弹框。
注意是任何消息,钩子钩到的消息非常密,非常多的,你把代码放在外面,就无限执行了。必须放在CASE下面。