C ++子类化表单来捕获F1 - F12键

时间:2010-07-30 09:04:02

标签: c++ windows focus subclassing

主窗体打开一个子窗体,其上有一些按钮CONTROL。我需要捕获键盘事件,所以我将其中一个控件子类化。一切都很好,直到控制失去了焦点。

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

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

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

增加: 我应该提一下,主窗体有一个大型的listview控件,它被子类化以恢复上/下箭头和鼠标滚轮等。

2 个答案:

答案 0 :(得分:1)

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

然而,您可以轻松地在计时器上使用GetKeyboardState轮询键盘,并检查您的f1-f12键是否已激活。计时器的速度可以达到100毫秒,几乎可以捕获所有内容,而几乎不使用任何资源。

答案 1 :(得分:0)

假设这是在Windows和Win32 API中,一个选项是在主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变量中的所有窗口(实际上是静态类成员而不是全局)。

相关问题