Pergunta

Estou criando um aplicativo de console no qual gostaria de gravar pressionamentos de teclas (como a seta para cima). Eu criei um gancho de teclado de baixo nível que deve capturar todas as pressões de teclas em qualquer encadeamento e invocar minha função de retorno de chamada, mas não está funcionando. O programa interrompe um pouco quando eu batia em uma chave, mas nunca chama o retorno de chamada. Eu verifiquei a documentação, mas não encontrei nada. Não sei se estou usando o setWindowshookex () incorretamente (a meu conhecimento, ele cria com sucesso o gancho) ou minha função de retorno de chamada está incorreta! Não tenho certeza do que há de errado! Obrigado antecipadamente pela ajuda.

#include "Windows.h"
#include <iostream>
using namespace std;

HHOOK hookHandle;

LRESULT CALLBACK keyHandler(int nCode, WPARAM wParam, LPARAM lParam);

int _tmain(int argc, _TCHAR* argv[]) {

 hookHandle = SetWindowsHookEx(WH_KEYBOARD_LL, keyHandler, NULL, 0);

 if(hookHandle == NULL) {
  cout << "ERROR CREATING HOOK: ";
  cout << GetLastError() << endl;
  getchar();
  return 0;
 }

 MSG message;

 while(GetMessage(&message, NULL, 0, 0) != 0) {
  TranslateMessage( &message );
  DispatchMessage( &message );
 }

 cout << "Press any key to quit...";
 getchar();

 UnhookWindowsHookEx(hookHandle);

 return 0;
}


LRESULT CALLBACK keyHandler(int nCode, WPARAM wParam, LPARAM lParam) {
 cout << "Hello!" << endl;

 // Checks whether params contain action about keystroke
 if(nCode == HC_ACTION) {
  cout << ((KBDLLHOOKSTRUCT *) lParam)->vkCode << endl;
 }

 return CallNextHookEx(hookHandle, nCode, 
            wParam, lParam);
}
Foi útil?

Solução

Você não pode bloquear em um syscall (o getchar), você deve executar um loop de janela e processar mensagens antes que seu gancho seja chamado.

Outras dicas

No Windows XP, você precisa, você precisa passar hInstance (a partir de WinMain) como o terceiro argumento para SetWindowsHookEx. Por exemplo:

int WINAPI WinMain
( HINSTANCE hInstance, HINSTANCE hPrevInstance,
  LPTSTR lpCmdLine, int nCmdShow ) {

  hookHandle = SetWindowsHookEx ( WH_KEYBOARD_LL, keyHandler, hInstance, 0 );

// ...

Eu sugiro simle primeiro;

// vb: recuperar a instância de aplicativos hinstance appInstance = getModuleHandle (null);

e então: HookHandle = setWindowshookex (wh_keyboard_ll, keyhandler, appInstance, 0);

// ..., mas há outros erros depois também

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top