当模式对话框关闭时,Delphi CMExit 消息未发送?
在我正在开发的应用程序的一部分中,有一个表单控件在接收 CMExit 消息时进行验证,这正是 Delphi 文档所说的操作方式(此代码示例来自 Delphi 帮助文件):
procedure TDBCalendar.CMExit(var Message: TWMNoParams);
begin
try
FDataLink.UpdateRecord; { tell data link to update database }
except
on Exception do SetFocus; { if it failed, don't let focus leave }
end;
inherited;
end;
这样做的目的是在控件失去焦点时立即执行验证。 因此,例如,如果我单击“确定”按钮,表单控件将失去焦点,此方法将运行,并且在出现异常时会将焦点设置回该表单控件。 (因此“确定”按钮上的“单击”事件永远不会执行,并且对话框永远不会关闭)。
我遇到的问题是这个表单控件位于模式对话框窗口内。 单击“确定”确实会发送 CMExit 消息并导致记录更新(并进行验证)。 但是,在表单控件中按 Enter 键会导致模式对话框关闭而不发送 CMExit 消息。 就好像表单控件永远不会“失去焦点”。 这意味着不仅对话框会在表单没有实际验证数据的情况下关闭,而且数据集也不会更新。
考虑到这个问题,我放置数据集更新/验证代码的最佳位置在哪里? 我可以将其移至对话框表单本身并在 OnCloseQuery 处理程序中实现它,但这意味着逻辑在表单本身的表单控件和中都会重复。 (表单控件在其他地方使用,我想避免改变它的行为)。
(我推测 CMExit 不会被触发,因为该控件实际上从未失去焦点。表单已关闭,但表单控件仍然“具有焦点”在关闭的表单上。)
In one part of the application I'm working on, there is a form control that does validation on reception of the CMExit message, which is exactly how the Delphi documentation says to do it (this code sample is from the Delphi Help files):
procedure TDBCalendar.CMExit(var Message: TWMNoParams);
begin
try
FDataLink.UpdateRecord; { tell data link to update database }
except
on Exception do SetFocus; { if it failed, don't let focus leave }
end;
inherited;
end;
The purpose of this is to perform the validation as soon as the control loses focus. So, for example, if I were to click on the OK button, the form control would lose focus, this method would run and on an exception would set the focus back to that form control. (Thus the "click" event on the OK button would never go through and the dialog would never close).
The problem I'm having is that this form control is inside a modal dialog window. Clicking OK does indeed send the CMExit message and causes the record to update (and validation to occur). However, pressing Enter while in the form control causes the modal dialog to close without sending the CMExit message. It's as if the form control never "loses focus". This means that not only does the dialog close without the form actually validating the data, but the data set isn't updated, either.
Given this problem, where is the best place for me to place my dataset updating/validation code? I could move it up to the dialog form itself and implement it in the OnCloseQuery handler, but this would mean that the logic is duplicated in both the form control and on the form itself. (The form control is used in other places, and I want to avoid changing its behaviour).
(I speculate that CMExit isn't triggered because the control never actually does lose focus. The form is closed, but the form control still "has focus" on the closed form.)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
关闭窗体不一定会触发 TControl 的退出事件。 例如,用户可以按 Alt-F4。
我建议将验证移至单独的过程,并从退出时和关闭时事件中调用该单独的过程。
下面的代码无需太多修改即可工作:
Closing a form does not necessarily fire the on-exit event of a TControl. The user could hit Alt-F4, for example.
I'd suggest moving the validation to a separate proc, and call that separate proc from both the on-exit and on-close events.
The below code should work without too much modification: