Keyboard issues

I am using a voice chat application that uses the push-to-talk key. I made a hook so that it will register an external push-to-talk application too.

HHOOK hHook = SetWindowsHookEx(WH_KEYBOARD_LL,(HOOKPROC)pushtotalk,0,0); LRESULT CALLBACK pushtotalk(int key, WPARAM wParam,LPARAM lParam) { if (key < 0) { return (CallNextHookEx(hook,key,wParam,lParam)); } else if (connected) { KBDLLHOOKSTRUCT* kbdll = (KBDLLHOOKSTRUCT*)lParam; if (kbdll ->vkCode == 75 && wParam == WM_KEYDOWN) { MessageBox(mainhWnd,"KEYSTART","KEYSTART",0); } else if (kbdll ->vkCode == 75 && wParam == WM_KEYUP) { MessageBox(mainhWnd,"KEYSTOP","KEYSTOP",0); } } return (CallNextHookEx(hook,key,wParam,lParam)); } 

Problems

1) Sometimes (for example, the first execution of proc in an application), a process causes a system shutdown 5 seconds before continuing. Why?

2) The hook only works with the process that was started before the launch of my application, if I started the text program after the application started, the interceptors will not be registered. Is there a fix for this?

3) If I hold the key for ~ 3 seconds, many of the MessageBox messages show, obviously, but after that proc never registers the other key pressed, so I suppose I somehow disconnected from the hook chain?

Greetings

EDIT: here is the main message loop for the application

 LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { switch(message) { case WM_COMMAND: switch (LOWORD(wParam)) { case ID_MENU_EXIT: SendMessage(hWnd,WM_CLOSE,0,0); break; case ID_MENU_PREFERENCES: voiceManager->send((void*) "1"); break; case ID_BUTTON_CONNECT: onConnect(hWnd); break; case ID_BUTTON_DISCONNECT: onDisconnect(hWnd); break; case ID_BUTTON_SEND: onSendText(hWnd); break; default: break; } break; case SOCKET_TCP: switch (lParam) { case FD_READ: { // Disable repeated FD_READ call while we process message WSAAsyncSelect(wParam,hWnd,SOCKET_TCP, FD_WRITE | FD_ACCEPT | FD_CLOSE); // first four bytes is packet size // second four bytes are used to identify type of msg char* psize = (char*)malloc(5); char* ptype = (char*)malloc(5); psize[4] = '\0'; ptype[4] = '\0'; recv(wParam,psize,4,0); recv(wParam,ptype,4,0); // allocate memory for the buffer int size_to_recv = atoi(psize); char* textbuff = (char*)malloc(size_to_recv); // receive int i = size_to_recv; while (i > 0) { int read = recv(wParam,textbuff,i,0); i = i - read; } // handle msg depending on type switch(identifyMsg(ptype)) { case 1: // handle 'text' msg onReadText(hWnd,textbuff); break; case 2: // handle 'name' msg onReadName(hWnd,textbuff); break; case 3: // handle 'list' msg onReadList(hWnd,textbuff); break; case 4: // handle 'remv' msg onReadRemv(hWnd,textbuff,size_to_recv); break; case 5: // handle 'ipad' msg -- add ip voiceManager->addParticipant(inet_addr(textbuff)); break; case 6: // handle 'iprm' msg -- remove ip voiceManager->removeParticipant(inet_addr(textbuff)); break; default: break; } // re-enable FD_READ WSAAsyncSelect(wParam,hWnd,SOCKET_TCP, FD_WRITE | FD_ACCEPT | FD_READ | FD_CLOSE); // free resources free(psize); free(ptype); free(textbuff); break; } case FD_WRITE: break; case FD_CONNECT: break; case FD_CLOSE: onDisconnect(hWnd); break; default: break; } break; case WM_PAINT: paintText(hWnd); break; case WM_DESTROY: shutdownConnection(hWnd); // reset window procs SetWindowLong(GetDlgItem(hWnd,ID_EDIT_SEND), GWL_WNDPROC,(LONG) OriginalEditProc); SetWindowLong(GetDlgItem(hWnd,ID_EDIT_IP), GWL_WNDPROC,(LONG) OriginalEditProc); PostQuitMessage(0); return 0; break; case WM_CLOSE: DestroyWindow(hWnd); break; default: break; } return DefWindowProc(hWnd, message, wParam, lParam); } LRESULT CALLBACK sendEditProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { if (message == WM_CHAR) { if (wParam == VK_RETURN) { onSendText(GetParent(hWnd)); return 0; } } if (message == WM_KEYUP || message == WM_KEYDOWN) { if (wParam == VK_RETURN) { return 0; } } return CallWindowProc(OriginalEditProc, hWnd, message, wParam,lParam); } 

Where sendEditProc is a sub / superclass designed to intercept the 'enter' keys when inside the edit control 'send' Does this help?

Here's the message loop; this is the standard, so there’s nothing fancy that can go wrong, afik :)

 while (GetMessage(&msg, NULL,0,0)) { TranslateMessage(&msg); DispatchMessage(&msg); } 
+6
c ++ input winapi keyboard hook
source share
1 answer

You call CallNextHookEx too many times. If key < 0 return CallNextHookEx , otherwise return 0 .

The problem you see is related to keyboard repeats, and the MessageBox or MessageBeep methods are very expensive calls. Try this test:

 HHOOK hHook; BOOL bTalkEnabled = FALSE; LRESULT CALLBACK pushtotalk(int key, WPARAM wParam, LPARAM lParam) { if (key < 0) return CallNextHookEx(hHook, key, wParam, lParam); KBDLLHOOKSTRUCT* kbdll = (KBDLLHOOKSTRUCT*)lParam; if (kbdll->vkCode == VK_F11) { BOOL bStarted = FALSE; BOOL bStopped = FALSE; if (wParam == WM_KEYDOWN) { if (!bTalkEnabled) { bStarted = TRUE; bTalkEnabled = TRUE; } } else if (wParam == WM_KEYUP) { if (bTalkEnabled) { bStopped = TRUE; bTalkEnabled = FALSE; } } if (bStarted) OutputDebugString(L"Pushed\r\n"); if (bStopped) OutputDebugString(L"Released\r\n"); } return 0; } 

You can control the debugging lines by running the application under the debugger (check the output window), or you can get a DebugView and see what.

Please note that I do not check connected , as you did. You do not want to perform this check on the hook, do it outside the hook and use only the hook to determine if the key is pressed or not pressed.

+3
source share

All Articles