none
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]");
    		break;
    	case VK_RETURN:
    		::lstrcat(g_pBuff, L"[ENTER]");
    		break;
    	case VK_TAB:
    		::lstrcat(g_pBuff, L"[TAB]");
    		break;	
    	case VK_ESCAPE:
    		::lstrcat(g_pBuff, L"[ESC]");
    		break;
    	case VK_CAPITAL:
    		::lstrcat(g_pBuff, L"[CAPS]");
    		break;
    	default:
    		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 {
    
    		}
    		break;
    	}
    	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

Answers

All replies

  • I read this link over and over again:

    http://msdn.microsoft.com/en-us/library/ms644990(VS.85).aspx

    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