SDI上に複数のドキュメント、ビューを用意して動的切り替え – プログラミング – Home

SDI上に複数のドキュメント、ビューを...
 
通知
すべてクリア

[解決済] SDI上に複数のドキュメント、ビューを用意して動的切り替え


ZZZY
 ZZZY
(@ZZZY)
ゲスト
結合: 19年前
投稿: 6
Topic starter  

ZZZYと申します。VisualC++は初心者です。

環境:WindowsXP VisualStudio.net2003 MFC使用

SDIで複数のフォームを切り替えるアプリを考えています。
フォームの切り替え自体はできたのですが、切り替えたビュー側から対応するドキュメン
トを受け取ることが出来ません。(GetDocumentが失敗します)

CWinApp継承クラスのInitInstance()でドキュメントテンプレートへの追加は行っている
のですが、ドキュメントクラスの生成が行われていないようです。(デバッグでコンスト
ラクタが呼ばれない)

自分で追加したドキュメントクラスを生成させるにはどのようにしたらよいでしょうか?


引用未解決
トピックタグ
ITO
 ITO
(@ITO)
ゲスト
結合: 22年前
投稿: 1235
 

「SDI = SingleDocumentInterface」
なので通常、ドキュメントを追加することが出来ません。
「MDI = MultipleDocumentInterface」をアプリケーションウイザードで作成して、
「InitInstance()」の 「CMultiDocTemplate」に追加します。


返信引用
MASATO
 MASATO
(@MASATO)
ゲスト
結合: 20年前
投稿: 3
 

SDIの制約は、1つのフレームに1つのドキュメント、ということなので、
ドキュメントを追加することはできると思います。

フォームの切り替えを行っているところあたりに抜けがあるのではないかと思います。
切り替えを行っているところのコードを提示して頂けませんか?


返信引用
MASATO
 MASATO
(@MASATO)
ゲスト
結合: 20年前
投稿: 3
 

同時に1つのドキュメントしか開けない、という制約だったかもしれません。
どちらにせよ、複数のドキュメントを用意して切り替えることは可能だと思います。


返信引用
r
 r
(@r)
ゲスト
結合: 22年前
投稿: 48
 

ビュー入替については MSDN の COLLECT サンプルがありますね。
上記サンプルのビュー入替の処理途中に、

CRuntimeClass::CreateObject() で新規ドキュメントを作成する
CSingleDocTemplate::RemoveDocument() で古いドキュメントを破棄する
CSingleDocTemplate::AddDocument() で新規ドキュメントを登録する

という処理を加えればドキュメント入替もできそうですが...


返信引用
ITO
 ITO
(@ITO)
ゲスト
結合: 22年前
投稿: 1235
 

「SDI」には、元になるフレーム「CMDIFrameWnd」がないですよね。
でも、「CSingleDocTemplate::RemoveDocument()」も大丈夫なんですね。
とても参考になりました。
時間があるときに、試してみます。


返信引用
ZZZY
 ZZZY
(@ZZZY)
ゲスト
結合: 19年前
投稿: 6
Topic starter  

ITO様、MASATO様、r様

ご指導ありがとうございます。
私のコードでは、ドキュメントの生成、テンプレートのドキュメントの切り替えのコード
が抜けていました。そこが原因と思われます。

今から修正を行いたいと思います。
出来ましたら、またご報告させていただきます。

ありがとうございました。


返信引用
ZZZY
 ZZZY
(@ZZZY)
ゲスト
結合: 19年前
投稿: 6
Topic starter  

申し訳ございません。行き詰ってしまいました。

> CRuntimeClass::CreateObject() で新規ドキュメントを作成する
> CSingleDocTemplate::RemoveDocument() で古いドキュメントを破棄する
> CSingleDocTemplate::AddDocument() で新規ドキュメントを登録する

RemoveDocument(),AddDocument()の実行で行き詰っています。

これらの関数を実行するCSingleDocTemplateオブジェクトの生成が行えません。

CORRECTサンプルと同様にmainfrm.cpp内でビューの切り替え処理を行っています。また、
プロジェクト名.cpp(WinApp継承クラス)のInitInstanceでDocumentTemplateの登録
AddDocTemplate()を行っております。2種類のビュー、ドキュメントの切り替えを考えて
いるので、AddDocTemplate()を2回実行する形としております。(この方法が正しいかも
よくわかっておりません)
登録したドキュメントテンプレートのポインタを受け取るなどの方法があるのでしょう
か?MSDNでSingleDocTemplate,DocumentTemplateを調べてみたのですが、関数など見つ
かりませんでした。


返信引用
r
 r
(@r)
ゲスト
結合: 22年前
投稿: 48
 

>登録したドキュメントテンプレートのポインタを受け取るなどの方法があるのでしょう
>か?MSDNでSingleDocTemplate,DocumentTemplateを調べてみたのですが、関数など見つ
>かりませんでした。

CWinApp::GetFirstDocTemplatePosition()
CWinApp::GetNextDocTemplate()
で取得できます。
別の方法としては、アプリケーションクラスのメンバー変数として
CSingleDocTemplate* m_pDocTemplate;
などを作り、InitInstance()時にそこに代入しておくのでもいいです。

以下は補足。

通常の SDI では、起動時に CDocument 派生クラスオブジェクトと
CView 派生クラスオブジェクトを生成すると、
それ以後は終了するまでこれらのオブジェクトを使い続けます。
#[ファイル]-[新規]や[開く]の場合も Doc/View は破棄せず、
#起動時に生成したものを再利用します。
#結果、Doc/View のコンストラクタ、デストラクタは1回しか
#動きません。

おそらく、CWinApp 派生クラスの InitInstance() で
CSingleDocTemplate を生成するときに渡す Doc/View のランタイム情報が
参照されるのは起動時の1回限りで、その後はこのランタイム情報と
実際の Doc / View オブジェクトの種類が違っていたとしても問題なく
動作するのではないかと思われます。

ですので、AddDocTemplate() は起動時に表示したい Doc/View に関して
1つだけ行い、あとは Doc / View の差し替えだけすれば大丈夫なのでは
ないかと思います。

注)僕は実際にはそのようなことを試したわけではありませんし、
しっかり調査したわけでもありません。
従って、すべて想像の範囲でこの回答を書いているということを
ご承知ください。


返信引用
ITO
 ITO
(@ITO)
ゲスト
結合: 22年前
投稿: 1235
 

僕も「CORRECTサンプル」を見ましたが、「STATIC_DOWNCAST」マクロを使用したりし
て、手がこんでいます。
いきなり自分のプログラムに組み込むのでなく、よく確かめながら組み込んだほうが
いいです。
特に、「CMainFrame::OnExample(UINT nCmdID)」の中とかは、崩さずにまずそのまま
使ってみて、自信がついたとこから崩していくぐらいの慎重さが必要だと思います。
せっかくrさんに探していただいたサンプルなのでよくZZZYさんなりに調べたほうが
いいです。

 僕も、MDIのソフトを製作するとき、ウインドウの切替え部分とかは、サンプルを
そのまま引用しています。

実際に、SDIでウインドウを切替えるソフトを作ったわけではないのですみませんがこんなア
ドバイスしか出来ません。


返信引用
ZZZY
 ZZZY
(@ZZZY)
ゲスト
結合: 19年前
投稿: 6
Topic starter  

r様、ITO様、ご指導ありがとうございます。

r様に教えていただいたようにCSingleDocTemplate* m_pDocTemplateをメンバに用意し、
その値を切り替えを行うMainFrmで受け取れるようにしました。
その結果、ビューの切り替え、ドキュメントの切り替えが出来るようになりました。あり
がとうございます。

まだ細かい点(サンプルからコピーしている部分)などを詰めていかねばなりませんが、
皆様の丁寧なご指導により道が開けました。本当にありがとうございました。


返信引用

返信する

投稿者名

投稿者メールアドレス

タイトル *

プレビュー 0リビジョン 保存しました
共有:
タイトルとURLをコピーしました