DocとViewの受け渡し

[戻る]
(^W^) 2010/03/10(水) 14:48:24
教えてください。MFCです。

View(正確にはListView)で持っている関数や値を
Docで使いたいのですがやり方はないでしょうか?

επιστημη [E-Mail] [HomePage] 2010/03/10(水) 16:24:13
それらは本来Docが持つべきもので、その見せ方をViewに任せたんじゃないでしょか。

(^W^) 2010/03/10(水) 17:14:45
そこを何とか実現させてみたいのです。
今調べたところ以下のようなやり方がありました。
POSITION poz = GetFirstViewPosition();
C***List* pView = (C***List*)this->GetNextView(pos);
そしてリストコントロールを得ます
CListCtrl& listCtrl = pView->GetListCtrl();

ですがデバッグしてlistCtrlの中を見ても取得されていませんでした。
どうしたら正確に入ってくれるでしょうか?

tetrapod 2010/03/10(水) 17:46:15
Doc/View の設計理念に反することをしようとしている、つまり、
本来すべきでないことをしたがっているわけなのだ。

MFC の設計思想に反してまでやらなきゃならない何らかの根拠がある?
単なる技術的興味?

俺としては View が Doc を見に/書きに行くように直すほうを強く推奨する。

ryo 2010/03/11(木) 00:21:02
とりあえず、DOCに対しVIEWは複数の可能性があるので
>C***List* pView = (C***List*)this->GetNextView(pos);
このpViewが、目的のVIEWである保証はない。
よって、目的のVIEWであるか確認すること。
ネット上で「GetFirstViewPosition」を知ったのなら
一緒に目的のVIEWかどうかの調べ方がでているはず。

(^W^) 2010/03/11(木) 09:22:56
tetrapodさん
>単なる技術的興味?
はい

ryoさん
>ネット上で「GetFirstViewPosition」を知ったのなら
>一緒に目的のVIEWかどうかの調べ方がでているはず。

一応調べてみたところ以下のようなやり方がありました
void *p;
C***List* pListView;
POSITION pos = GetFirstViewPosition();
p = GetNextView(pos);
pListView = (C***List*)p;

CListCtrl& listCtrl = pListView->GetListCtrl();

前回より少々良くなりましたがデバッグで見たところ
pListViewの中身に違うViewクラスが入ってしまってるみたいです。
またunused=???とよくわからないこともかかれています。
どこかおかしいところがありましたら教えていただけないでしょうか?

(^W^) 2010/03/11(木) 09:29:37
補足します
今上記のコードに
void *p,*p2;   
C***List* pListView;
POSITION pos = GetFirstViewPosition();
p = GetNextView(pos);
p2 = GetNextView(pos);    
pListView = (C***List*)p2;

CListCtrl& listCtrl = pListView->GetListCtrl();

ともう一つViewを取得したところうまくC***Listクラスが入っていました
なぜなんでしょうか?ちなみに
p = GetNextView(pos);
にはTreeViewのクラスが入っていたようです

aetos 2010/03/11(木) 10:44:12
> DOCに対しVIEWは複数の可能性がある

このためです。

その Document に対する View が複数あり、2つ目の View が目的のものだったというこ
とでしょう。
ただし、常に必ず2つ目の View が目的のものだとは限りません。

επιστημη [E-Mail] [HomePage] 2010/03/11(木) 11:11:47
>> 単なる技術的興味?
> はい

んー...僕だったら UpdateAllViews() 使って
「ListCtrl持ってる奴ぁ手ぇ挙げろー」
てやっちゃうかなー。

仲澤@失業者 2010/03/11(木) 11:32:05
あんまりお勧めはしませんが、どうしてもやりたいなら、

  Doc      = Template->CreateNewDocument();
  NewFrame = Template->CreateNewFrame(pDoc, NULL);

した後に、

  while(1){
    Frame = GetActiveFrame();
    View  = Frame->GetActiveView();
    if( View->IsKindOf( RUNTIME_CLASS(「ビュークラス名」)){
      Doc->SetYourFrmae( Frame); // Docにフレームポインタを設定
      Doc->SetYourView( View);   // Docにビューポインタを設定
      break;
    }
  }
とかすれば、Viewだろうが、Frameだろうが
好きにできますよねぇ(笑)。

ryo 2010/03/11(木) 12:25:31
>一応調べてみたところ以下のようなやり方がありました
全然違う。
これじゃ、「なんのVIEWかわからないまま、気にせず型変換してる」だけ

で、色々書こうと思ったがほとんど答えがでてるのでいいや

しかし、
「TreeView」がいきなり出てきたな・・・

aetos 2010/03/11(木) 12:33:15
エクスプローラスタイルなんでしょうね、たぶん。

(^W^) 2010/03/11(木) 14:27:12
aetosさん

>ただし、常に必ず2つ目の View が目的のものだとは限りません。

これは困りましたね。あらかじめ2つ目のViewが目的のものとすることは出来るのでしょ
うか?

επιστημηさん

UpdateAllViews() を使ってView間を制御出来るみたいですね。
調べて使ってみます。

bun 2010/03/11(木) 14:47:51
>これは困りましたね。あらかじめ2つ目のViewが目的のものとすることは出来るのでし
ょうか?
基本的に何番目のビューとか意識しないのがDoc-Viewの考え方です。

ドキュメントからビューに要求を出したいときは、
UpdateAllViews()で全てのビューに要求を一斉送信。
「ビューよお前に任せた」
「必要なデータは俺のところへ取りに来い!」
みたいな感じです。

ビューの側では、UpdateAllViews()の応答で OnUpdate()が呼ばれますので、
ビューが自分で判断して必要なら処理するだけです。

επιστημη [E-Mail] [HomePage] 2010/03/11(木) 17:10:40
> UpdateAllViews() を使ってView間を制御出来るみたいですね。

てか、UpdateAllViewsの目的はその名のとおり、
「俺(Doc)の状態/値が変化した。
 おまえら(AllViews)が俺の状態/値に依存する見てくれを持っているなら
 俺の状態/値を反映(Update)せよ」です。

目的はそーなのですが、これを悪用(?)し、
「だれかいるぅ? いたらなんかしておくれー」と
Viewが何かをするきっかけを与えるだけにとどめるす。

で、

#define LISTCTRLくれ 100

class Doc : public CDocument {
  CListCtrl* ctrl_;
public:
  void setListCtrl(CListCtrl* p) { ctrl_ = p; }
private:
  void ListCtrlがほしくなった() {
    ctrl_ = 0;
    UpdateAllViws(0,LISTCTRLくれ);
    if ( ctrl_ != 0 ) {
      ctrl_ を使う
    }
  }
};

class XXXView : public CXXXView {
  void OnUpdate(CView*, LPARAM lHint, CObject*) {
    if ( lHint == LISTCTRLくれ ) {
      GetDocument()->setListCtrl(俺の持ってるCListCtrl);
    }
  }
};

とかなんとか。

デゴルガン 2010/03/11(木) 19:13:16
pView = GetNextView(pos) をループで回して、
pView->IsKindOf(RUNTIME_CLASS(CxxxView)) でビュークラスを判断することができる
よ。

(^W^) 2010/03/12(金) 08:48:49
[[解決]]
皆様、適切な回答をありがとうございます。
皆様から頂いた回答はとても役に立ちました。
仲澤@失業者さん
επιστημηさん
コードまで書いていただいてありがとうございます。
頂いたコードは自分のノートにメモしておきました。

解決しときますね

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