1

次のシナリオで問題が発生しています。

  • 2編集
  • Edit1に何かを入力してTabキーを押すと、フォーカスがEdit2に移動します
  • Edit1.OnExit->「Processing...」というメッセージを含むフォームを表示します(長い検証を行います)

フォームが閉じた後、Edit2のフォーカスが「クラッシュ」したようです...-Edit2の穴のテキストが選択されていません-キャレットが点滅していません

例:

  • 新しいフォームを作成する
  • 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
4

2 に答える 2

3

これは既知の問題です。最後のフォーカス変更が完了する前にフォーカスを変更すると、Windowsに問題が発生します(たとえば、フォーカスがからEdit1に変更され始めますがEdit2Edit1.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のPeterBelow博士による古いBorlandNG投稿から:

これが「OnExitからのダイアログを表示する」問題に関する私の一般的な説教です。

OnExitハンドラーがトリガーされた場合(これはWindowsメッセージWM_KILLFOCUSに応答して発生します)、Windowsはフォーカス変更の最中です。別のフォーカス変更を引き起こすハンドラーで何かを行うと(メッセージボックスのポップアップやSetFocus呼び出しの実行など)、Windowsはひどく混乱します。カーソルの欠落はその症状です。

OnExitハンドラーからユーザーにメッセージを表示する必要がある場合は、次のようにします。

  1. フォームの型宣言の上にある、ユニットのインターフェイスセクションのどこかにユーザーメッセージの定数を定義します。

    'Const UM_VALIDATE = WM_USER + 200;'

  2. フォームにこのメッセージのハンドラーを指定します。これは、クラス宣言のプライベートセクションに配置するのが最適です。

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

  3. フィールドの内容に問題がある場合は、OnExitハンドラーからフォームにUM_VALIDATEメッセージを送信します。メッセージのwparamパラメーターとlparamパラメーターで、エラー番号やSenderオブジェクトなどの追加情報を渡すことができます。実際、UMValidateハンドラーで検証全体を実行できます。

于 2012-06-22T14:19:33.400 に答える
2

ここで何が起こっているのか正確にはわかりませんが、メッセージの処理順序が少し混乱しているようです。で他のフォームを強制終了する代わりにFree、使用するReleaseとフォーカスが希望どおりに動作します。

別のオプションは、ShowModalの代わりに使用することですShow。通常、処理中にユーザーがメインフォームに変更を加えたくないため、処理ダイアログをモーダルに表示します。そうすれば、を使い続けることができますFree

于 2012-06-22T12:02:44.740 に答える