MOUSE HOOK的DLL中产生的窗口上的数据如何回传给产生该MOUSE事件的窗体(100分)

  • 主题发起人 主题发起人 miki
  • 开始时间 开始时间
function MouseHookProc(Code:integer;// hook code
wParam:WPARAM;// message identifier
lParam:LPARAM// mouse coordinates
):LRESULT;stdcall;
var
x,y:integer;
begin
if code=HC_ACTION then
begin
PostMessage(HookRec^.Receiver,MOUSE_EVENT,
pMouseHookStruct(lparam)^.x,pMouseHookStruct(lparam)^.y);
end;
//HC_NoREmove need not process
Result := CallNextHookEx(HookRec^.MouseHook, Code, wParam, lParam);
end;
方法是自定义一个消息,wparam,lparam 分别为mouse.x,mouse.y 用
postmessgage(yourhookwindow.handle,owndefinemessage,x,y);给你的hook程序发消息。
 
; 我也遇到过类似问题,但发给窗体的消息一旦鼠标离开窗休就接收不到,
不知为什么?
 
我用Delphi写的也用了共享内存段,离开窗体,也能接受消息,要不要。
(C++Builder的没有)
 
; 请给我发一份吧,谢谢!
 
; hubdog谢谢你的源代码,不过我只需要DLL部分的源代码,您能把DLL
部分的源代码给我吗?(这在我的问题中已说过了,可能您没注意)再次
感谢!!
 
library Hook;

{ Important note about DLL memory management: ShareMem must be the
first unit in your library's USES clause AND your project's (select
Project-View Source) USES clause if your DLL exports any procedures or
functions that pass strings as parameters or function results. This
applies to all strings passed to and from your DLL--even those that
are nested in records and classes. ShareMem is the interface unit to
the BORLNDMM.DLL shared memory manager, which must be deployed along
with your DLL. To avoid using BORLNDMM.DLL, pass string information
using PChar or ShortString parameters. }

uses
//SysUtils,
//Classes,
windows;

{$R *.RES}
const
MSG_MOUSE_EVENT='MOUSE_EVENT';
MSG_SHELL_EVENT1='SHELL_EVENT1';//respond to HSHELL_ACTIVATESHELLWINDOW,HSHELL_TASKMAN,HSHELL_LANGUAGE
MSG_SHELL_EVENT2='SHELL_EVENT2';//HSHELL_GETMINRECT
MSG_SHELL_EVENT3='SHELL_EVENT3';//HSHELL_REDRAW
MSG_SHELL_EVENT4='SHELL_EVENT4';//HSHELL_WINDOWACTIVATED
MSG_SHELL_EVENT5='SHELL_EVENT5';//HSHELL_WINDOWCREATED,HSHELL_WINDOWDESTROYED
MSG_KEY_EVENT='KEY_EVENT';

HookMemFileName='Hook.DAT';
HookMutexName='HookMutex';

type
THookType=(htCALLWNDPROC,htCALLWNDPROCRET,htCBT,htDEBUG,htGETMESSAGE,
htJOURNALPLAYBACK,htJOURNALRECORD,htKEYBOARD,htMOUSE,htMSGFILTER,
htSHELL,htSYSMSGFILTER);
//SetWindowsHookEx
THookRec = record
CallHook:HHook;
CallCount:integer;
CallRetHook:HHook;
CallRetCount:integer;
CBTHook:HHook;
CBTCount:integer;
DebugHook:HHook;
DebugCount:integer;
GetMsgHook:HHook;
GetMsgCount:integer;
PlayHook:HHook;
PlayCount:integer;
RecordHook:HHook;
RecordCount:integer;
KeyHook:HHOOK;
KeyCount:Integer;
MouseHook:HHook;
MouseCount:integer;
FilterHook:HHook;
FilterCount:integer;
ShellHook:HHook;
ShellCount:integer;
SysFilterHook:HHook;
SysFilterCount:integer;
Receiver:Integer;
AttachCount:Integer;
MouseInfo:TMouseHookStruct;
end;
PHookRec=^THookRec;

var
Call_Event,CallRet_Event,CBT_Event,Debug_Event,GetMsg_Event,Play_Event,
Record_Event,KEY_EVENT,Mouse_Event,Filter_Event,Shell_Event1,Shell_event2,
Shell_Event3,Shell_event4,Shell_event5,SysFilter_Event:Integer;

MemFile, HookMutex: THandle;
HookRec: PHookRec;

{------------ Hook procedures ------------------}
// Callback of the Keyboard Hook
function MouseHookProc(Code:integer;// hook code
wParam:WPARAM;// message identifier
lParam:LPARAM// mouse coordinates
):LRESULT;stdcall;
var
x,y:integer;
begin
if code=HC_ACTION then
begin
HookRec^.MouseInfo:=pMouseHookStruct(lparam)^;
PostMessage(HookRec^.Receiver,MOUSE_EVENT,wParam,lParam);//postmessage may be lost message
end;
//HC_NoREmove need not process
Result := CallNextHookEx(HookRec^.MouseHook, Code, wParam, lParam);
end;

function KeyHookProc( Code: Integer; // hook code
wParam: WPARAM; // virtual-key code
lParam:LPARAM // keystroke-message information
): LRESULT; stdcall;
begin
if code=HC_ACTION then
PostMessage(HookRec^.Receiver,KEY_EVENT,wParam,lParam);
Result := CallNextHookEx(HookRec^.KeyHook, Code, wParam, lParam);
end;

// Callback of the Shell Hook
function ShellHookProc( Code: Integer; // hook code
wParam: WPARAM; // event-specific information
lParam:LPARAM // undefined
): LRESULT; stdcall;
begin
case Code of
HSHELL_ACTIVATESHELLWINDOW,HSHELL_TASKMAN,HSHELL_LANGUAGE:// send the Code as wParam
PostMessage(HookRec^.Receiver,SHELL_EVENT1,Code,0);
HSHELL_GETMINRECT:
PostMessage(HookRec^.Receiver,Shell_event2,wparam,lparam);
HSHELL_REDRAW:
PostMessage(HookRec^.Receiver,Shell_event3,wparam,lparam);
HSHELL_WINDOWACTIVATED:
PostMessage(HookRec^.Receiver,Shell_event4,wparam,lparam);
HSHELL_WINDOWCREATED,HSHELL_WINDOWDESTROYED:
PostMessage(HookRec^.Receiver,Shell_event5,wparam,Code);
end;
Result := CallNextHookEx(HookRec^.ShellHook, Code, wParam, lParam);
end;

{----------------Procedures called by TCXHook component----------------}
procedure InstallHook(HookType:THookType); stdcall;
begin
try
WaitForSingleObject(HookMutex,INFINITE);
with HookRec^ do
case HookType of
htKEYBOARD:
begin
if (KeyCount=0) and (KeyHook=0) then
KeyHook:=SetWindowsHookEx(WH_KEYBOARD, @KeyHookProc, HInstance , 0);
inc(KeyCount);
end;
htMOUSE:
begin
if (MouseCount=0)and (MouseHook=0) then
MouseHook:=SetWindowsHookEx(WH_MOUSE,@MouseHookProc,HInstance, 0);
inc(MouseCount);
end;
htSHELL:
begin
if (ShellCount=0) and (ShellHook=0) then
ShellHook:=SetWindowsHookEx(WH_SHELL, @ShellHookProc, HInstance , 0);
inc(ShellCount);
end;
end;
finally
ReleaseMutex(HookMutex);
end;
end;
//UnInstallHook
procedure UnHook(HookType:THookType); stdcall;
begin
try
WaitForSingleObject(HookMutex,INFINITE);
with HookRec^ do
case HookType of
htKEYBOARD:
begin
dec(KeyCount);
if (KeyCount<=0) and (KeyHook<>0) then
begin
UnhookWindowsHookEx(KeyHook);
KeyHook:=0;
KeyCount:=0;
end;
end;
htMouse:
begin
dec(mouseCount);
if (MouseCount<=0)and (MouseHook<>0) then
begin
UnhookWindowsHookEx(MouseHook);
MouseHook:=0;
MouseCount:=0;
end;
end;
htSHELL:
begin
dec(ShellCount);
if (ShellCount<=0) and (ShellHook<>0) then
begin
UnhookWindowsHookEx(ShellHook);
ShellHook:=0;
ShellCount:=0;
end;
end;
end;
finally
ReleaseMutex(HookMutex);
end;
end;
// frees all Hooks
procedure UnHookAll; stdcall;
var AlreadyUnHooked:Boolean;
begin
try
WaitForSingleObject(HookMutex,INFINITE);
with HookRec^ do
begin
AlreadyUnHooked:=((ShellCount=0) and (KeyCount=0)and (MouseCount=0));
ShellCount:=0;
KeyCount:=0;
MouseCount:=0;
end;
finally
ReleaseMutex(HookMutex);
end;
if not AlreadyUnHooked then
begin
UnHook(htSHELL);
UnHook(htKEYBOARD);
UnHook(htMouse);
end;
end;
// returns, whether any Hooks are installed
function IsHooked:Boolean; stdcall;
begin
try
WaitForSingleObject(HookMutex,INFINITE);
with HookRec^ do
result:=(ShellCount>0) or (KeyCount>0) or (MouseCount>0);
finally
ReleaseMutex(HookMutex);
end;
end;

procedure SetReceiver(R:Integer); stdcall;
begin
try
WaitForSingleObject(HookMutex,INFINITE);
HookRec^.Receiver:=r;
finally
ReleaseMutex(HookMutex);
end;
end;

procedure IntoDll; stdcall;
begin
// called everytime when the dll is injected into another context
MOUSE_EVENT:=RegisterWindowMessage(PChar(MSG_MOUSE_EVENT));
KEY_EVENT:=RegisterWindowMessage(PChar(MSG_KEY_EVENT));
SHELL_EVENT1:=RegisterWindowMessage(PChar(MSG_SHELL_EVENT1));
SHELL_EVENT2:=RegisterWindowMessage(PChar(MSG_SHELL_EVENT2));
SHELL_EVENT3:=RegisterWindowMessage(PChar(MSG_SHELL_EVENT3));
SHELL_EVENT4:=RegisterWindowMessage(PChar(MSG_SHELL_EVENT4));
SHELL_EVENT5:=RegisterWindowMessage(PChar(MSG_SHELL_EVENT5));

HookMutex:=CreateMutex(nil,True,HookMutexName);
MemFile:=OpenFileMapping(FILE_MAP_WRITE,False,HookMemFileName);
if MemFile=0 then
MemFile:=CreateFileMapping($FFFFFFFF,nil,
PAGE_READWRITE,0,SizeOf(THookRec),HookMemFileName);
HookRec:=MapViewOfFile(MemFile,FILE_MAP_WRITE,0,0,0);
if MemFile=0 then
FillChar(HookRec^,SizeOf(THookRec),0);
inc(HookRec^.AttachCount);
ReleaseMutex(HookMutex);
end;

procedure ExitDll; stdcall;
var finish:Boolean;
begin
try
WaitForSingleObject(HookMutex,INFINITE);
dec(HookRec^.AttachCount);
finish:=(HookRec^.AttachCount=0);
finally
ReleaseMutex(HookMutex);
end;
if finish then
begin
UnHookAll;
UnmapViewOfFile(HookRec);
CloseHandle(MemFile);
CloseHandle(HookMutex);
end;
end;
{------------- DLL Entry ----------------}
procedure DLLEntryPoint(reason:integer);
begin
case reason of
0: {DLL_PROCESS_DETACH} ExitDll;
1: {DLL_PROCESS_ATTACH} IntoDll;
// 2: {DLL_THREAD_ATTACH}
// 3: {DLL_THREAD_DETACH}
end;
end;

function GetMouseInfo:TMouseHookStruct;stdcall
begin
try
WaitForSingleObject(HookMutex,INFINITE);
Result:=HookRec^.MouseInfo;
finally
ReleaseMutex(HookMutex);
end;
end;

exports
InstallHook,
UnHook,
UnHookAll,
IsHooked,
SetReceiver,
GetMouseInfo;

begin
Intodll;
DLLProc:=@DLLEntryPoint;
end.
BTW:
CXLIB.ZIP里的hook.dpr就是dll的原代码。你没注意到吗
 
hubdog: 你能给我传一份dll的代码吗? 非常感谢!!bench的问题和我的贴子是一
回事“如何写一个程序随时监视的按键。(nil)”,我也是在form内有用,form外不
行。
 
; 报歉我对Delphi实在不熟,可否指点一下到底哪一块是定义共享内存段?
Delphi定义时用不着.def文件吗?
 
接受答案了.
 
hubdog兄:
你的 Hook 我能生成 .dll 文件,但不知怎样使用,能否给一个实例,谢谢!!!

信箱: win98_123@net.263
 
后退
顶部