- ベストアンサー
MFC:MDIにおけるビューのアクティブ化
- タブドキュメント形式でMDIアプリを作っているのですが、複数ドキュメントがある際にプログラムから任意のビューを安全にアクティブ化させる方法がわからずに困っております。
- CMainFrameのSetActiveViewメソッドを使用すると指定したビューがアクティブになり所望の動作になるのですが、ドキュメントをクローズする際にアクティブ化を解除しているアクティブ化コンテキストは最近アクティブ化されたものではないという例外が発生します。このような状況に遭遇しない方法を探っていますが、適切な使用タイミングがつかめずに困っています。
- ご教授いただければ幸いです。
- みんなの回答 (7)
- 専門家の回答
質問者が選んだベストアンサー
ちょっと今環境がないのでテストしていませんが これでどうでしょうか? http://rararahp.cool.ne.jp/cgi-bin/lng/vc/vclng.cgi?print+200302/03020076.txt
その他の回答 (6)
- okdummy002
- ベストアンサー率0% (0/1)
質問主です。 修正ですが、ドキュメントを閉じるときというよりは、複数のドキュメントを開いている状態で、前記した方法でアクティブ化を行い、「アプリケーション自体」をクローズボタンなどから終了したときに例外が出ます。 MDIアプリのスケルトンをタブドキュメントスタイルで作り、同様にやってみて同じ例外がアプリケーション終了時に出るので、他の実装の影響ではないようです。 ドキュメントが作成された時点でアクティブ化が一度行われるので本質的に必要のない目的のように思われますが、タブをクリックしたときのOnActivateViewの呼び出しタイミングをエミュレートしたいときにはプログラマティックに行えなければやはり不便かなと思います。
お礼
dummy
- okdummy002
- ベストアンサー率0% (0/1)
質問者です。 アクティブ化がうまくいくのはMDIActivateではなくSetActiveView関数でした。度々の誤記申し訳ないです。
お礼
dummy
- okdummy002
- ベストアンサー率0% (0/1)
質問者です。 とりあえず別の方針で所望の挙動を実装してみました。 1.ドキュメントテンプレートからドキュメントを列挙 2.各ドキュメントから対応するビューを取得 3.ビューに任意の排他制御処理を記述 という感じで回避できました。 もしMFCクラスが持っている関数などで対応できる解があった場合、ご回答いただければ幸いです。
お礼
dummy
補足
前記のとおりCMDIFrameWndが持つMDIActivateはビューを有効化するという目的だけは果たすのですが、ドキュメントクローズ時に例外が出てしまうので使うタイミングが難しいという感想です。 タブスタイルドキュメントを用いている場合に限る話ですが、どのタイミングでビューをプログラマティックに有効化すれば安全にドキュメントのクローズが出来るのかは知りたいところなので、もしご存知の方がおられましたら、ご回答いただければ幸いです。
- okdummy002
- ベストアンサー率0% (0/1)
質問者です。別アカで補足します。 前記補足でビューがアクティブかされたときにOnMDIActivateという仮想関数が呼ばれると記述したのですが誤りで、OnViewActivateでした。
お礼
dummy
- 5S6
- ベストアンサー率29% (675/2291)
それってアクティブにするハンドルを間違っていませんか?
お礼
ご回答ありがとうございます。
補足
CMainFrame::SetActiveView関数にはCWnd*を引数として渡すようになっていますがこのポインタの指しているインスタンスがCView派生のものではいけないということになるのでしょうか?その点もいろいろ試しまして、ビューの親ウィンドウなどを渡したりしてみたのですがうまくはいきませんでした。
- 5S6
- ベストアンサー率29% (675/2291)
最近開発から離れていて、自宅に開発環境ないので曖昧だけど SetActiveViewでなくSetFocusを使ってはいかがですか? SetFocusとSetActiveViewはキー入力する場所になります。 正確にはちょっと違うけどどうでしょうか? またはMFC使わずAPIを直接呼ぶとか。 あとなぜOnCreateで呼んでいるのかはわかりません。 他にタイミング(メッセージ)はないのですか? 昔OnDrawでアプリケーションかを作ったことがあります。 どういったアプリケーションを作ろうとしていて、どんなどんな タイミングでアクティブにしたいのか教えてくれるとよりアドバイスしやすいですよ。
お礼
ご回答ありがとうございます。
補足
実はOnCreate以外にもいろいろ試しました。そしてタイミングはつかめていません。タブドキュメントになっているので、タブをクリックすると対応するビューがアクティブ化されるので、この挙動と同じ処理をAPIから叩ければいいのかもしれませんがよくわかっておりません。 あとSetFocusも試したのですがアクティブ化がなされませんでした。
お礼
ご回答ありがとうございます。
補足
上記リンクは私もGoogleから検索してみておりましたが、そのあたりはクラスのメソッド名から予測していろいろ試し済みのところでもありまして、うまくもいきませんでした。 で、今回のケースではタブによるMDI子ウィンドウの切り替えを行っています。タブを交互にクリックするとCView::OnMDIActivate仮想関数が正しく呼ばれ、そこで所望の処理を記述し、たとえば複数のCView間でどうしても1つのリソースを共有しなければならない場合などに排他処理のフラグを立てたりします。今回問題なのは新規ドキュメント生成直後に「新規ドキュメント以外も」有効化状態のままになってしまうというところでして、新規ドキュメント作成後に新しいタブとともにそれに対応したビューが表示されるのですが、それだけを有効化されたビューにしたいのです。 新規のドキュメントが生成されたときにも既存のビューのOnMDIActivateは呼ばれるようなのですが、どうも既存のドキュメントのOnMDIActivateが「無効化フラグ」付きで実行されないようで、タブをクリックしてドキュメントを切り替えたときのような動作をしてくれません。 つまり上にも書いたとおりタブをクリックしたときは正常に有効化ならびに無効化状態がトグルされるので、その挙動をプログラマティックにやりたいのです。