ShowInTaskbarプロパティとOwnerDrawについて
FormのShowInTaskbarプロパティを変更するとハンドルが変わるそうです。その為かTabControlでOwnerDrawしている部分がShowInTaskbarプロパティを変更した途端にOwnerDrawができなくなります。
多分TabControl以外のコントロールでも同じ現象が発生すると思いますが、今回はTabControlについて四苦八苦した結果をメモっておきます。
TabControlでDrawModeプロパティをTabDrawMode.OwnerDrawFixedにすることによりDrawItemイベントを発生させますが、FormのShowInTaskbarプロパティを変更するとDrawItemイベントが止まります。よってOwnerDrawができなくなります。
このDrawItemイベントを再開させるにはDrawModeプロパティを一度TabDrawMode.Normalに設定し再度TabDrawMode.OwnerDrawFixedに戻します。
TabControlのインスタンスを全て把握できている場合にはShowInTaskbarプロパティ変更時にDrawModeプロパティも制御すれば問題解決となりますが、そんなに簡単な構造ならば苦労はしません。やはりShowInTaskbarプロパティが変更された事をキャッチしDrawModeプロパティを制御したいものです。
そこでTabControl側でFormのHandleCreatedイベントを拾うようにします。ShowInTaskbarプロパティが変更されるとハンドルが変わってしまうのでForm側でHandleDestroyedイベントとHandleCreatedイベントが発生します。このHandleCreatedイベントが発生した時にDrawModeプロパティを制御すればShowInTaskbarプロパティが変更されてもOwnerDrawが引き続き行われるようになります。
問題はTabControl側でどのようにFormのインスタンスを取得するかです。全てのコントロールを把握している状態ではFormのLoadイベントあたりでTabControl側にFormのインスタンスを渡すことができますが、そんなことを言っている場合ではないことが多いでしょう。私はそうでした。
TabControlがFormのインスタンスを取得するにはFindFormメソッドを使いますが、このFindFormメソッドを呼び出すタイミングが難しいのです。
正直TabControl側では自分がFormの中に格納されたタイミングがわかりません。Shownイベントなんかがあれば良いのですが、そのような気の利いたイベントもありません。
今回は邪道だとは思いつつコンストラクターでタイマーを仕掛けてFindFormメソッドでFormのインスタンスが取得できるまで気長に待機することにしました。タイマーイベントの優先順位は一番低いので恐らく始めのイベントでインスタンスは取得できるとは思いますが...
もっとスマートな方法でFormのインスタンスを取得できる方法をご存じの方が居ましたら、その方法を教えて頂けると助かります。
余談ですがShowInTaskbarプロパティをFalseにしてFormをTabPageなどに格納しタブ内に表示させようとするとタブから抜け出して親Formの上に張り付きます。これもまた不思議な現象です。
多分TabControl以外のコントロールでも同じ現象が発生すると思いますが、今回はTabControlについて四苦八苦した結果をメモっておきます。
TabControlでDrawModeプロパティをTabDrawMode.OwnerDrawFixedにすることによりDrawItemイベントを発生させますが、FormのShowInTaskbarプロパティを変更するとDrawItemイベントが止まります。よってOwnerDrawができなくなります。
このDrawItemイベントを再開させるにはDrawModeプロパティを一度TabDrawMode.Normalに設定し再度TabDrawMode.OwnerDrawFixedに戻します。
TabControlのインスタンスを全て把握できている場合にはShowInTaskbarプロパティ変更時にDrawModeプロパティも制御すれば問題解決となりますが、そんなに簡単な構造ならば苦労はしません。やはりShowInTaskbarプロパティが変更された事をキャッチしDrawModeプロパティを制御したいものです。
そこでTabControl側でFormのHandleCreatedイベントを拾うようにします。ShowInTaskbarプロパティが変更されるとハンドルが変わってしまうのでForm側でHandleDestroyedイベントとHandleCreatedイベントが発生します。このHandleCreatedイベントが発生した時にDrawModeプロパティを制御すればShowInTaskbarプロパティが変更されてもOwnerDrawが引き続き行われるようになります。
問題はTabControl側でどのようにFormのインスタンスを取得するかです。全てのコントロールを把握している状態ではFormのLoadイベントあたりでTabControl側にFormのインスタンスを渡すことができますが、そんなことを言っている場合ではないことが多いでしょう。私はそうでした。
TabControlがFormのインスタンスを取得するにはFindFormメソッドを使いますが、このFindFormメソッドを呼び出すタイミングが難しいのです。
正直TabControl側では自分がFormの中に格納されたタイミングがわかりません。Shownイベントなんかがあれば良いのですが、そのような気の利いたイベントもありません。
今回は邪道だとは思いつつコンストラクターでタイマーを仕掛けてFindFormメソッドでFormのインスタンスが取得できるまで気長に待機することにしました。タイマーイベントの優先順位は一番低いので恐らく始めのイベントでインスタンスは取得できるとは思いますが...
もっとスマートな方法でFormのインスタンスを取得できる方法をご存じの方が居ましたら、その方法を教えて頂けると助かります。
余談ですがShowInTaskbarプロパティをFalseにしてFormをTabPageなどに格納しタブ内に表示させようとするとタブから抜け出して親Formの上に張り付きます。これもまた不思議な現象です。
この記事に対するコメント