在 PreTranslateMessage 中检查 class 时出现 CInvalidArgumentException

CInvalidArgumentException when checking class in PreTranslateMessage

案例:我想用小键盘创建快捷方式,以便用户可以快速使用我的应用程序。我在 PreTranslateMessage 中实现了这个并且成功了。

但情况是我有一个编辑控件,用户应该在其中输入一些数字。因此,当用户将焦点放在编辑控件 (CEdit) 上时,快捷方式应该 disabled.

为了解决这个问题,我添加了

CWnd* pControl;
pControl = this->GetFocus();
if(!(pControl->IsKindOf(RUNTIME_CLASS(CEdit)))){

但现在每当我的应用程序对话框失去焦点时,它就会关闭 (see video) 并且我得到以下异常:

这是完整代码:

// Handles keypresses for fast acces of functions
BOOL COpenFilesDlg::PreTranslateMessage(MSG *pMsg){
    CWnd* pControl;
    pControl = this->GetFocus();
    if(!(pControl->IsKindOf(RUNTIME_CLASS(CEdit)))){ //when this statement is commented the program doesn't crash
        if(pMsg->message == WM_KEYDOWN)
        {
            if((pMsg->wParam == 0x31 || pMsg->wParam == VK_NUMPAD1))
                someFunction();
            else if((pMsg->wParam == 0x33 || pMsg->wParam == VK_NUMPAD3)){
                someOtherFunction();
            }
        }
    }       

    return CDialog::PreTranslateMessage(pMsg);
}

现在我的问题是:为什么我的程序在未获得焦点时会崩溃,以及如何检查焦点是否以正确的方式位于编辑控件上?

CWnd::GetFocus returns 指向具有当前焦点的 window 的指针,如果没有焦点 window,则为 NULL。

pControl = this->GetFocus();
if ( pControl != NULL )
{
    if(!(pControl->IsKindOf(RUNTIME_CLASS(CEdit))))
    ...
}

另一种方法是将 pControl 值与指向对话框 class 的 CEdit class 成员(或多个成员)的指针进行比较。例如,如果 CEdit m_edit 是编辑框 class 成员,则测试:

if ( pControl == (CWnd*)&m_edit )
{
    // focus is on m_edit control
}