如何截获分析其它程序窗口的WM_COMMAND消息?就像SPY++一样。
我主要目的是想分析出菜单的ID。
请给出详细的代码,谢谢了。我想这个问题应该难不倒你的!是吗?
我主要目的是想分析出菜单的ID。
请给出详细的代码,谢谢了。我想这个问题应该难不倒你的!是吗?
解决方案 »
- 如何通过代码设计Dbgrid1的字段名?
- 菜鸟问题,大家帮下忙,检测指定窗体鼠标点击事件,再转为某个键盘按键,最好有简单代码框架,先谢谢各位了 .
- 请问C++中的_int64 和 int *aaa 在DELPHI 中如何转换
- 想用delphi把mysql的数据导出备份,
- stringGrid 控件如何让字体居中 ?
- 关于字符串处理的问题。
- 怎么实现类似银行存折的套打
- 哎,本人用QUERY连DBGRID,本来可以,但是ORDER BY后就不行了。
- 谁帮我看看这个报表用FastReport怎么制作?
- Delphi6两个新控件的问题,高手请进。
- 文本修改后读取乱码
- 怎样知道指定窗口的指定按钮是否被按下?
HHOOK SetWindowsHookEx(
int idHook, //要安装的HOOK的类型
HOOKPROC lpfn, //HOOK的回调函数
HINSTANCE hMod, //进程
DWORD dwThreadId //程序的线程,如果为0则是全局HOOK
);熟悉了SetWindowsHookEx函数,我们就能开始我们的工作,挂钩进程。
首先打开Delphi,创建一个DLL工程(DLL Wizard)。然后创建一个新的单元(Unit1)。
首先在单元的 interface 下面声明要用到的函数。
var
OldHook:HHOOK;
Histance:HISTANCE;
OldProc:FARPROC;
我们的第一个函数是安装HOOK,让我们看一下代码:Function SetHook:Boolean;stdcall;
begin
OldHook:=SetWindowsHookEx(WH_KEYBOARD,@HookProc,Histance,0);
if (OldHook=0) then exit else Result:=True;
end;这样的话就安装一个全局的键盘HOOK,HOOK的方法还有很多,在此就不一一列举了。下面介绍一下回调函数:
Function HookProc(nCode,wParam,lParam:Integer);Integer;stdcall;
begin
Result:=CallNextHookEx(OldHook,nCode,wParam,lParam);
end;这样的话就完成了对进程的挂钩。可是挂上钩我们的工作并没结束,相反,我们的工
作才刚刚开始。钩子的作用是帮我们把DLL注入到别人的进程空间。现在我们的DLL已
经在别人的进程空间内。所以,我们就可以做我们想做的事。
下面介绍一下Windows的子类化处理。大家都知道,在windows里不管你做了什么事,都会向windows发送一条消息,然后由
Windows作出相应的处理后才会返回给传送消息的应用程序。
那大家会问:“HOOK不是已经拦截了windows消息了吗?”是啊,那也要看是拦截了什么消息,就如上面我们写的WH_KEYBOARD,我们拦截了键盘
消息,我们可以在按下任何一个按键的时候做出处理。消息的种类有很多。
可是我们今天要讲的是windows的子类化处理,这又是一门新的技术。
不废话了,这就开始。^_^相信大家都见过两这个API:GetWindowsLong 和 SetWindowLong;
可能你们会说,这些不是处理窗口消息的吗?对,这就是我们要用到的API。接下来让我们看一下这些API的参数。
LONG GetWindowLong(
HWND hWnd, //窗体的句柄
int nIndex //欲取回的信息,可参照下表
);
nIndex的值可以是下列任何一个
GWL_EXSTYLE 扩展窗口样式
GWL_STYLE 窗口样式
GWL_WNDPROC 该窗口的窗口函数的地址
GWL_HINSTANCE 拥有窗口的实例的句柄
GWL_HWNDPARENT 该窗口之父的句柄。不要用SetWindowWord来改变这个值
GWL_ID 对话框中一个子窗口的标识符
GWL_USERDATA 含义由应用程序规定
DWL_DLGPROC 这个窗口的对话框函数地址
DWL_MSGRESULT 在对话框函数中处理的一条消息返回的值
DWL_USER 含义由应用程序规定
也许大家会注意到 GWL_WNDPROC 这个参数。没错,我们子类处理就是要用到这个参数。
代码如下:
OldProc:=GetWindowLong(hWnd,GWL_WNDPROC);这样我们的OldProc就指向窗体的窗口函数地址;
既然得到了窗口函数地址,那么就修改到我们自定义的消息处理地址里吧。
下面要用到SetWindowLong函数了。
LONG SetWindowLong(
HWND hWnd, //指定窗口句柄
int nIndex, //和GetWindowLong的nIndex一样
LONG dwNewLong //新的消息处理地址
);代码如下:
SetWindowLong(hWnd,GWL_WNDPROC,Longint(@WinProc));这样就把指定窗体的消息转到了我们的函数内执行;回调函数如下:
Function WinProc(Hwnd,Msg,wParam,lParam:longint):LRESULT; stdcall;
begin
Result:=CallWindowProc(OldProc,Hwnd,Msg,wParam,lParam);
end;
这里的Msg就是窗口的消息,后面赋上消息表。小节:文章写到这里,相信大家应该明白HOOK和子类是什么回事吧。下面再解释一下
为什么不在HOOK里处理消息。前面已经提到,HOOK是帮助我们把DLL注入别人的进程。
而windows子类处理只能在进程内处理消息,所以只有我们到了别人的进程空间内,才
能做出消息屏蔽的动作。这样说大家都能明白了吧。 好了,就不废话了。下面赋上源代码。希望大家多多支持! ^_^
(复制就可以用的哦)##########################################################################
unit Unit1;interface
uses windows;
var
OldHook:HHOOK; //用来保存HOOK的返回值
OldProc:FARPROC; //用来指向窗口消息
Function SetHook:Boolean;stdcall;
Function HookProc(nCode,wParam,lParam:Integer):Integer;stdcall;
Function WinProc(Hwnd,Msg,wParam,lParam:longint):LRESULT; stdcall;
implementation
{###################################################################################}
//安装HOOK
Function SetHook:Boolean;stdcall;
var
Histance:Cardinal;
begin
//安装HOOK
OldHook:=SetWindowsHookEx(WH_KEYBOARD,@HookProc,Histance,0);
if (OldHook=0) then exit else Result:=True;
end;{###################################################################################}
//HOOK回调函数
Function HookProc(nCode,wParam,lParam:Integer):Integer;stdcall;
var
WinStr:HWND;
begin
//设置热键
if (wParam=VK_F12) then
begin
WinStr:=FindWindow(nil,'窗口的标题文字');
OldProc:=FARPROC(GetWindowLong(WinStr,GWL_WNDPROC));
SetWindowLong(WinStr,GWL_WNDPROC,Longint(@WinProc));
end;
//将HOOK传递给Windows处理
Result:=CallNextHookEx(OldHook,nCode,wParam,lParam);
end;{###################################################################################}
//自定义Windows消息处理函数
Function WinProc(Hwnd,Msg,wParam,lParam:longint):LRESULT; stdcall;
begin
{在这做出对消息的处理 case Msg of
WM_ACTIVATEAPP:exit;
WM_ACTIVATE:exit;
WM_KILLFOCUS:exit;
WM_SETFOCUS:exit;
end;
上面这些消息是窗口失去焦点和获得焦点的屏蔽
}
//将窗口消息传递给Windows处理
Result:=CallWindowProc(OldProc,Hwnd,Msg,wParam,lParam);
end;
end.
function WindowProc(hWnd,Msg,wParam,lParam:longint):LRESULT; stdcall;
var k:integer;
begin
Result:=DefWindowProc(hWnd,Msg,wParam,lParam);
case Msg of
wm_destroy:
begin
for k:=0 to 12 do SetHook(False,k);
postmessage(findwindow('WinHook',nil),wm_destroy,0,0);
ExitThread(0);
end;
end;
if msg=wmhook then
begin
if wparam>0 then
begin
if sethook(true,wparam-1)=true then postmessage(findwindow('WinHook',nil),wmhook,wparam,0);
end else
begin
if sethook(false,-wparam-1)=true then postmessage(findwindow('WinHook',nil),wmhook,wparam,0);
end;
end;
end; procedure run;stdcall;
//var k:integer;
begin
win.wClass.lpfnWndProc:= @WindowProc;
win.wClass.hInstance:= hInstance;
win.wClass.lpszClassName:='WideHook';
RegisterClass(win.wClass);
win.hmain:=CreateWindowEx(ws_ex_toolwindow,win.wClass.lpszClassName,'WideHook',WS_CAPTION,0,0,1,1,0,0,hInstance,nil);
FillChar(Shared^,SizeOf(TShared),0);
shared^.self:=win.hmain;
shared^.hinst:=hinstance;
InitHookData;
wmhook:=registerwindowmessage(pchar('wm_hook'));
while(GetMessage(win.Msg,win.hmain,0,0))do
begin
TranslateMessage(win.Msg);
DispatchMessage(win.Msg);
end;
end; procedure DllEntryPoint(fdwReason:DWORD);
begin
case fdwReason of
DLL_PROCESS_DETACH:
Extro;
end;
end; exports run; begin
//建立内存映象文件,用来保存全局变量
MemFile:=CreateFileMapping($FFFFFFFF,nil,PAGE_READWRITE,0,SizeOf(TShared),HookMemFileName);
Shared:=MapViewOfFile(MemFile,FILE_MAP_WRITE,0,0,0);
DLLProc:=@DllEntryPoint;
end. ---------这是*.exe主程序--------------------------- Program WinHook; uses windows,messages,sysutils;
{$r *.res} //使用资源文件
const
HTName:array[1..13] of pchar=(
'CALLWNDPROC','CALLWNDPROCRET','CBT','DEBUG','GETMESSAGE','JOURNALPLAYBACK',
'JOURNALRECORD','KEYBOARD','MOUSE','MSGFILTER','SHELL','SYSMSGFILTER','FOREGROUNDIDLE'
);
type
TWin = record
Msg:TMsg;
wClass:TWndClass;
hMain:integer;
hbut,hlab:array[1..16] of integer;
hLib:integer;
HookStat:array[1..16] of bool;
end;
var
Win:TWin; //结构变量
wmhook:integer;
WorkPath:string;
hRun:procedure;stdcall;
//
procedure runhookfun;
begin
win.hlib:=loadlibrary(pchar(WorkPath+'DemoHook.dll'));
if win.hlib=0 then messagebox(win.hmain,'error','',0);
hrun:=GetProcAddress(win.hlib,'run');
if @hrun<>nil then hrun;
end; procedure runhook;
var tid:integer;
begin
createthread(nil,0,@runhookfun,nil,0,tid);
end; function WindowProc(hWnd,Msg,wParam,lParam:longint):LRESULT; stdcall;
var k:integer;
begin
case Msg of
WM_SYSCOMMAND:
begin
case wparam of
SC_CLOSE:
begin
if findwindow('WideHook','WideHook')<>0 then postmessage(findwindow('WideHook','WideHook'),wm_destroy,0,0);
end;//showwindow(hwnd,sw_hide);
SC_MINIMIZE:;//showwindow(hwnd,sw_hide);
SC_MAXIMIZE:;
SC_DEFAULT:;
SC_MOVE:;
SC_SIZE:;
//else
//Result := DefWindowProc(hwnd, uMsg, wParam, lParam);
end;
exit;
end;
wm_command:
begin
http://blog.csdn.net/linzhengqun
看里面的钩子应用。