私はマルチスレッド TDI UI に取り組んでいます (興味がある場合は C1 DockingTabs を使用してください)。これまでのところ、各ウィンドウを個別のスレッドで開き、SetParent Win32 API を使用してウィンドウを適切なタブ内に配置することができました。また、モーダル ダイアログをタブ内にも表示し、他のタブの動作を妨げないようにすることもできました (ダイアログ フォームの Shown イベントにハンドラーを追加して、SetParent を再度呼び出すことにより、オンとオフの切り替えに多少手間がかかります)。タブ内のフォームの TopLevel ですが、機能します)。
ここで、少し厄介なことが起こっているのは、ダイアログが開いていることです。これにより、TDI 親フォームからフォーカスが削除され、フォーカスがすぐに戻されます。表示する前に SetParent を呼び出すと、親を持つフォームにモーダル ダイアログを表示できないため、例外が発生します。ウィンドウアニメーションのスライド/フェードインとフェードアウトを、タブ内に収まるまでサイズを 0,0 にすることで回避できましたが、フォーカスのフリックオフとバックを停止する方法がわかりません。メインの親フォーム。
2つの可能なアプローチがあると思います:
- フォーカスを失ったように見えるウィンドウ効果を無効にします(ウィンドウメッセージをブロックする可能性がありますか?)
- 実際にそれを止めてフォーカスを失う
これは少し変わったクエリであることに感謝します。助けていただければ幸いです。
編集:
演習のポイントを明確にするために、各タブが事実上独立しているタブ ベースの UI を用意しました。何かが ShowDialog を呼び出すたびに、その 1 つのタブだけでなくアプリ全体がブロックされるというエンド ユーザーからの苦情がありました。これを回避する唯一の方法 (Google Chrome のようなマルチプロセスを除く) は、各タブに個別の UI スレッドを提供し、タブ内にダイアログをロードして、ユーザーが引き続き他のタブにアクセスできるようにすることです。ハッキングの一部をある程度取り除くことができ、問題のほとんどを修正することができました (もう少しプレイしただけです)。メイン フォームで WM_NCACTIVATE メッセージをブロックすることで、私が尋ねた質問を実際に修正することができました。私は私だと思います アクティブ化するかどうかを決定するには、アクティブ化されたフォームがこのダイアログの子であるかどうかを検出する必要があります。解決しようとするちらつきもありますが、見た目はずっと良くなっています。コードを投稿しますが、関連するフォームが 3 つあるため、プロジェクトをアップロードしないと少し面倒です。誰かが興味を持っている場合は、それを減らすことができるかどうかを確認しますか?
私は現在、概念実証としてそれをいじっているだけです。これが機能するようになったら、既存のアプリケーションに改造する必要があります。そこから本当の楽しみが始まります! 私は TDI の側面を制御するためのフレームワークを持っているので、その点からはかなり単純なはずです。本当の悪夢は、本質的にスレッドセーフではない共有リソースがいくつかあるため、さまざまなスレッド間で発生する可能性のある同期の問題を解決するために全体を監査することです。