当控件即将失去焦点时,是否会有来自C ++程序的事件?

时间:2018-04-17 17:14:44

标签: c++ winapi mfc

我正在尝试修复MFC CEdit控件中的验证错误。目前,验证是在OnChange事件处理程序中执行的。但这不起作用,因为它会在用户完成输入之前验证数据

所以,相反,我试图在OnKillFocus事件处理程序内部进行验证。如果验证失败,那么我使用GotoDlgCtrl()将焦点返回到包含无效数据的编辑框。当我调用GotoDlgCtrl()时,杀戮焦点事件再次触发,我处于无限循环中。

所以,我想处理一个在控件丢失焦点之前触发的事件,这样如果我确定数据无效,我可以停止焦点离开,而是让用户输入正确的数据。

我知道我在某个地方看过验证活动,但那可能是在.Net世界。但它提供了我正在寻找的功能。

1 个答案:

答案 0 :(得分:2)

右键单击对话框资源并调用类向导:

Class Wizard

接下来,转到虚拟功能选项卡,找到PreTranslateMessage并添加它:

Virtual Functions

然后,你可以这样做:

BOOL CTestDlgDlg::PreTranslateMessage(MSG* pMsg)
{
    if (pMsg->message == WM_CHAR)
    {
        CWnd *pControl = GetDlgItem(IDC_EDIT1);
        if (pControl->GetSafeHwnd() == pMsg->hwnd)
        {
            if (pMsg->wParam == _TINT('!'))
            {
                AfxMessageBox(_T("Not allowed ! character"));
                return TRUE;
            }
        }
    }

    return CDialogEx::PreTranslateMessage(pMsg);
}

通常,控件是CEdit类型的成员变量,因此您可以与m_edit.GetSafeHwnd()进行比较。

结果:

Result

更新

我意识到你说过:

  

但这不起作用,因为它会在用户完成输入之前验证数据

您可以改为使用WM_KEYUP

BOOL CTestDlgDlg::PreTranslateMessage(MSG* pMsg)
{
    if (pMsg->message == WM_KEYUP)
    {
        CWnd *pControl = GetDlgItem(IDC_EDIT1);
        if (pControl->GetSafeHwnd() == pMsg->hwnd)
        {
            CString str;
            GetDlgItemText(IDC_EDIT1, str);
            if (str.Find(_T("!")) >= 0)
            {
                AfxMessageBox(_T("Not allowed ! character"));
                return TRUE;
            }
        }
    }

    return CDialogEx::PreTranslateMessage(pMsg);
}

这使您有机会在显示更新后进行验证。

另一种自定义DoDataExchange处理程序的方法。在那里,您可以根据需要进行验证。然后在您的代码中,您可以简单地测试UpdataData(TRUE)的{​​{1}}的返回值。