1

メイン フォームに TPageControl を持つアプリがあります。ページコントロールにはいくつかのタブがあります。アプリはトレイ アイコンに最小化できます。しばらく最小化して実行した後、(トレイ アイコンを右クリックして) メイン ウィンドウを復元すると、最後に表示されていたタブが表示されますが、他のタブを選択できません。

別のタブをクリックすると、そのタブがアクティブなタブのように見えるように外観が変わります (つまり、タブ自体がタブの行の先頭に移動します) が、タブの本体は元のままです。他のタブを選択するためのメニュー項目とショートカット キーもあり、それらは同じように動作します。Alt-O (オプション) を入力すると、上部のオプション タブがアクティブになりますが、そのタブの本体に何が表示されているかわかりません。他のタブの内容はまだ表示されています。

別のタブをクリックするとフォーカスが最初のタブから移動し、そのタブをクリックすると元に戻ることを確認しました。

動作が発生するまでに時間がかかるため、動作が特定のタブに限定されているかどうかはまだ確認していません.

何か案は?

アップデート

興味深いメモ。このような状況で問題が発生することを確認しました。アプリが起動し、トレイに最小化されます。アラート状態が検出され、ウィンドウがポップアップ表示され、メイン ウィンドウが復元されます (これはアプリの意図した動作です)。この時点で障害が観察されます。つまり、他のタブをクリックしても表示されません。

  • アプリを起動します。タブ 1 が表示されます
  • アプリを最小化します。トレイへ
  • ポップアップが表示されるのを待ちます。メインフォームが復元されます
  • Tab 2 FAULT OBSERVED をクリックします (Tab 2 本体は表示されません)。
  • TWinControl.CreateHandle にブレークポイントを設定
  • タブ 3 - 休憩をクリックします。
  • 実行 - タブ 3 本体を表示しない
  • タブ 1 をクリック - 壊れません
  • タブ 3 をクリック - 壊れません
  • タブ 4 をクリック - 改行
  • 実行 - タブ 4 本体を表示しません
  • タブ 1、2、3、4 をクリック - 壊れません

そのため、タブは最初にクリックされたときにハンドルを作成しているようで、その時点から、それらは存在すると考えられますが、表示されません。ポップアップが無効になっている場合、障害は観察されません。ポップアップは Application.OnIdle タスクからトリガーされます。

別の更新: いくつかの進歩。ウェブをいじった後、いくつかの変更を加えました。

次のコードを削除しました。

procedure RestoreMainWindow ;

begin
MainForm.WindowState := wsNormal ;
MainForm.visible := true ;
Application.Restore ;
Application.BringToFront ;
ShowWindow (Application.Handle, SW_SHOW) ;  { show the taskbar button }
end ;

そしてそれを次のように置き換えました:

procedure RestoreMainWindow ;

begin
MainForm.Show () ;
MainForm.WindowState := wsNormal ;
Application.BringToFront () ;
ShowWindow (Application.Handle, SW_SHOW) ;  { show the taskbar button }
end ;

私は削除しました:

procedure TTADMainForm.SendToTray (Sender: TObject) ;

begin
MainForm.visible := false ;
ShowWindow (Application.Handle, SW_HIDE) ;  { hide the taskbar button }
end ;
...
Application.OnMinimize := SendToTray ;    

そしてそれを次のように置き換えました:

procedure TTADMainForm.ApplicationEvents1Minimize(Sender: TObject) ;

begin
Hide();
WindowState := wsMinimized ;
TrayIcon1.Visible := True;
end ;

問題は解決したようです。でも。これで、起動後にアプリを最小化できます。ポップアップが発生してモーダルに表示され、メイン フォームが表示され、すべてのタブが表示されて機能します。しかし。フォームを再び最小化することはできません。OnMinimize ハンドラーは、初回以降はトリガーされません。ぐらぐら。

なぜそれが機能するのか、今でも理解できません。これは少し心配です。そして、どうすればそれを再び最小化できますか??

4

1 に答える 1

3

5年前の記憶から完全に作業していますが、次のようになります。

TPageControl は、その中のページごとに異なるウィンドウ ハンドルを使用します。タブ バーは独自のウィンドウ ハンドルであり、TPageControl はタブの変更をリッスンし、対応するページの非表示/表示を行います。したがって、タブをクリックしてタブがパックの先頭にジャンプすると、TPageControl は現在のページ ウィンドウを非表示にして、選択したタブに対応するページ ウィンドウを表示することになっています。

通常、VCL コントロールは、実際に必要になるまで、たとえば実際に表示されるまで、ウィンドウ ハンドルを作成しません。これにより、ウィンドウ ハンドルの消費が削減されます。Windows 3.1 と Win95 では非常に重要ですが、今日の NT ベースの 32 ビット OS ではそれほど重要ではありません。

リソースの負荷と起動時間を最小限に抑えるために、TPageControl は、コントロールの作成時にすべての非表示ページのウィンドウ ハンドルを作成しません。ページ ウィンドウ ハンドルは、最初に表示されるときに作成されます。

タブがクリックされたときにページが描画されない理由には、いくつかの可能性があります。

  1. GDI ウィンドウ ハンドル プールを使い果たしています。16ビットのWindows OSを使用していない限り、ほとんどありません。(Win 3.1 または Win95)
  2. アプリがスワップ ファイルにスピルし、ハード ディスクをスラッシングする原因となるメモリ リーク。アプリはほぼ停止し、フリーズしたように見え、時々 UI アクティビティが発生します。
  3. メッセージ ループのないバックグラウンド スレッドでウィンドウ ハンドルが作成されています。バックグラウンド スレッドで何かを実行していますか? バックグラウンド スレッドで VCL コントロールに触れると、ウィンドウ ハンドルが途中で作成される可能性があり、ウィンドウ ハンドルは作成されたスレッドにバインドされます。そのスレッドにメッセージ ループがない場合、そのウィンドウ ハンドルはメッセージをまったく受信しないため、画面に描画されません。

No. 3 があなたの犯人である可能性が最も高いです。では、そのバックグラウンド スレッドで何をしているのでしょうか。;>

于 2010-07-13T23:51:04.173 に答える