0

例外を引き起こすこの厄介な状況があります。私は問題を見つけましたが、解決策を実装するのは今のところ難しいです。

私たちのアプリケーションでは、ユーザーが一定時間アクティブでない場合、セキュリティ タイムアウト手順が開始され、ユーザーにパスワード入力ボックスが表示されます。

ただし、FormShow()イベント中に何らかの理由でフォームにメッセージ ボックスが表示された場合 (ここで注意する必要があります。formShowイベントの実行はまだ完全には完了していません)、ユーザーはダイアログ ボックスの [OK] ボタンをクリックしないことにしました。ある時点で、セキュリティ コードが作動し、すべてのフォームを非表示にして、パスワードを要求できるようにします。このシナリオでは、 「OnShow または OnHide で Visible を変更できません」という例外がトリガーされます。

セキュリティ コードは、すべてのフォームを使用してループし、個別に使用TScreen.FormCountして非表示にします。TForm(TScreen.Forms[ii]).Hideこのフォームはまだロード手順を完全に完了していないと思うので、手順を非表示にすると例外が発生します。

テストを行ったところ、FormShow() イベントの実行後にメッセージ ボックスを表示すると、セキュリティ コードは問題なく機能し、すべてのウィンドウが問題なく非表示になりました。

Screen.Forms[ii].Visible、Screen.Forms[ii].Active など、フォームを非表示にする前に「if チェック」を実行するために、いくつかのプロパティとウィンドウ メッセージ チェックを試しましたが、今のところうまくいきません。上記のフォームは表示されますが、アクティブであるという保証はありません。アクティブな場合、他の非アクティブなフォームを非表示にするにはどうすればよいですか。だから私の質問は、どのプロパティまたは Windows メッセージが、フォームが完全に読み込まれたこと、または少なくともFormShowフォームに存在する特定のフォームのイベントを過ぎたことを示すTScreen.Formsでしょうか?

私が求めていることへの回答が必要です。セキュリティ コードに実装する必要がある一般化されたソリューションが必要です。この巨大なアプリケーションにある 1,000 を超えるフォームを調べて、個別に解決策を見つけようとすることはできません。これらのフォームには検証/警告ロジックが存在します。

ありがとうございました

4

2 に答える 2

3

簡単な答えはOnShow、所有者フォームのモーダル ダイアログの表示を停止することです。モーダル ダイアログを表示する前に、フォームの表示が終了するまで待ちます。その変更を行うと、その変更だけで、既存のコードが機能し始めます。

あなたが選んだ質問のタイトルは次のとおりです。

完全に初期化されていないウィンドウを非表示にすることはできません

したがって、明らかな解決策は、ウィンドウが完全に初期化されるまで待つことです。

これを実現する最も簡単な方法は、現在実行されているコードをOnShowのハンドラーに移動することCM_SHOWINGCHANGEDです。

procedure CMShowingChanged(var Message: TMessage); message CM_SHOWINGCHANGED;

次のように実装します。

procedure TMyForm.CMShowingChanged(var Message: TMessage);
begin
  inherited; // this is what invokes OnShow
  if Visible then
  begin
    // do what you previously did in OnShow
  end;
end;
于 2014-01-30T17:24:12.050 に答える
0

David Heffernanの解決策は私にアイデアを与え、私はこの問題を解決しました。

以下を作成しました。

const
  WM_SHOW_MESSAGE = WM_USER + 1;

private
  procedure WMShowMessage(var Msg: TMessage); message WM_SHOW_MESSAGE; 

コンストラクター内。

PostMessage(Handle, WM_SHOW_MESSAGE, 0, 0); 

そして、これにはメッセージボックスのロジックがあります:

procedure MyMethod.WMShowMessage(var msg: TMessage); message WM_SHOW_MESSAGE;
于 2014-01-30T20:16:50.263 に答える