私が取り組んでいるアプリケーションの一部では、CMExitメッセージの受信時に検証を行うフォームコントロールがあります。これは、Delphiのドキュメントに記載されているとおりです(このコードサンプルはDelphiのヘルプファイル):モーダルダイアログが閉じられているときにDelphi CMExitメッセージが送信されませんか?
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;
この目的は、コントロールがフォーカスを失うとすぐに検証を実行することです。たとえば、[OK]ボタンをクリックすると、フォームコントロールのフォーカスが失われ、このメソッドが実行され、例外でフォームコントロールにフォーカスが戻されます。 (したがって、OKボタンの「クリック」イベントは決して通過せず、ダイアログは決して閉じることはありません)。
問題は、このフォームコントロールがモーダルダイアログウィンドウ内にあることです。 [OK]をクリックすると、実際にCMExitメッセージが送信され、レコードが更新されます(検証が実行されます)。ただし、フォームコントロール内でEnterキーを押すと、CMExitメッセージを送信せずにモーダルダイアログが閉じるになります。これは、フォームコントロールが決して「フォーカスを失う」ことではありません。これは、フォームが実際にデータを検証するのではなくダイアログが閉じるだけでなく、データセットも更新されないことを意味します。
私のデータセットの更新/検証コードを置くのに最適な場所はどこですか?私はそれをダイアログフォーム自体に移し、OnCloseQueryハンドラでそれを実装することができますが、これはロジックがフォームコントロールとの両方でフォーム自体に複製されていることを意味します。 (フォームコントロールは他の場所で使用され、その動作を変更しないようにしたい)。
(私はコントロールが実際にが失うフォーカスをしたことがないので、CMExitがトリガされていないと推測している。フォームが閉じられているが、フォームコントロールは、まだ閉じた形の「フォーカスがある」。)クロージング
Cm_Exitは、フォーカス変更イベントです。そこからSetFocusを呼び出さないでください。フォーカスがすでに変化している間は、フォーカスを変更しないでください。代わりに、メッセージを投稿し、それに応答してフォーカスを変更します。 OSはフォーカスを変更している間中断されたくない。実際に何が焦点を当てているのか混乱します。 –