/定义全局数据
///////////////////////////////////
#pragma data_seg("ShareData")
HHOOK g_hMsgHook = NULL;
HHOOK g_hCallProcHook = NULL;
TCHAR g_szBuff[11] = {0};
#pragma data_seg()
#pragma comment(linker, "/SECTION:ShareData,rws")
HINSTANCE  g_hInst = NULL;

LRESULT CALLBACK GetMsgProc(int code,   //消息钩子
    WPARAM wParam,
    LPARAM lParam
)
{ MSG* pMsg = (MSG*)lParam; 
if(pMsg->message == WM_KEYDOWN || pMsg->message == WM_KEYUP)
{
     for(int i = 0 ; i< 11 ;i ++)
 {
if(GET_CHAR_VK(g_szBuff[i]) == pMsg->wParam)
{
SetVirtualKey(GET_VIRTUALKEY(0),pMsg->wParam);
}
 }

}
return ::CallNextHookEx(g_hMsgHook,code,wParam,lParam);}
通过上述钩子,已经能够把相应的按键消息转换成其他按键消息了!!
但是出现了其他的问题!
问题如下:
当我挂钩好之后,发现能够将按键A 映射到按键VK_NUMPAD0 
然后我在notepad里面按A键,显示的都是0很正常!
但是,当我吧notepad关闭掉,再按键A ,发现显示的都是A字符了!说明钩子不起作用了!!!郁闷!!!
没想明白是哪里出了问题!高手指点!!!

解决方案 »

  1.   

    把notepad关掉后,然后再打开,在notepad和其他任何文本框中输入,都没有效果了!
      

  2.   

    关掉notepad好像没有卸载钩子吧!我在DLL_PROCESS_DETACH中加入了OutputDebug来查看,发现,没有输出语句,应该就没有卸载吧,我是把卸载放在这里的!
    BOOL APIENTRY DllMain( HMODULE hModule,
                           DWORD  ul_reason_for_call,
                           LPVOID lpReserved
     )
    {
    switch(ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
    g_hInst = hModule;
    break;
    case DLL_PROCESS_DETACH:
    if(g_hMsgHook != NULL)
    ::UnhookWindowsHookEx(g_hMsgHook);
    if(g_hCallProcHook != NULL)
    ::UnhookWindowsHookEx(g_hCallProcHook);
    ::OutputDebugString(TEXT("Process Detach \n"));
    break;
    default:
    break;
    }    return TRUE;
    }
    BOOL SetHook()
    {
        if(g_hMsgHook != NULL)
    ::UnhookWindowsHookEx(g_hMsgHook);
    if(g_hCallProcHook)
    ::UnhookWindowsHookEx(g_hCallProcHook); g_hMsgHook = ::SetWindowsHookEx(WH_GETMESSAGE, GetMsgProc,g_hInst,0); //设置GetMessage钩子
    g_hCallProcHook = ::SetWindowsHookEx(WH_CALLWNDPROC,CallWndProc,g_hInst,0);//设置CallWndProc钩子
    if(g_hMsgHook != NULL && g_hCallProcHook != NULL)
    {
    return TRUE;
    }
    DWORD dwErr;
    dwErr = GetLastError();
    return FALSE;
    }
      

  3.   

    在安装钩子的时候用的WH_KEYBOARD_LL
      

  4.   

    case DLL_PROCESS_DETACH: 
    if(g_hMsgHook != NULL) 
    ::UnhookWindowsHookEx(g_hMsgHook); 
    if(g_hCallProcHook != NULL) 
    ::UnhookWindowsHookEx(g_hCallProcHook); 
    ::OutputDebugString(TEXT("Process Detach \n")); 
    break; 进程退出 钩子就卸载了
    吧这部分改下