Viewクラス以外でGetListCtrl()を使いたい

[戻る]
むかのさん 2007/10/01(月) 18:22:25
WindowsXPprofessional, VC++6.0, MFC, シングルドキュメントで作成しています。 

現在、CListViewのCItemViewクラスで、リストビューに関連付けられているリスト コン
トロールへの参照を取得するためにCListViewクラスのメンバ、GetListCtrl()を使って
リストビューの情報を取得しています。 

このGetListCtrl()を別のクラスの例えば自分で追加したクラス、CDialogのCItemDlgク
ラスで使用したいのですが、Viewクラスからどのように受け渡すなり、CDialogクラスで
使うようにするのでしょうか? 
現在CItemDlgクラスで使おうとすると「定義されていない識別子です」とエラーがでま
す。 

よろしくお願いします。

名無し 2007/10/02(火) 09:21:58
そのリストコントロールを持ってるウィンドウのハンドルさえ取れてれば
とれるんじゃないの?
たとえば

CListCtrl* CItemDlg::GetListCtrl()
{
  return ((CItemView*)GetParent())->GetListCtrl();
}

PATIO 2007/10/02(火) 15:31:00
> 現在CItemDlgクラスで使おうとすると「定義されていない識別子です」とエラーがでま
す。
これにかんしては言うまでも無く、CDialogクラスの派生クラスにそんな関数は無いから
当然ではないかと思います。で、使う以上はそのクラスをMSDNで調べるべきではないかと
思いますよ。MSDNにはそのクラスの派生元のクラスについても書かれていますから
その辺をきちんと見てまわれば、その関数が無いのはわかるはずです。

どうしても使いたいなら名無しさんが書かれているように自分で実装するしかないですね。
といいつつ、見ていて気がついたんですけれどGetListCtrl()って参照を返しませんか?
そのへんは実装する時に御自分で調べて見られたほうがよろしいかと思います。

名無し 2007/10/02(火) 16:04:41
>GetListCtrl
ほんとだ。失礼しました。

質問からははっきりしていないのだけど
CListViewのlistctrlじゃなくてまさかCDialogに貼り付けた
listctrlのハンドルを取得するGetListCtrl()がない、とか言ってませんよね・・?

むかのさん 2007/10/02(火) 20:44:28
派生クラスについてみてみたいと思います。自分で実装したいのですが、Viewクラスか
ら受け渡しとかはできないのですかね?初歩的ですいません。

ダイアログのリストビューのを取得するという意味ではないです。Viewクラスで表示さ
れているlistctrlの取得ですね。Viewクラス以外で使いたいという意味ですが…。わか
りずらい質問で申し訳ないです。

wclrp ( 'o') 2007/10/03(水) 00:54:26
俺の感覚で言わせてもらうと
クラスに渡すとかって曖昧なんだよな。

何のオブジェクト(インスタンス)の何メソッドが
何のオブジェクトの何メソッドで何したいのかって重要だと思う。

それが判らないと
渡せるか渡せないか
どうやって渡すのかなんて判りません。

だから勝手に決め付けて回答する。
メニューxxxが押されるとCItemView::OnClickXxxx()が呼ばれ
そこでモーダルダイアログを出し
そのモーダルダイアログでリストビューからの情報が欲しいと仮定する。

void CItemView::OnClickXxxx()
{
  CDialog dlg;
  dlg.m_pList = GetListCtrl();
  dlg.DoModal();
}

上記は渡し方の例として書いたのであって
正しく動くプログラムではありません。

PATIO 2007/10/03(水) 09:57:22
ダイアログにどういう機能を求めるのかによって
話が変わってきますけれど、私の場合はCListCtrlの制御は
View側の仕事であってダイアログの仕事では無いと思うので
単純にView上のデータの編集用ダイアログなら
ダイアログを表示する前にViewから必要な情報を取り出して
ダイアログに渡してしまい、ダイアログから戻ってきた時に
内容をViewに反映すると思います。
ダイアログとCListCtrlの間でデータのやり取りがしたいなら
View側にそれようのメンバー関数を作成してダイアログは
そのメンバー関数を通じてやり取りをするようにすると思います。
私の場合は基本的にダイアログにView内のものを直接弄らせるようには
しないと言うのがスタンスですね。
その良し悪しについては言及しませんけれど。

むかのさん 2007/10/08(月) 19:07:12
実行したいことはViewのリストで選択した行の行をチェックしてダイアログや印刷する
Printクラスに渡してその情報をつかってダイアログに表示したり、選択した行のデータ
を印刷するようにしたいですね。

ダイアログへはwclrp ( 'o')さんのを参考にしてみたいと思います。

ダイアログや印刷するクラスで選択した情報のみを印刷しなくてはいけないので渡るよ
うにしたいです。

PATIO 2007/10/10(水) 12:14:25
>ダイアログや印刷するクラスで選択した情報のみを印刷しなくてはいけないので
>渡るようにしたいです。

選択って複数行選択なんでしょうか?
単一行で良いなら選択された行のデータをリストコントロールから
取り出してデータのみをダイアログとかに渡すっていう方法は無しですか?
詳しいGUIの内容が分からないので何とも言いかねる部分では有りますけれど。

むかのさん 2007/10/10(水) 21:57:46
選択は単一行または複数行です。
Ctrlキー押しながら選択したランダムな行の情報などですね。

Viewクラスでは取得できるのですが、他の印刷するクラスとかダイアログのクラスで
GetListCtrl()が使えないでいます。

やはりViewクラスのを渡すしかないのでしょうか?

2007/10/11(木) 03:54:46
>やはりViewクラスのを渡すしかないのでしょうか?
リストコントロールを管理しているのがViewなので、リストコントロールの内容にダ
イアログからアクセスするならViewを経由する事になります。

どのような形でアクセスできるようにするかは、どのクラスがどんな役割を持ってい
る(持つべき)なのかを考えてみたほうがいいでしょう。
…本来ドキュメント/ビューの場合はビューは外見を管理するものでデータの保
持はドキュメントのほうが都合がいいのですが、ビューにコントロールを持たせてし
まうとそこにデータも全部入れることになったりでアウアウ…

あと、ダイアログを表示しながらビューの操作が出来るような設計の場合はダイア
ログに現在の選択に基づくデータを送るのはやめたほうが無難です。

>単一行で良いなら選択された行のデータをリストコントロールから
>取り出してデータのみをダイアログとかに渡すっていう方法は無しですか?
何らかの配列にして置けば良いだけなので、別に単一行に限らなくても良いと思
います。
が、モードレスダイアログだと都合が悪い可能性も…

名無し 2007/10/11(木) 09:13:45
素直にPATIOさんや麩のアドバイスの方法を取るが得策。
データ自体がどこにあるか知りませんが選択したデータを印刷するのに
Viewのリストコントロール本体を渡すべき理由が見当たりません。

データが渡せたなら必要に応じて渡し先のダイアログでリストを作成/表示/印刷すれば
いい
Doc/Viewが嫌なら

class CXXXData
{
private:
  CXXXData(){}
public:
...

friend CXXXData* theData();
}

CXXXData* theData()
{
  static CXXXData dt;
  return &dt
}

のようなインスタンスがひとつしかできない様な
グローバル変数でも作ればいいんじゃないかしら

PATIO 2007/10/11(木) 09:51:22
>が、モードレスダイアログだと都合が悪い可能性も…

私が知りたいのそこですね。
この辺のインターフェイスの話がついて来ないと
良いアドバイスは難しいです。

但し、私的にはViewの持ち物であるリストコントロールを
ダイアログに直接操作させるのはカプセル化とかモジュールの独立性から
考えるとあんまり良い手だとは思えません。
まあ、いずれにしてもDialogから直接Viewの持ち物である
リストコントロールを参照するのは無理で、
少なくともCListViewのポインタか何かを通してアクセスするか、
Viewでダイアログを生成する時にViewのリストコントロールを
取得してダイアログにポインタとして渡しておくかしないと
無理ですね。
この辺は、Windows云々と言うよりもC++言語レベルの話なので
もしどうしても納得できないならC++言語について書籍等で
確認されたほうが良いと思いますよ。

モードレスだったとしたら、私ならユーザー定義のウインドウメッセージと
PostMessageやSendMessageを使ってやると思います。
View側に受け口を設けておいてメッセージ経由でやり取りするようにします。
こうしておくとウインドウ間の結合が弱くなって色々とプログラミング上の
利便性が上がります。
こうする事でリストコントロールの操作その物はViewの内部に閉じ込める事が
できるのでダイアログは目の前のデータ処理だけに注力できるようになります。

2007/10/12(金) 22:57:06
定石かどうかは知りませんが。
私は、ListCtrlとか限定しませんが

・データクラス(単に構造体配列だったり)
・GUI表示クラス。ViewとかDialogにあたります。

の2個へ、必ず切り分けます。
そうすれば掲題のようなケースは、Viewからダイアログへは、
データを渡すのみで、データを受け取ったViewなり、ダイアログは
表示・データ操作だけに専念できます。
データのハンドリングはデータクラス内でみ行います。

経験則からデータの入れ物である"コントロール"を直接に、
やり取りするインターフェイスは後日必ず破綻しますんで・・・。

2007/10/12(金) 23:03:19
と異口同音でみなさん仰ってるようで^^;

むかのさん 2007/10/24(水) 20:20:52
[[解決]]
返事が遅くなりまして大変申し訳ありません。

クラスはきちんと分けて、Viewクラスの時点で選択したデータのみを印刷やダイアログ
クラスへ渡す方法で解決しました。印刷クラスとダイアログクラスはそれぞれの仕事の
みをするように、Viewクラスでは表示関係をするように分けて、行いました。

クラスが変わると取得できない事もあったのでそのようにしました。

大変参考になりありがとうございました。

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