在PreTranslateMessage中按Ctrl + C时接收Ctrl + R消息

时间:2013-03-15 20:34:07

标签: c++ winapi mfc

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

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

    return CDialogEx::PreTranslateMessage(pMsg);
}

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

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

2 个答案:

答案 0 :(得分: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);
}

希望这有帮助。

答案 1 :(得分: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_hAccel是HACCEL类型的CMyDialogDlg的成员。

像这样覆盖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) ;
  ...
}