【问题标题】:Is there an event that fires from a C++ program when a control is about to lose focus?当控件即将失去焦点时,是否存在从 C++ 程序触发的事件?
【发布时间】:2018-04-17 17:14:44
【问题描述】:

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

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

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

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

【问题讨论】:

标签: c++ winapi mfc


【解决方案1】:

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

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

然后,你可以这样做:

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() 进行比较。

结果:

更新

我知道你说过:

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

您可以改用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) 的返回值FALSE。

【讨论】:

  • 这个答案与问题中已被 OP 拒绝的 OnChange 验证有何不同?
  • @MarkRansom 公平点。但他所要做的就是肯定地改变信息。 WM_KEYUP 也许。另外,我不明白为什么他不能只使用DoDataExchange 并在那里进行自定义验证。或者,他可以引入一个“应用”按钮,然后简单地测试所有值并根据需要进行处理。
  • 这就是我最终所做的。由于我要验证的表单是属性表,因此我会自动获得 Apply 按钮。我已经有一个 OnApply() 方法。我只是将所有验证移到那里。我认为这是一个人试图通过验证每次击键来变得过于花哨的情况。
  • 非常感谢 Truckle 先生的详细示例!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多