当前位置:C++技术网 > 资讯 > 钩子拦截Notepad中WM_COMMAND消息

钩子拦截Notepad中WM_COMMAND消息

更新时间:2015-06-26 15:03:17浏览次数:1+次

    由于工作软件需要改进,最近看了些钩子方面的知识,没想到一开始就遇到问题了。假如要给Notepad菜单中增加一个新的子菜单,而当菜单按下时会发送WM_COMMAND消息,安装WH_GETMESSAGE钩子,即可对其进行响应。  
    关于钩子的基本用法和设置请参考C++技术网《钩子最基本的设置方法(作者:NBHZ200)》,在此不作赘述。
    通过捕获WM_COMMAND消息的思想来实现。由于Windows中每个进程都有自己独立的地址空间,因此对新菜单的响应代码并不能放在我们所编写程序的exe(称为控制程序)中,而是要放在dll内。dll中代码如下:
#include "stdafx.h"
#include <windows.h>
#include <tchar.h>
#define IDM_TEST 0x100//菜单ID
extern HMODULE hDll;//包含钩子过程的dll应用实例句柄,可通过DllMain函数的第一个参数获取;也可通过函数GetModuleHandle获取
#pragma data_seg(".shared") 
HWND g_hWnd = 0;//窗口句柄
HMENU hMenu=0; //窗口菜单
HHOOK g_hHook=0; //HOOK句柄 
UINT WM_HOOKSPY=0; //自定义消息,通知远程进程读取编辑框控件的内容
#pragma data_seg() 
#pragma comment(linker,"/SECTION:.shared,RWS") 
#define pCW ((MSG*)lParam)
extern "C" LRESULT CALLBACK HookProc( 
    int code, 
    WPARAM wParam,  
    LPARAM lParam
    ) 
{
    if(code>=0)
    {
        if(pCW->message==WM_COMMAND)//捕获WM_COMMAND消息
        {
            if(LOWORD(pCW->wParam)==IDM_TEST)//wParm低16位控件ID号,高16位为通知码
            {
                MessageBox(NULL,_T("test"),_T("NotepadHook"),0);
            }
            UnhookWindowsHookEx(g_hHook);
        }
    }
    return CallNextHookEx(g_hHook,code,wParam,lParam);
}
_declspec(dllexport) void NotepadHook() 
{
    g_hWnd=FindWindow(_T("Notepad"),_T("无标题 - 记事本"));//获取记事本窗口句柄
    hMenu=GetMenu(g_hWnd);//获取菜单
    AppendMenu(hMenu,MF_ENABLED | MF_STRING,IDM_TEST,_T("testMenu"));//在菜单中添加新菜单testMenu
    DrawMenuBar(g_hWnd);
    g_hHook=SetWindowsHookEx(WH_GETMESSAGE,(HOOKPROC)HookProc,
        hDll,GetWindowThreadProcessId(g_hWnd,NULL));//安装钩子
}

    我们所编写的控制程序代码:
void CNotepadDlg::OnClickedAppend()
{
    typedef void (*NotepadHook)();
    NotepadHook notepadhook=NULL;
    HINSTANCE hDll=0;
    hDll=LoadLibrary(_T("NotepadHook.dll"));
    notepadhook=(NotepadHook)GetProcAddress(hDll,"?NotepadHook@@YAXXZ");
    if(NULL==notepadhook)
        MessageBox(_T("error"));
    notepadhook();
}
     结果分析:调试运行时,钩子能够安装成功,菜单也能添加成功,但当菜单按下时没有任何反应。通过SPY++查看,菜单按下时会发送WM_COMMAND消息,而且其ID也和设定的一致。找了好久资料和相关知识,但还是不知道问题出在哪个环节,欢迎能和大神们探讨!