Удаление хука клавиатуры, когда пользователь покидает приложение

Я пытаюсь определить, когда пользователь нажимает на вкладки из моего окна. Я пробовал несколько сообщений (проверка WM_ACTIVATE, WM_KILLFOCUS, WM_ACTIVATEAPP, WM_NCACTIVATE, WM_CANCELMODE и WM_SYSCOMMAND на SC_MINIMIZE). Но та же проблема все еще возникает. Происходит следующее

  1. Мое приложение находится в фокусе, и я удерживаю Alt и нажимаю Tab.
  2. Следующее окно выведено.
  3. Я продолжаю удерживать нажатой клавишу alt, а затем снова нажимаю клавишу табуляции, но на этот раз распознается только табуляция, и поэтому я в конечном итоге вкладываю вкладки в новом окне, а не снова нажимаю вкладки, как обычно

Я использую низкоуровневую клавиатуру, и если я удаляю это вышеописанное поведение alt tabbing, отлично работает. Я хочу удалить клавиатуру, как только пользователь покинет мое окно таким образом. Как только я отпускаю alt tab в другом окне, мое окно получает несколько сообщений, которые я ищу, и ловушка удаляется. Но когда вы удерживаете клавиши таким образом, они не будут работать так, как ожидалось, пока хук установлен.

2 ответа

Я использовал следующий код, и он, кажется, улавливает изменения фокуса, и у меня не возникает проблем с удержанием ALT или TAB в различных комбинациях. Но я еще не проверил это полностью.

РЕДАКТИРОВАТЬ: я прочитал ваш пост еще раз и вижу, что ваша проблема, вероятно, является взаимодействие между двумя различными крючками. Поэтому я также подключаю клавиатуру в своем приложении, но я использую ловушку таблицы адресов импорта из DispatchMessage. Мои крючки взаимодействуют не так, как ваши, но моё решение может не подойти вам.

bool AddHookToKeyboardFocusChanges()
{
  HHOOK hhookFocusChange = NULL;

  hhookFocusChange = SetWindowsHookEx(WH_CALLWNDPROC, (HOOKPROC)CallWindowProcHook, NULL, GetCurrentThreadId());    // the last parameter makes it a local, not global hook

  if(hhookFocusChange == NULL)
    return false;

  return true;
}

///////////////////////////////////////////////////////////////////////////////
// This is the routine that we register to be called on every call to a
// WindowProc in our application; we use it to catch WM_SETFOCUS and 
// WM_KILLFOCUS messages that indicate gaining or losing keyboard input focus.
// Unlike keyboard, mouse, paint, and timer messages, the focus messages are not
// posted to the message queue. Instead they are sent directly to WindowProc.
// We must hook them here.
//
LRESULT WINAPI CallWindowProcHook(int nCode, WPARAM wParam, LPARAM lParam) 
{
  UINT message = ((CWPSTRUCT*)lParam)->message;

  switch(message)
  {
    case WM_ACTIVATE:
      OutputDebugString(L"Window activated.\n");
      break;
    case WM_SETFOCUS:
      OutputDebugString(L"Window focused.\n");
      break;
    case WM_KILLFOCUS:
      OutputDebugString(L"Window focus lost.\n");
      break;
    default:
      break;
  }

    // CallNextHookEx calls the next hook in the chain.
    return CallNextHookEx(NULL, nCode, wParam, lParam); 
}

Зачем вам снимать зацепку клавиатуры? SetWindowsHook является локальным для вашего приложения и не влияет на другие приложения, поэтому он уже ничего не делает, если ваше приложение не имеет фокуса.

Отредактируйте, убедитесь, что вы вызываете следующий хук в вашем обратном вызове с CallNextHookEx, чтобы не испортить программы чтения с экрана

Другие вопросы по тегам