こんにちは。tete2000です。
MFCのダイアログで、ダイアログ自身にドラッグアンドドロップでエクスプローラ等
からファイル名を取得出来たのですが、コントロール(CEdit)
へのドラッグアンドドロップの実装方法が分かりません。
そこで過去ログからどんぴしゃの質問があり
--------------------------------------------------------
1) CEditの派生クラスを作成
2) クラスウィザードでダイアログ側にコントロール変数を追加
(その際、変数のタイプを1)で作成した派生クラスにする)
3) 派生クラスにて、PreSubclassWindow()をオーバーライドし、
DragAcceptFiles()を呼ぶ
4) 派生クラスにて、WM_DROPFILESのイベントハンドラを追加
これで、エディットボックスにドラッグアンドドロップすると、
4)で作成したイベントハンドラが呼ばれます。
----------------------------------------------------------
↑で派生クラスにてイベントハンドラが呼ばれることまでは確認できました。
そこで質問ですが、派生クラスのOnDropFiles関数内からダイアログ側のコントロール変
数やメンバ変数にアクセスするにはどうすれば良いのでしょうか?
ものすごく基本的なことだと思いますが、わからなくて悩んでいます。
開発環境は
WinXP
VC++6.0
MFCのダイアログ
です。
CEditの派生クラスのWM_DROPFILESの処理で自分にSetWindowTextで内容をかえる。
値が必要になった時に親ウィンドウがUpdateData(TRUE)でCEditの内容を読み込むので十
分と思うけど。
あるいは親ウィンドウにCEditの内容が変化したときに通知が来るから
親ウィンドウでそのハンドラを使う。
CEditのテキストを変えたくない
CEditのハンドラから親ウィンドウのメンバ変数を操作したい
というならGetParentで親ウィンドウを取得できるよ。
ダウンキャストが必要になるけど。
親ウィンドウが行うべき処理をCEditが色々とやってしまうのは邪道だけどね。
エディットコントロールの処理はCEdit::hogehoge()や属性はCEdit::m_hogehoge、
ダイアログの処理はCDialgo::hogehoge()や属性はCDialgo::m_hogehogeって
クラスやファイルが整理されている意味が無くなる。
CEditに書いた方が都合いい処理だと判断したなら止めないが。
アドバイスありがとうございます。
ご丁寧に教えて頂いたのに基本的な部分でつまずいています。
>CEditの派生クラスのWM_DROPFILESの処理で自分にSetWindowTextで内容をかえる。
>値が必要になった時に親ウィンドウがUpdateData(TRUE)でCEditの内容を読み込むので
>十分と思うけど。
CEdit派生クラスのOnDropFiles()内で「自分にSetWindowTextで内容をかえる」処理がう
まくできません。この処理がやりたいので、
コントロールメンバ変数をm_ed1(親ウインドのメンバ変数)とすると
派生クラス内の
void CDropEdit::OnDropFiles(HDROP hDropInfo) {
m_ed1.SetWindowText(hoge);
}
と書くと、m_ed1は定義されていないとエラーがきます。
GetParentで親ウインドを取得しないといけないのでしょうか?
基本的に、子が親をいじるようなコードは好ましくない。
そのEditは親ダイアログに完全に依存してしまうし。
子のイベントをどうにかして親に通知して、いろいろやってもらうようなつくりに変えた
ほうが良いです。
よくやるのは、イベントクラスみたいなのを作って、親で実装してもらうようなの。
これならば、子はイベントクラスだけ知っていれば十分。
//
// DropEdit.h
//
// 追加<<
class FDropEditEvent {
public:
virtual void OnDropFiles(CDropEidt* pSender, HDROP hDropInfo) {}
};
// >>追加
class CDropEdit {
// 追加<<
FDropEditEvent* m_pEvent; // コンストラクタで NULL で初期化
public:
void SetEvent(FDropEditEvent* pEvent) { m_pEvent = pEvent; }
// >>追加
// 省略
};
//
// DropEdit.cpp
//
void CDropEdit::OnDropFiles(HDROP hDropInfo) {
if (m_pEvent) {
m_pEvnet->OnDropFiles(this, hDropInfo);
}
}
//
// HogeDlg.h
//
class CHogeDlg : public CDialog
// 追加<<
, public FDropEditEvent
// >>追加
{
// 追加<<
virtual void OnDropFiles(CDropEidt* pSender, HDROP hDropInfo);
// >>追加
// 省略
};
//
// HogeDlg.cpp
//
void CHogeDlg::OnInitDialog()
{
// 省略
// 追加<<
m_dropedit1.SetEvent(this);
// >>追加
// 省略
}
void CHogeDlg::OnDropFiles(CDropEidt* pSender, HDROP hDropInfo)
{
m_ed1.SetWindowText(hoge);
}
他にもユーザ独自のメッセージを用意して、親ダイアログに子のドロップファイルイベン
トを通知してあげるとか。
this->GetParent()->SendMessage(WM_XXXXXX, (WPARAM)this->m_hWnd, (LPARAM)hDropInfo);
追記
>class FDropEditEvent {
の前に、
class CDropEdit;
がないとまずかったです。
ご返答ありがとうございます。
教えて頂いた「ユーザ独自のメッセージを用意して親ダイアログに子のドロップファイ
ルイベ>ントを通知してあげる方法」で上手くいきました。
ダイアログアプリをかじった程度だったので、今回のメッセージのやり取りには目から
鱗状態でたいへん勉強になりました。
ご指導ありがとうございまいた。