这是一个已知问题。当您在完成最后一次焦点更改之前更改焦点时,Windows 会出现问题(例如,焦点开始从 Edit1 更改为 Edit2,但 Edit1.OnExit 会执行某些操作以将焦点更改为另一个控件或表单。
例如,当应用尝试在 OnExit 事件中进行验证,然后在验证失败时尝试将焦点返回到原始控件时,就会发生这种情况。
最简单的解决方案是将消息发布到OnExit 中的表单句柄,并在那里处理焦点更改需求。一旦目标控件获得输入焦点,它就会触发,Windows 不会感到困惑。
const
UM_EDIT1_EXITED = WM_USER + 1;
type
TForm1=class(TForm)
...
private
procedure UMEdit1Exited(var Msg: TMessage); message UM_EDIT1_EXITED;
end;
implementation
procedure TForm1.Edit1Exit(Sender: TObject);
begin
PostMessage(Handle, UM_EDIT1_EXITED, 0, 0);
end;
procedure TForm1.UMEdit1Exited(var Msg: TMessage);
begin
// Show your other form here
end;
来自TeamB下方的 Peter 博士的旧 Borland NG 帖子:
这是我关于“从 OnExit 显示对话框”问题的一般布道:
如果触发了 OnExit 处理程序(这发生在响应
视窗
消息 WM_KILLFOCUS) Windows 正在更改焦点。如果你这样做
处理程序中导致另一个焦点变化的东西(比如弹出
一个消息框或进行 SetFocus 调用)Windows 变得非常混乱。
这
缺少光标就是一个症状。
如果您必须从 OnExit 处理程序向用户显示消息,请执行
它
这样:
-
在接口的某处为用户消息定义一个常量
部分
你的单位,在你的表格的类型声明上方
'常量
UM_VALIDATE = WM_USER + 200;'
-
为您的表单提供此消息的处理程序,最好放在私有
类声明部分:
Procedure UMValidate( Var Msg: TMessage ); message UM_VALIDATE;
如果出现以下情况,则从 OnExit 处理程序向表单发布 UM_VALIDATE 消息
该字段的内容不正确。你可以通过额外的
消息的 wparam 和 lparam 参数中的信息,例如
错误号和 Sender 对象。事实上你可以做整个
在 UMValidate 处理程序中进行验证!