ListViewのマウスクリックでOnExitイベントが2回実行されてしまう

解決


Suzuki  2013-06-22 17:35:19  No: 44722

適当にEditコンポーネントとListViewコンポーネントをフォーム上に置いて、
以下のようにEditのOnExitイベントを書いたとします。

procedure TForm1.Edit1Exit(Sender: TObject);
begin
  if ○○ then begin
    ShowMessage('入力値が不正です。再入力してください。');
    Edit1.SetFocus;
  end;
end;

上記のソースで、(if文の条件を満たしつつ)Edit1からListViewコンポーネントへ
「マウスクリック」でフォーカスを移すと、OnExitイベントが「2回」実行されてしまうようで
メッセージも2回表示されてしまうのですが、これは何故なのでしょうか。
マウスクリックによるフォーカス移動ではなくタブキーでフォーカス移動した場合や、
ListViewではなくて、別のコンポーネント(TMemoとかツリービューとか)をクリックした場合には
OnExitが1回しか実行されません。
この現象を回避する方法(1回のみOnExitイベントを実行する方法)がもしあればご教示いただきたいのです。
どうぞよろしくお願いします。

(環境は、Delphi6 personal+Windows7です。)


Harry  2013-06-22 23:02:16  No: 44723

提示されたコードのようにOnExitの中でSetFocusすると再現しました。(Delphi6 Personal、WindowsXP)
ListViewがvsReport時で言うと、ヘッダ部分、またはItemのCaptionの文字をクリックした
場合は普通に1回で、それ以外の場所だと2回発生します。

>これは何故なのでしょうか。
分かりません (^^;
>1回のみOnExitイベントを実行する方法
分かりません (^^;
どなたか解説をお願いします…。

以下、とりあえず思い付いた回避策です。
FormのOnCreateでApplication.OnIdleを設定する以外に、ApplicationEventsコンポーネントの
OnIdleを使ってもOkです。

procedure TForm1.FormCreate(Sender: TObject);
begin
  Application.OnIdle:=ApplicationIdle;
end;

procedure TForm1.Edit1Exit(Sender: TObject);
begin
  if Edit1.Text='Edit1' then Edit1.Tag:=1;
end;

procedure TForm1.ApplicationIdle(Sender: TObject; var Done: Boolean);
begin
  if Edit1.Tag=1 then begin
    Edit1.Tag:=0;
    ShowMessage('入力値が不正です。再入力してください。');
    Edit1.SetFocus;
  end;
end;


Suzuki  2013-06-23 06:41:28  No: 44724

Harryさん

ご回答ありがとうございます。
Harryさんのご提示いただいた方法でメッセージ2回出る問題は回避できることを確認しました。
うまい回避策が思いつかなかったので助かりました。

そもそもの原因は気になりますが、とりあえず「やりたいこと」の解決はできたので
ステータスは「解決」とさせていただきます。
ありがとうございました。


takana  2013-06-23 09:03:16  No: 44725

Tagプロパティを使用しない方法です。

procedure TForm1.Edit1Exit(Sender: TObject);
begin
  if Edit1.Text = 'Edit1' then
  begin
    ShowMessage('入力値が不正です');
    Application.OnIdle := Edit1SetFocus;
  end;
end;

procedure TForm1.Edit1SetFocus(Sender: TObject; var Done: Boolean);
begin
  Application.OnIdle := nil;
  Edit1.SetFocus;
end;


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加