当控件即将失去焦点时,是不是存在从 C++ 程序触发的事件?
Posted
技术标签:
【中文标题】当控件即将失去焦点时,是不是存在从 C++ 程序触发的事件?【英文标题】: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 世界中。但它提供了我正在寻找的功能。
【问题讨论】:
在你走得太远之前,请阅读 Microsoft 的 Raymond Chen 的这篇文章:WM_KILLFOCUS is the wrong time to do field validation。 MFC 为dialog data validation 提供了一个框架,您可以对其进行自定义以满足您的特定要求。 【参考方案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 先生的详细示例!以上是关于当控件即将失去焦点时,是不是存在从 C++ 程序触发的事件?的主要内容,如果未能解决你的问题,请参考以下文章
当嵌入式 ActiveX 控件接收并失去键盘焦点时如何获得通知?
EXCEL 文本框控件点击文字变很小,失去焦点后又回复正常,这怎么解决?