Keyboard hook RRS feed

  • Question

  • Hello,
    First of all, excuse my languange, since English is no my native lang.
    I try to hook the keyboard with SetWindowsHookEx() func, but something strange happened, please take a look at this code:
    HINSTANCE hInst;
    HHOOK g_hKbHook;  // Hook handle
    HWND g_hEdit;     // Handle to Edit control
    wchar_t *g_pBuff;   // pointer to buffer in global
    void ToggleKbHook(HWND hWnd)
    g_hKbHook = ::SetWindowsHookEx(WH_KEYBOARD, reinterpret_cast<HOOKPROC>(KeybHookProc), hInst, ::GetCurrentThreadId());
    LRESULT CALLBACK KeybHookProc(int nCode, WPARAM wParm, LPARAM lParm)
    	UINT mapRes = 0;
    	switch (static_cast<unsigned int>(wParm))
    	case VK_SHIFT:
    		::lstrcat(g_pBuff, L"[SHIFT]");
    	case VK_RETURN:
    		::lstrcat(g_pBuff, L"[ENTER]");
    	case VK_TAB:
    		::lstrcat(g_pBuff, L"[TAB]");
    	case VK_ESCAPE:
    		::lstrcat(g_pBuff, L"[ESC]");
    	case VK_CAPITAL:
    		::lstrcat(g_pBuff, L"[CAPS]");
    		mapRes = ::MapVirtualKey(static_cast<UINT>(wParm), MAPVK_VK_TO_CHAR);
    		if (mapRes > 0){
    			wchar_t res[2];
    			res[0] = static_cast<wchar_t>(mapRes);
    			res[1] = L'\0';
    			::lstrcat(g_pBuff, &res[0]);
    		} else if (mapRes == 0) {
    			::lstrcat(g_pBuff, L"[UNKNOWN_KEY]");
    		} else {
    	if (g_hEdit){
    		if (::lstrlen(g_pBuff) > 0){
    			::SetWindowText(g_hEdit, reinterpret_cast<LPWSTR>(g_pBuff));
    	return ::CallNextHookEx(g_hKbHook, nCode, wParm, lParm);
    When I put one or more breakpoint inside function KeybHokkProc(), the programm running as I expected, Edit control display text properly, but when I remove the breakpoints Edit control show "double characters", it mean when I press character A in keyboard, the Edit control show double character A (AA).
    Why is this happen ?
    Thanks before
    Monday, May 9, 2011 9:49 AM


All replies

  • I read this link over and over again:


    The page say that WH_KEYBOARD is in thread and global scope, and thread scope is called first than global scope. It mean hook procedure is called twice, right ? And somehow debugging system block one of them, I am not sure which one.

    If you know someting about this, please confirm.

    Tuesday, May 10, 2011 11:40 AM
  • Hi,

    I know this is late. However, I recently came across this issue. Turns out that the callback runs twice, once for WM_KEYDOWN and once for WM_KEYUP. Hence what I did was only process one of the callbacks, by putting all the logic in an if condition:

    if(wParm == WM_KEYDOWN || wParm == WM_SYSKEYDOWN) { //or WM_KEYUP and WM_SYSKEYUP

    //your switch statement here.


    Hope this helps.

    Wednesday, September 4, 2013 9:12 AM