刚刚学习钩子,可是在调用的时候总会报错,请帮我看一下那里有错.
*****钩子的功能为:当接收到系统打印对列中有任务后,发送WM_SPOOLERSTATUS消息给调用程序,以实现对打印任务实时监控.
________________________________________________________________
library PrinterHook;
uses
SysUtils,
Classes,
Windows,
Messages;var fHHook:HHook;
Apphandle:HWND;
{$R *.res}
//钩子处理过程
function ProcessHook(Code: Integer;WP:WParam;LP:LParam): LRESULT;stdcall;
begin
Result:=0;
if PMSG(lP).message=WM_SPOOLERSTATUS then
SendMessage(AppHandle,WM_SPOOLERSTATUS,WP,LP);
Result := CallNextHookEx(fHHook, Code, WP, LP);
end;
//注册钩子
function RegsiterHook(handle:HWND):boolean;stdcall;export;
begin
AppHandle:=handle;
fHHOOK:=SetWindowsHookEx(WH_GETMESSAGE,@ProcessHook,hInstance,0);
result:=true;
MessageBox(handle,'ok!','information',mb_ok);//Test...
end;
//撤消钩子
function UnRegsiterHook:boolean;stdcall;export;
begin
result:=UnhookWindowsHookEx(FHHOOK);
end;exports
RegsiterHook,
UnRegsiterHook;
begin
end.
____________________________________________
*****钩子的功能为:当接收到系统打印对列中有任务后,发送WM_SPOOLERSTATUS消息给调用程序,以实现对打印任务实时监控.
________________________________________________________________
library PrinterHook;
uses
SysUtils,
Classes,
Windows,
Messages;var fHHook:HHook;
Apphandle:HWND;
{$R *.res}
//钩子处理过程
function ProcessHook(Code: Integer;WP:WParam;LP:LParam): LRESULT;stdcall;
begin
Result:=0;
if PMSG(lP).message=WM_SPOOLERSTATUS then
SendMessage(AppHandle,WM_SPOOLERSTATUS,WP,LP);
Result := CallNextHookEx(fHHook, Code, WP, LP);
end;
//注册钩子
function RegsiterHook(handle:HWND):boolean;stdcall;export;
begin
AppHandle:=handle;
fHHOOK:=SetWindowsHookEx(WH_GETMESSAGE,@ProcessHook,hInstance,0);
result:=true;
MessageBox(handle,'ok!','information',mb_ok);//Test...
end;
//撤消钩子
function UnRegsiterHook:boolean;stdcall;export;
begin
result:=UnhookWindowsHookEx(FHHOOK);
end;exports
RegsiterHook,
UnRegsiterHook;
begin
end.
____________________________________________
改為 PostMessage 試下
if PMSG(lP).message=WM_SPOOLERSTATUS then
SendMessage(AppHandle,WM_SPOOLERSTATUS,WP,LP);
这一步,无法拦截到WM_SPOOLERSTATUS 消息?或者不知道那位能给我讲一WM_SPOOLERSTATUS 这个消息在系统中的运作流程?谢谢.
现在HOOK成功了,当每个进程(包括程序B)取得消息时,都会加载DLL并进入ProcessHook函数,注意,这时DLL在不同的进程空间里,它被加载进来的时候,全局变量AppHandle的值为零!!!
这是钩子应用过程中的常见BUG,解决方法之一是利用内存映射来产生一个真正意义上的全局变量-----跨进程访问的!
const
BUFFER_SIZE = 16 * 1024;
HOOK_MEM_FILENAME = 'MEM_FILE';type
TShared = record
MainWnd :THandle;
end;
PShared = ^TShared;var
MemFile: THandle;
Shared: PShared;procedure DllEntry(dwReason : integer);
begin
case dwReason Of
DLL_PROCESS_ATTACH:
begin
MemFile := OpenFileMapping(FILE_MAP_WRITE,False,HOOK_MEM_FILENAME);
if MemFile = 0 then
MemFile := CreateFileMapping($FFFFFFFF,nil,
PAGE_READWRITE,
0,
SizeOf(TShared),
HOOK_MEM_FILENAME);
Shared := MapViewOfFile(MemFile,
File_MAP_WRITE,
0,
0,
0);
end;
DLL_PROCESS_DETACH:
begin
//你的处理
UnmapViewOfFile(Shared);
CloseHandle(memFile);
end;
else;
end;
end;Shared^.MainWnd := Handle;
现在的问题是当系统中打印任务有变化时钩子无法检测到?而使用其它程序采用PostMessage
WM_SPOOLERSTATUS 消息就可以钩到.怀疑是不是windows在打印队列发生变化时不广播这个消息????欢迎继续讨论!