DELAPI Edit.OnExit by TAB,显示焦点错误的窗口结果

时间:2012-06-22 11:57:58

标签: delphi

我遇到以下情况时出现问题:

  • 2编辑
  • 在Edit1中输入内容并按TAB键,焦点转到Edit2
  • Edit1.OnExit - >显示一个带有“Processing ...”消息的表单(进行冗长的验证)

表单关闭后,对Edit2的关注似乎“崩溃”了...... - 未选择Edit2中的孔TEXT - carret没有闪烁

示例:

  • 创建新表单
  • 进行2次编辑
  • 将其设置为Edit1中的OnExit事件:

    procedure TForm1.Edit1Exit(Sender: TObject);
    begin
      with TForm.CreateNew(self) do
         try
           Width := 100;
           Height := 50;
           Position := poMainFormCenter;
           show;
           sleep(200);
         finally
           Free;
         end;
    end;
    
  • 运行应用程序

  • 在Edit1中设置焦点并按TAB

我正在使用:

  • Delphi 7 Enterprise
  • Windows 7 x64

2 个答案:

答案 0 :(得分:3)

这是一个已知问题。在完成最后一次焦点更改之前更改焦点时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 Peter博士的旧Borland NG帖子:

  

这是关于“OnExit显示对话框”问题的一般布道:

     

如果触发OnExit处理程序(响应于   视窗   消息WM_KILLFOCUS)Windows正处于焦点变化之中。如果你这样做   处理程序中导致另一个焦点更改的东西(如弹出窗口)   消息框或执行SetFocus调用)Windows非常困惑。   该   缺少光标就是这种情况的症状。

     

如果必须从OnExit处理程序向用户显示消息,请执行此操作   它   这样:

     
      
  1. 在INterface中的某处定义用户消息的常量   部分   您的单位,高于表格的类型声明

         

    “CONST     UM_VALIDATE = WM_USER + 200;'

  2.   
  3. 为您的表单提供此邮件的处理程序,最好放在私有邮件中   类声明部分:

         

    Procedure UMValidate( Var Msg: TMessage ); message UM_VALIDATE;

  4.   
  5. 从OnExit处理程序中将UM_VALIDATE消息发布到表单中   该字段的内容不正常。你可以传递额外的   消息的wparam和lparam参数中的信息,例如   错误号和Sender对象。事实上,你可以做到整体   UMValidate处理程序中的验证!

  6.   

答案 1 :(得分:2)

我不确定这里究竟发生了什么,但看起来消息的处理顺序有些混乱。不要使用Free删除其他表单,而是使用Release,焦点会按照您的意愿运行。

另一种选择是使用ShowModal代替Show。通常,您会以模态方式显示处理对话框,因为您不希望用户在处理时对主窗体进行修改。如果您这样做,那么您可以继续使用Free