2

我有一个处理 PreTranslateMessage 中某些消息的 MFC 对话框应用程序。我感兴趣的其中之一是Ctrl+ R。但是,当我单击另一个窗口(Visual Studio 2010 中的代码编辑器、notepad++ 等)并使用Ctrl+ C(或 Ctrl+X)复制一些文本时,我会收到此消息。Ctrl请注意, +似乎不会发生这种情况,并且可以同时使用andV来重现。行为非常混乱!要重现,请在 Visual Studio 10 中创建一个基本的 MFC 对话框,将 pretranslate 添加为:GetKeyStateGetASyncKeyState

BOOL CPreTranslateTestDlg::PreTranslateMessage(MSG *pMsg)
{
    if (GetKeyState(VK_CONTROL) & 0x8000 && pMsg->wParam == 'R')
    {
        return true;
    }

    return CDialogEx::PreTranslateMessage(pMsg);
}

在 上放一个断点return true;,启动对话框。然后转到您的 Visual Studio Code 窗口,然后Ctrl+C一些文本;你的断点将被击中。

关于为什么会发生这种情况的任何想法?

4

2 回答 2

5

GetKeyState旨在为您提供键的状态,无论您的对话框是否具有焦点,因此在您的情况下,它正确指示 Ctrl 已按下。

其次,您没有检查刚刚发生的消息的类型,因此它可能不是 keydown 等。我怀疑正在触发一条与键无关的消息,其 wParam 值恰好等于“R”。

我会更改代码,以便您检查您的对话框是否有焦点并用于GetAsyncKeyState确定是否R也关闭,例如

BOOL CPreTranslateTestDlg::PreTranslateMessage(MSG *pMsg)
{
    if (GetKeyState(VK_CONTROL) & 0x8000 && 
     GetKeyState(VK_R) & 0x8000 && 
     GetFocus == this)
    {
        return true;
    }

    return CDialogEx::PreTranslateMessage(pMsg);
}

希望这可以帮助。

于 2013-03-15T21:14:14.303 回答
0

我这样做是为了在对话框中捕捉键盘快捷键。

首先,您需要有一个加速器表,其中包含要在对话框中使用的加速器,在资源文件中。

例如:

IDR_MYDIALOG_ACCEL

IDC_CTRL_R    Ctrl+R    Virtkey

在对话框的消息映射中,您应该有如下内容:

BEGIN_MESSAGE_MAP(CMyDialogDlg, CDialog)
  //{{AFX_MSG_MAP(CMyDialogDlg)
  ...
    ON_COMMAND(IDC_CTRL_R, OnMyCtrlRHandler)
    ON_WM_DESTROY()
  ...
    //}}AFX_MSG_MAP
END_MESSAGE_MAP()

OnMyCtrlRHandler是快捷方式将调用的方法。

加载加速器表是在OnInitDialog中完成的,如下所示:

BOOL CMyDialogDlg::OnInitDialog()
{
  ...
    m_hAccel = LoadAccelerators ( AfxGetResourceHandle(), 
                                  MAKEINTRESOURCE(IDR_MYDIALOG_ACCEL) );
  ...
}

m_hAccelCMyDialogDlg作为type的成员HACCEL

像这样覆盖 PretranslateMessage:

BOOL CMyDialogDlg::PreTranslateMessage(MSG* pMsg)
{
    if (::TranslateAccelerator(m_hWnd, m_hAccel, pMsg))
      return(TRUE);
    else
      return CDialog::PreTranslateMessage(pMsg);
}

最后,您应该在 OnDestroy 处理程序中销毁加速器表:

void CMyDialogDlg::OnDestroy()
{
  ...
  DestroyAcceleratorTable(m_hAccel) ;
  ...
}
于 2013-03-18T07:58:17.633 回答