0

主窗体打开一个子窗体,上面有一些按钮控件。我需要捕获键盘事件,因此我对其中一个控件进行了子类化。一切都很好,直到控制当然失去焦点。

理想情况下,只要这个子窗体是打开的,我想将焦点分配给这个控件,从而捕获所有的击键,无论用户点击哪里。

我怀疑超类可能是一个更好的方法,但我并不熟悉它。

也许我应该做的是在主窗体上使用加速器?

添加:我应该提到主窗体有一个大型列表视图控件,该控件被子类化以恢复向上/向下箭头和鼠标滚轮等。

4

2 回答 2

1

传统的方法是安装一个键盘钩子(SetWindowsHookEx),但是您需要将它注入到每个应用程序中,并且它不能跨越 32/64 位边界。

但是,您可以很容易地在计时器上使用GetKeyboardState轮询键盘并检查您的 f1-f12 键是否已激活。计时器可以慢到 100 毫秒,它几乎可以在不使用任何资源的情况下捕获所有内容。

于 2010-07-30T09:10:29.090 回答
0

假设这是在 Windows 和 Win32 API 中,一种选择是在您的 main GetMessageTranslateMessageDispatchMessage循环中查找消息。您可以在此循环中对任何消息进行特殊处理,而不管它针对的是哪个窗口。

您可能应该使用IsChild检查该消息是否用于主窗口上的控件(而不是某些可能单独显示的对话框或消息框)。获得正确的逻辑也可能很繁琐。最好在您知道您的控件失去焦点时才拦截消息,并且拦截您需要的确切消息。

几年前,我写了一个库消息循环,其中包含很多内置的。我有一个简单的管理器类,它保存指向我自己的小窗口类实例的指针。循环知道对话框和普通窗口之间的区别,让每个窗口类有机会窥探其子级消息,等等。您将无法直接运行它,并且约定有点奇怪,但您可能会发现这很有用......

int c_Window_List::Message_Loop (void)
{
  MSG msg;
  bool l_Handled;

  while (GetMessage (&msg, NULL, 0, 0))
  {
    l_Handled = false;

    c_Windows::c_Cursor l_Cursor;
    bool                ok;

    for (ok = l_Cursor.Find_First (g_Windows); ok; ok = l_Cursor.Step_Next ())
    {
      if (IsChild (l_Cursor.Key (), msg.hwnd))
      {
        if (l_Cursor.Data ().f_Accelerators != NULL)
        {
          l_Handled = TranslateAccelerator (l_Cursor.Key (), l_Cursor.Data ().f_Accelerators, &msg);

          if (l_Handled)  break;
        }

        if (l_Cursor.Data ().f_Manager != 0)
        {
          l_Handled = l_Cursor.Data ().f_Manager->Spy_Msg (l_Cursor.Key (), msg);
        }

        if (l_Handled)  break;

        if (l_Cursor.Data ().f_Is_Dialog)
        {
          l_Handled = IsDialogMessage (l_Cursor.Key (), &msg);
          if (l_Handled)  break;
        }
      }
    }

    if (!l_Handled)
    {
      TranslateMessage (&msg);
      DispatchMessage  (&msg);
    }

    if (g_Windows.Size () == 0)
    {
      //  When all windows have closed, exit
      PostQuitMessage (0);
    }
  }

  return msg.wParam;
}

f_前缀表示字段 - 我后来采用了约定m_,但是很长时间没有重新访问此代码。f_Manager特别指向我c_Window_Base班级的一个实例。该类c_Cursor是一种迭代器,用于遍历存储在g_Windows变量中的所有窗口(实际上是静态类成员而不是全局成员)。

于 2010-07-30T09:55:16.980 回答