DockeblePaneに貼り付けたFormViewのOnInitialUpdate()

[戻る]
週休十日 2011/04/27(水) 17:30:51
お世話になっています。

Windows XP Professonal SP 3
Visual Studio 2008 VC++ MFC (APP - SDI)で開発をしています。

私はCDockeblePaneの派生クラスで生成したペイン(hogePaneとします)に
CFormView(hogeViewとします)を貼り付け、それをMainFrameにドッキングさせていま
す。

それで、hogeViewのOnInitialUpdate()でとある処理をしているのですが、
hogePaneのドッキング状態によってhogeViewのOnInitialUpdate()が
呼ばれたり呼ばれなかったりします。
具体的には
hogePaneをMainFrameにドッキングしている -> 呼ばれる
hogePaneをフローティングにしている -> 呼ばれない
という感じです。

hogePaneをフローティングにしている状態でもhogeViewの
OnInitialUpdate()が呼ばれるようにするにはどうしたらいいのでしょうか。

ご存知の方、どうぞご享受ください。

- - - - - - - - - - - - - - - - - 

・・・ちなみに、ちょっとデバッガで追ってみたところ
CWndクラスのSendMessageToDescendants()という
メソッドを使ってInitialUpdateメッセージを送っていて、その中で

void PASCAL CWnd::SendMessageToDescendants(HWND hWnd, UINT message,
    WPARAM wParam, LPARAM lParam, BOOL bDeep, BOOL bOnlyPerm)
{
    // walk through HWNDs to avoid creating temporary CWnd objects
    // unless we need to call this function recursively
    for (HWND hWndChild = ::GetTopWindow(hWnd); hWndChild != NULL;
              hWndChild = ::GetNextWindow(hWndChild, 
GW_HWNDNEXT))
    {
        // メッセージを送る処理...(省略)
    }
}

という処理をしているのですが、hogePaneがドッキングされている状態では
for文の
hWndChild = ::GetNextWindow(hWndChild, GW_HWNDNEXT)
で hogePane が取得され、貼り付けられている hogeView の OnInitialUpdate()が
呼ばれますが、hogePane がフローティングの状態では先ほどの GetNextWindow()
で hogePane が取得されず、その結果 hogeView の
OnInitialUpdate() が呼ばれません。

- - - - - - - - - - - - - - - - - 

どうか対応策をご享受ください。
よろしくお願いします。

仲澤@失業者 2011/04/27(水) 20:08:41
誤りを訂正させてもらいます(CDockeblePane -> CDockablePane)。

OnInitialUpdate()は「ポップアップしないチャイルド」しか探さないのですね(笑)。
いずれにしろ、hogePaneはどっかでインスタンスを作成しているはずなので、
その持ち主(たぶんフレーム)に代替処理をしてもらうしかないと思います。
もちろん、処理が重複しないようにフロート中だけにする必要があるでしょう。

ちなみに自分は、MDIチャイルドやViewがポップアップする可能性のある設計
の場合、InitialUpdateFrame()には頼らない、自前の方法で初期化するように
してますです(vv;)。

hirocco 2011/04/28(木) 14:23:50
まぁ,推理なんですけどね

MainFrameは存在しているCViewに対して初期化の為にメッセージを送ろうと
したんだけど, 兄弟っぽくなってるCドッカブルペインにも送っちゃうんで
しょうね
それを受け取って受け取っちゃった Cドッカブルペインが処理をしちゃった
感じぢゃないのかな?
実際,CドッカブルペインにはOnInitUpdateって無いですよね?
それがCFormViewを持ってるもんだから,一応メッセージは届いてるし, 動作
しちゃうんだと思いますよ

でも,それがCFormViewじゃない場合もあるわけで(例えばCTreeCtrlとかね),
その時の初期化はOnInitUpdateで初期化はしないですよね

VCの雛形を見ると初期化はCドッカブルペインの OnCreateでコチョコチョし
てるので,私はの場合はそれを大きくマネてますよwww

AR 2011/04/30(土) 11:50:55
 何名かの方も既に答えられていますが、私もフロートしているものは何らかの理由で
除外するものがあるものと考えて、OnInitialUpdate()に頼らない仕組みを組み込んでい
ます。
 基本的に親から作られるタイミングで初期化処理を呼んでいますが、起動速度を稼ぐ
場合はコマンド実行時(初期化が必要になった時)に初期化するようなこともしていま
す。

 初期化なども柔軟な発想で構築しても良いのではないかと思います。

ITO 2011/05/06(金) 19:12:22
うーーん、hiroccoさんと同意見ですね。
基本的に
  Create文で作成したウインドウは、OnCreateで初期化する。
でいいと思います。

例外はいろいろありそうです。

週休十日 2011/05/16(月) 08:48:02
[[解決]]
回答が遅れ、申しわけありません。

回答くださった仲澤@失業者さま、hiroccoさま、ARさま、ITOさま
ありがとうございました。

皆様の回答にある通り、hogeViewのOnInitialUpdate()での
初期化を見直し、CMainFrame内で初期化することにいたしました。

古いスレッドには追加発言できません。