其实我们看到的菜单也是窗口,窗口类名是“#32768”,不过HMenu不是窗口句柄,HMenu是菜单的一个内置结构的地址。
如果我们想要替换菜单的窗口过程的地址,必须通过Hook来截获到菜单的窗口创建消息。对于一般的创建我们只要处理了wm_create就可以了,但对于菜单我们必须截获Windows没有公开的消息:0x1e2 ,在该消息中msg.hwnd就是我们要找的菜单窗口的句柄。
获得了菜单窗口的句柄,我们就很容易进行SetWindowLong对菜单进行窗口过程回调的设置。
********************************************************************************************************************************
菜单也是窗口,窗口类名是“#32768”,不过HMenu不是窗口句柄,HMenu是菜单的一个内置结构的地址
HHOOK hhook=SetWindowsHookEx(WH_CALLWNDPROC,(HOOKPROC)myHookProc,hInstance,GetCurrentThreadId());
LRESULT CALLBACK myHookProc(int code,WPARAM wParam,LPARAM lParam)
{
CWPSTRUCT* lpcwps=(CWPSTRUCT*)lParam;
if(code==HC_ACTION)
{
int nCount;
TCHAR szClassName[100];
WNDPROC lpfnOrg;
if(lpcwps->message==WM_NCCREATE)
{
//Customize menu
if(lstrcmp(szClassName,"#32768")==0)
{
//在这里重定义Menu窗口过程(需要保存原始窗口过程)
WNDPROC lpfnOrg=(WNDPROC)SetWindowLong(lpcwps->hwnd,GWL_WNDPROC,(LONG)NewMenuProc);
//Save old wndproc to window properties
SetProp(lpcwps->hwnd,"__oldwndproc",(HANDLE)lpfnOrg);
}
}
}
}
//菜单窗口过程
LRESULT CALLBACK NewMenuProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
{
WNDPROC lpfnOrg=(WNDPROC)GetProp(hwnd,"__oldwndproc");
//处理相关消息
return CallWindowProc(lpfnOrg,hwnd,msg,wParam,lParam);
}