MDIアプリケーションにおける同一ドキュメントにおける別viewの生成

[戻る]
Fortran使い 2005/08/12(金) 17:50:45
お世話になっております。
MFC、MDIアプリに関する質問です。(VC++.net2003)
ただいま、ひとつのデータをグラフ表示させてその処理結果を別view(別子ウインド)で
表示するプログラムを作成しています。

はじめにメニューに「データ処理」という項目をつけてこれのメッセージを受けて
別ウィンドを作りたいのですが明示的にインスタンスを生成するにはどうしたら
よいのでしょうか?ドキュメント・ビューアーキテクチャではドキュメントテンプレー
トに登録すれば明示的にインスタンスを生成する記述をしなくてもよくできてますが、
処理の結果を別ウィンドを生成して表示するにはどのようにすればよいのでしょうか?
CWinAppのOnFileNewなどを参考にすればよいのでしょうが(ソースってどこにあるんで
すか?)もともと明示的にやらなくてもできるようでしたらそちらでも教えてくださ
い。

次に、同じドキュメントに対して別viewを生成するときの話ですがドキュメントテンプ
レートを複数登録すれば可能であるとは聞いています。しかし、ダイアログでどちらの
テンプレートを使うか聞いてくるようですがスマートな回避の仕方はあるのでしょう
か?それから、この方法だと同一ドキュメントというのは同一クラスという意味でイン
スタンスは同一とできないのでしょうか?(STATICで値を共有するなど)ここら辺の疑
問はまだ経験がないための漠然とした不安ですので的外れでしたら余りつつかないでく
ださい。

アドバイスよろしくお願いします。

Fortran使い 2005/08/12(金) 20:35:03
2番目の質問は「[MSVC] MDI で子ウィンドウ新規作成時にテンプレート一覧を表示させ
ない」が見つかりましたので結構です。

Fortran使い 2005/08/12(金) 20:38:40
さらに

AppWizard ベースのアプリケーションでは、MDI 子ウィンドウの作成に MFC リファレン
スに記載されていない CMultiDocTemplate::OpenDocumentFile 関数を利用することがで
きます。 

もありました。調べてないわけではないですが慣れないもので。

Fortran使い 2005/08/12(金) 21:04:40
CXXXApp* pApp = (CXXXApp*)AfxGetApp();
pApp->pDocTemplate->OpenDocumentFile(NULL);

こんな感じで子ウィンド生成には成功しました。
しかし、ドキュメントのインスタンスを共有したり、
受け渡しをしたりしたいのですが。

miwa 2005/08/12(金) 22:37:16
OpenDocumentFile() で開いた新しいドキュメントに元ドキュメントのポインタを渡すっ
てのはどうでしょう。

CMainFrame* pMainFrame = (CMainFrame*)AfxGetMainWnd();
CMasterDoc* pDocMaster = pMainFrame->GetActiveDocument();
CXXXApp* pApp = (CXXXApp*)AfxGetApp();
CSlaveDoc* pDoc = (CSlaveDoc*)pApp->pDocTemplate->OpenDocumentFile(NULL);
pDoc->pDocMaster = pDecMaster;

みたいな感じになるかなぁ?(例として適当に書いてみただけで、試していません)

本当に共有するってことになると、共有に持ち込むこと自体は比較的容易にできそうな気
がするんだけど、
・子フレームを閉じるときにドキュメントがダーティな場合は保存ダイアログが出る
・子フレームの破棄とともにドキュメントは破棄される
・UpdateAllViews で関連するすべてのビューが更新される
など、もともとある処理を一方では無効にしたり、逆に一方にしか効かない部分を両方に
効くようにするなど、あっちこっちいじらないといけなくなって異様にややこしいことに
なりそうな予感。

Fortran使い 2005/08/12(金) 23:13:53
miwaさんのご意見を参考に以下のようにコードを組んで見ました。
CMainFrame* pFramWnd = (CMainFrame*)AfxGetMainWnd();
CXXXDoc* pDoc =
 (CXXXDoc*)pFramWnd->MDIGetActive()->GetActiveDocument();

CXXXApp* pApp = (CFukaDespApp*)AfxGetApp();
 
  CXXXDoc* pDocSL = (CXXXDoc*) pApp->pDocTemplate->OpenDocumentFile(NULL);
  pDocSL=pDoc;

うまく動かないですね。アクティブなフレームのドキュメントを取得したことがないの
でそこらへんも正しいのか自身がありません。

基本的に下から2行目のところでポインタを取得しつつウィンドを生成して最後の行
でオブジェクトを引き継いでるという形ですよね。

もうちょっといじってみようと思います。

Fortran使い 2005/08/12(金) 23:27:16
アプリケーションクラスでアクティブなフレームのドキュメントを取得して

pDocTemplate->CreateNewFrame(pDoc, NULL);

とやっても今度は子ウィンドの生成すらできません。
もうちょっとがんばってみます。

Fortran使い 2005/08/13(土) 14:11:03
[[解決]]
とりあえず同じview間でのドキュメントインスタンスの引継ぎはできました。

CMainFrame* pFramWnd =(CMainFrame*)AfxGetMainWnd();
CXXXDoc* pDoc =
 (CXXXDoc*)pFramWnd->MDIGetActive()->GetActiveDocument();

    CMainFrame* pNewFrame = (CMainFrame*)pDocTemplate->CreateNewFrame
(pDoc, NULL);
    if( pNewFrame )
        pDocTemplate->InitialUpdateFrame(pNewFrame, pDoc);

これはXXXAPPクラスからの記述です。
初心者なのでどのメンバ関数がどのクラスに属しているとかどのクラスからの派生だ
ということが概念としてはわかるのですがいざコーディングするとゴッチャになってし
まっていました。

あとは別viewなどですが大きな問題はなさそうです。
http://www.alpha-net.ne.jp/users2/uk413/vc/VCT_MDI1.html

miwaさんのやり方も考えとしては間違っていないとおもうので試してみたいと思いま
す。

一応解決ということで、ありがとうございました。

miwa 2005/08/13(土) 15:24:27
>あとは別viewなどですが大きな問題はなさそうです。

複数フレームからのドキュメント共有だとかなりややこしいことになりそうな気がしてい
たのですが、MFC はそういうのもある程度は想定した作りになっているみたいですね。
大丈夫かなぁ?、とちょっと気になってたフレーム破棄時のドキュメントの自動破棄も、
別のフレームが残っていたらドキュメント破棄はしないようですし。
(さっき CFrameWnd::OnClose() のソースコードをざっと見てみたら、そんな感じ)

MFC の柔軟性にはちょくちょく感動させられます。

あと、私が示した例については、おそらく、CView::OnInitialUpdate() 時にはドキュメ
ントへのポインタが未設定だったり、すんなりとは動かないところがあると思います。単
に基本的な考え方を示すのみで、細部は実際に作る人にお任せ、くらいのつもりで即興で
書き込んだメモみたいなものですから。(^^;

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