MFCプログラミング(MDI)について教えてください。

1つのドキュメントに
複数の子ウィンドウ+子ビューのセットがあるとき、
特定のビューへのポインタの取得方法を教えてください。

ちなみに、ビューの種類は、

1.CViewの派生クラス
2.CFormViewの派生クラス

です。

MSDNを調べ回っった結果、

ドキュメントクラスのポインタから、
GetNextView(pos)を使って順番にビューを使うところまで来たのですが、その後が分かりませんし、
この方法の方向性自体の是非も良く分かりません。

ご指導よろしくお願いします。

POSITION pos = pDoc->GetFirstViewPosition();
while(pos != NULL)
{
CView* tmpView = pDoc->GetNextView(pos);
if(tmpView == ???????)........?????
}

A 回答 (1件)

1つのドキュメントにそのクラスのビューは1つだけ、という前提でよければ



CView* tmpView = pDoc->GetNextView( pos );
if ( tmpView->IsKindOf( RUNTIME_CLASS ( CTargetView ) ) {
...
}
    • good
    • 0
この回答へのお礼

遅くなってすみません。

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

お礼日時:2001/08/01 10:15

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aと関連する良く見られている質問

Q基本クラスポインタ = new 派生クラス[i];

基本クラスのポインタ変数pbaseを宣言し、new演算子にて派生クラスの配列を動的に確保して、pbaseに代入した場合、delete[] pbaseは上手く動作するのでしょうか。
(Aのデストラクタは仮想関数にしてあるとしておきます)

------ex-start------
class A {};
class b:public A{};

main()
{
  A * pbase
  pbase = new B[5];
  delete[] pbase
}
------ex-end------

例えば、
class Aは12バイト
class Bは20バイト
である場合、配列のサイズが違うのに、delete[]でちゃんと開放されるのでしょうか。
それともnew/deleteは確保したサイズをシンボル毎に記憶しているのでしょうか。
どうもこの辺が曖昧で実装する時にあやふやになってしまいます。どなたかお知恵をお貸しくださいませ。

Aベストアンサー

struct A { int x; virtual ~A() { cout << "~A: " << this << endl; } };
struct B: A { int y; ~B() { cout << "~B: " << this << endl; } };
B *b = new B[5];
A *a = b;
A *a2= a + 2;
a2->x = 1;
delete[] a;
これを素朴に考えると a2 は単純に a に 2 * sizeof(A) バイト足した場所(b[1] と b[2] の中間ぐらい?)を指すかもしれないです。a2->x = 1 は危険な感じがします。
delete [] が、配列の各要素のデストラクタに渡す this を求めるときに同様の失敗をするかもしれないです。

…と今日まで思っていましたが、実際やってみると delete[] で new B[5] が削除できてしまいました(VC++6.0)。不思議です。

Q基本クラスのポインタで、派生クラスのメンバ関数を呼び出す方法?

VC++でプログラミングをしています。
A(基本クラス)
B(派生クラス)
を作成しました。Bは、Aの特別な場合です。

このとき、基本クラスAのポインタから、派生クラスBにのみあるメンバ関数を呼ぶことはできないのでしょうか?

基本クラスAにも同じ名前の関数があれば、仮想関数をオーバーロードすれば呼び出せるようですが、この関数は、基本クラスには不要なので、できれば使わないメンバ関数を基本クラスに書きたくありません。
(純粋仮想関数という方法もあるようですが、)

操作としましては、
Aのポインタ配列 A* a[100]を作成し
特別な場合のみ派生クラスBのメンバ関数だけを実行させたいのです。
派生クラスにのみあるメンバ関数を、Readとします。

for(i=0;i<100;i++){
if(派生クラスBの場合){
a[i]->Read()
}
}

現状では、コンパイルエラーで、
関数Readは、aのメンバ関数ではありませんとなってしまいます。
以上よろしくお願いします。

Aベストアンサー

>この関数は、基本クラスには不要なので、
>できれば使わないメンバ関数を基本クラスに書きたくありません。

その動機付けがよくわからないのですが、もう少し具体的な話があれば補足にどうぞ。


>for(i=0;i<100;i++){
> if(派生クラスBの場合){
>  a[i]->Read();
> }
>}

これだけ見ると、基底クラス A に何もしない仮想関数 A::Read() を用意して、
これを派生クラス B でオーバーライドすれば if 文不要で

for ( i = 0 ; i < 100 ; i++ ) {
 a[i]->Read(); // a[i] が派生クラス B を指すときのみ Read()が意味のある処理をする
}

となるから、そちらの方が(効率はさておき)優れていると思いますけど。

Q基本クラスのポインタから、特定の派生クラスのメンバ変数を変更する方法?

VC++でプログラミングをしています。
A(基本クラス)
A1, A2, A3, ...(派生クラス)
を作成しました。A1,A2,A3, ...は、Aの派生クラスです。

このとき、基本クラスAのポインタから、特定の派生クラスにのみ存在するメンバ変数m_dataのみ変更したいのですが、存在するかどうかをどのように判定して、値を変更すれば良いでしょうか?

できれば、下記のような構造でループできるとありがたいです。

A* a[100]
(その後、a[100]に、派生クラスA1,A2,A3,..を割り当て、
 それらが、混在しているとします。)

for(i=0 ; i<100 ; i++){
if(a[i]->m_dataが存在する場合){ (2)
  a[i]->Set_m_data("m_dataの新しい値") (1)
 }
}

(1)は、a[i]->m_data = "m_dataの新しい値"
でも良いです。

現状では、m_dataがメンバでない派生クラスがあるので、
(2)のif文の判定自体ができず困っています。

よろしく御願いします。

VC++でプログラミングをしています。
A(基本クラス)
A1, A2, A3, ...(派生クラス)
を作成しました。A1,A2,A3, ...は、Aの派生クラスです。

このとき、基本クラスAのポインタから、特定の派生クラスにのみ存在するメンバ変数m_dataのみ変更したいのですが、存在するかどうかをどのように判定して、値を変更すれば良いでしょうか?

できれば、下記のような構造でループできるとありがたいです。

A* a[100]
(その後、a[100]に、派生クラスA1,A2,A3,..を割り当て、
 それらが、混在しているとし...続きを読む

Aベストアンサー

言語仕様的はメンバ変数の存在を確認する方法は無いです。
(処理系依存でも良いならば全く無いわけではありませんが…)

よって別のアプローチで
(1)仮装関数を利用して別個に処理させる
class A{
public:
   virtual Set_m_data(M_DATA &Adata){
      //何も入れない。空の処理
   }
};

class A1{ //メンバ無し
public:
   //何も作らない
};

class A2{ //メンバ有り
private:
   M_DATA m_data;
public:
   virtual Set_m_data(M_DATA &Adata){
      m_data = Adata;
   }
};
//代入処理
for(i=0 ; i<100 ; i++){
   a[i]->Set_m_data(m_dataの新しい値);//チェックする必要もない
}


(2)基底クラスAにm_data型のポインタを用意してそれで判別
class A{
public:
   M_DATA *pm_data:
   A(){//コンストラクタ
      pm_data = NULL; //NULLならばデータ無し
   }
};

class A1{ //メンバ無し
public:
   //何も作らない
};

class A2{ //メンバ有り
private:
   M_DATA m_data;
public:
   A2(){//コンストラクタ
      pm_data = &m_data; //NULLでない場合はデータ有り
   }
};


//代入処理
for(i=0 ; i<100 ; i++){
   if(a[i]->pm_data){//ここがNULLならばメンバ無しと判定できる
      *(a[i]->pm_data) = m_dataの新しい値; //そのまま代入も可能
   }
}

言語仕様的はメンバ変数の存在を確認する方法は無いです。
(処理系依存でも良いならば全く無いわけではありませんが…)

よって別のアプローチで
(1)仮装関数を利用して別個に処理させる
class A{
public:
   virtual Set_m_data(M_DATA &Adata){
      //何も入れない。空の処理
   }
};

class A1{ //メンバ無し
public:
   //何も作らない
};

class A2{ //メンバ有り
private:
   M_DATA m_data;
public:
   virtual Set_m_data(M_DATA &Adata){
      m_d...続きを読む

QCwndクラスの派生クラスmCWndクラスのOnDrawについて

OnDraw関数が呼び出しされていません。
どうすればいいですか?
よろしくお願いします。
class mCWnd :public CWnd
{
public:
DECLARE_MESSAGE_MAP()
afx_msg void OnLButtonDown(UINT nFlags,CPoint point)
{
AfxMessageBox("子ウインドウ");
CDC *pDC=GetDC();
pDC->TextOut(0,0,"HELLO");
ReleaseDC(pDC);
Invalidate();
}
virtual void OnDraw(CDC* pDC)
{
AfxMessageBox("OnDraw");
pDC->FillSolidRect(CRect(0,0,300,300),RGB(255,255,255));
}
};
BEGIN_MESSAGE_MAP(mCWnd, CWnd)
ON_WM_LBUTTONDOWN()
END_MESSAGE_MAP()
-------------------------------------------
//***View.cpp
(mCWnd cw)
void CKoDlg::OnBnClickedButton1()
{
CRect rect=CRect(50,50,190,250);
cw.Create(NULL,"Hello",WS_CHILD|WS_VISIBLE,rect,this,5000,0);
// TODO : ここにコントロール通知ハンドラ コードを追加します。
}

OnDraw関数が呼び出しされていません。
どうすればいいですか?
よろしくお願いします。
class mCWnd :public CWnd
{
public:
DECLARE_MESSAGE_MAP()
afx_msg void OnLButtonDown(UINT nFlags,CPoint point)
{
AfxMessageBox("子ウインドウ");
CDC *pDC=GetDC();
pDC->TextOut(0,0,"HELLO");
ReleaseDC(pDC);
Invalidate();
}
virtual void OnDraw(CDC* pDC)
{
AfxMessageBox("OnDraw");
pDC->FillSolidRect(CRect(0,0,300,300),RGB(255,255,255));
}
};
BEGIN_MESSAGE_MAP(mCWnd, CWnd)
ON...続きを読む

Aベストアンサー

OnDrawは、CWndではなくてCViewクラスのメンバです。
WM_PAINTメッセージのハンドラOnPaintに書いてみてはどうでしょう?

Q親クラスのポインタ、クラスを指定しないポインタ

親クラス A (抽象メソッドX、Yの2つを持つ) と
子クラス B-1 (親はA、抽象メソッドX、Y、Zの3つを持つ)
子クラス B-2 (親はA、抽象メソッドX、Y、Wの3つを持つ)
のように、子クラスでポリモーフィズムを実現しているとき、

クラスC
  「実行時に、iniファイルに(1)と書かれていたら、B-1のクラスで実体化し、
  iniファイルに(2)と書かれていたら、B-2のクラスで実体化する」
 というクラスを作りたいです。

////////////////////////////////////////////////////////////////

質問(1)
その際、クラスCは、どうやってもZのメソッドや、Wのメソッドは書けない認識です。
(メソッド名もiniファイルから取るようにすれば別でしょうが。)
この認識であっていますでしょうか?

質問(2)
逆に、XとYについては、それぞれ挙動の違う処理を行わせることができる認識です。
(クラスCで、親クラスAのポインタ型の変数を用意しておき、
 そのポインタに、DLLのインスタンス化したものをいれておけば、
 メソッドXとYについては実行可能という認識です)

親クラス A (抽象メソッドX、Yの2つを持つ) と
子クラス B-1 (親はA、抽象メソッドX、Y、Zの3つを持つ)
子クラス B-2 (親はA、抽象メソッドX、Y、Wの3つを持つ)
のように、子クラスでポリモーフィズムを実現しているとき、

クラスC
  「実行時に、iniファイルに(1)と書かれていたら、B-1のクラスで実体化し、
  iniファイルに(2)と書かれていたら、B-2のクラスで実体化する」
 というクラスを作りたいです。

////////////////////////////////////////////////////////////////

質問(1)
その...続きを読む

Aベストアンサー

> その際、クラスCは、どうやってもZのメソッドや、Wのメソッドは書けない認識です。

dynamic_castでは解決にならんですか?

> 逆に、XとYについては、それぞれ挙動の違う処理を行わせることができる認識です。

こんなこと訊くまでもないでしょう。やってみりゃわかる。


#include <iostream>

using namespace std;

class A {
public:
virtual void x() =0;
virtual void y() =0;
};

class B1 : public A {
public:
virtual void x() { cout << "B1::x()\n"; }
virtual void y() { cout << "B1::y()\n"; }
virtual void z() { cout << "B1::z()\n"; }
};

class B2 : public A {
public:
virtual void x() { cout << "B2::x()\n"; }
virtual void y() { cout << "B2::y()\n"; }
virtual void w() { cout << "B2::w()\n"; }
};

class C {
public:
A* create(int n) {
A* result;
switch ( n ) {
case 1: result = new B1(); break;
case 2: result = new B2(); break;
default: result = nullptr; break;
}
return result;
}
};

void test(A* p) {
p->x();
p->y();
B1* p1 = dynamic_cast<B1*>(p);
if ( p1 ) p1->z();
B2* p2 = dynamic_cast<B2*>(p);
if ( p2 ) p2->w();
}

int main() {
C c;
A* p;
p = c.create(1);
test(p);
delete p;
p = c.create(2);
test(p);
delete p;
}

> その際、クラスCは、どうやってもZのメソッドや、Wのメソッドは書けない認識です。

dynamic_castでは解決にならんですか?

> 逆に、XとYについては、それぞれ挙動の違う処理を行わせることができる認識です。

こんなこと訊くまでもないでしょう。やってみりゃわかる。


#include <iostream>

using namespace std;

class A {
public:
virtual void x() =0;
virtual void y() =0;
};

class B1 : public A {
public:
virtual void x() { cout << "B1::x()\n"; }
virtual void y() { cout << "B1::y()...続きを読む


人気Q&Aランキング

おすすめ情報