こんにちは。じんです。
すいません、質問致します。
MFCのダイアログで、ダイアログ自身にドラッグアンドドロップでエクスプローラ等
からファイル名を取得出来たのですが、コントロール(CEditやCComboのエディット)
へのドラッグアンドドロップの実装方法が分かりません。
どうすれば良いのでしょうか?
サブクラス可化等の必要があるのでしょうか?
開発環境は
WinXP
VC++6.0
MFCのダイアログ
です。
よろしくお願いします。
コンボエディットは未調査です。
エディットボックスの方は以下の手順でできました。
1) CEditの派生クラスを作成
2) クラスウィザードでダイアログ側にコントロール変数を追加
(その際、変数のタイプを1)で作成した派生クラスにする)
3) 派生クラスにて、PreSubclassWindow()をオーバーライドし、
DragAcceptFiles()を呼ぶ
4) 派生クラスにて、WM_DROPFILESのイベントハンドラを追加
これで、エディットボックスにドラッグアンドドロップすると、
4)で作成したイベントハンドラが呼ばれます。
bunさん、ありがとうございました。
とりあえず、CEditで実現しようとしましたが、正常に動作しません。
PreSubclassWindowには入って来ますが、OnDropFilesには入ってきません。
何かおかしいですかね?
ダイアログのOnInitDialogでも、DragAcceptFilesをコールしています。
コールしない場合は、ドロップしようとしてもマウス形状が変化しません。
すいませんが、お知恵を貸してください。
/////////////////////////////////////////////////////////////////////////////
// CDropEdit Class
class CDropEdit : public CEdit
{
// インプリメンテーション
protected:
// 生成されたメッセージ マップ関数
//{{AFX_MSG(CDropEdit)
afx_msg void OnDropFiles(HDROP hDropInfo);
virtual void PreSubclassWindow();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
/////////////////////////////////////////////////////////////////////////////
// CDropEdit Class
BEGIN_MESSAGE_MAP(CDropEdit, CEdit)
//{{AFX_MSG_MAP(CDropEdit)
ON_WM_DROPFILES()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
void CDropEdit::OnDropFiles(HDROP hDropInfo)
{
CEdit::OnDropFiles(hDropInfo);
}
void CDropEdit::PreSubclassWindow()
{
DragAcceptFiles(TRUE);
CEdit::PreSubclassWindow();
}
変ですねぇ。
私のところでは、上記のコードと同じ状況でちゃんとOnDropFiles()に
飛んできます。
それに、ダイアログのOnInitDialogで DragAcceptFiles()を呼ばなくても
きちんと動作します。
何が違うんでしょう?
> ダイアログのOnInitDialogでも、DragAcceptFilesをコールしています。
> コールしない場合は、ドロップしようとしてもマウス形状が変化しません。
上記内容からdrop対象のエディットボックスはサブクラス化されていないと予想される。
現状でマウス形状が変わっているのは「エディットボックスにdropできるよ」という意味
ではなく「ダイアログにdropできるよ」という意味だと思われる。(多分、dropすると現在は
ダイアログ::OnDropFiles() に入っているんじゃなかろうか)
ドロップ対象のエディットボックスがきちんとサブクラス化できているか確認してみては
どうだろう。
> PreSubclassWindowには入って来ますが、OnDropFilesには入ってきません。
例えば edit_A,edit_B と2つエディットボックスがあり edit_B をサブクラス化した場合、
1、edit_B::PreSubclassWindow() は呼ばれるので「PreSubclassWindowには入って来ます
が」は成立する
2、edit_A にドロップした場合、edit_A はサブクラス化されていないので「OnDropFilesに
は入ってきません」も成立する
かなりエスパー気味に推測して出した回答なので、これが的を射ている保証は全く無し。
bunさん、gakさん、ありがとうございます。
前記の派生クラス、CDropEditの所で、OnContextMenuのイベントでは飛んで来るので、
おそらくサブクラス化は出来てると思いますが、OnDropFilesには入って来ないんです。
何が考えられますか?
DragAcceptFilesの方法が悪いのでしょうか?
> ダイアログのOnInitDialogでも、DragAcceptFilesをコールしています。
とりあえずこれを止めよう。エディットへのファイルDropには関係無いので。
> コールしない場合は、ドロップしようとしてもマウス形状が変化しません。
その上で、エディットBoxにDropしようとしても↑の状態なら
> DragAcceptFilesの方法が悪いのでしょうか?
が原因である可能性が考えられる。
一度新規プロジェクトを作成し、bun さんが 2008/08/06(水) 10:16:26 で示してくれた
手順を実装してみよう。その結果、新規プロジェクトで旨く動くようなら現在のプロジェ
クトと比べて問題になっていそうな点を探し出す。新規プロジェクトでも×なら bun さん
の回答通りに実装できていない可能性があるので実装方法を見直す。
って事をしてみると良いかと。
私も新規プロジェクトでやってみることをお勧めします。
他のイベントと喧嘩して、WM_DROPFILESが食われちゃってるとかは良くある話なので、
新規プロジェクトでやってみることで、それらとの切り分けができます。
万が一、新規プロジェクトでも駄目となると、情報が足りない気がします。
もう少し試行錯誤をしてみて、新たな情報が得られたら連絡ください。
返事が遅くなり、申し訳ありません。
確かに、新規プロジェクトではうまくいきました。
やはり私のプロジェクトが悪いようです。
何が違うのか見比べてみます。
ありがとうございました。
対象のエディットボックスを”グループボックス”コントロールで囲ったりしてる?
↑状況で、グループボックスのタブオーダーがエディットボックスのタブオーダーより若
いindex時、じんさんと同じような現象が確認できた。
恐らくファイルdrop時にdrop対象のウィンドウを検索する際、z-order順に対象ウィンド
ウを探している。
なので複数のWindowが重なっている↑のような状況だと、エディットより先にグループ
ボックス(ファイルDrop不可)が対象WindowとしてHitしてしまい、そこで検索処理が終
了(エディットへのdopr判定自体が行われない)される。結果「ファイルdropできませ
ん」となる。
これが原因臭いケドどうだろう。
gakさん、ありがとうございます。
まさしく、それでした。
やっと解決出来て、解決チェックを入れようと見てみたら・・・。
ちゃんとチェックしてなかった事を猛省です。
bunさん、gakさん、本当にありがとうございました。
なんか言葉足らずですね。
問題全てが解決してから、解決チェックを入れようとしたら、gakさんのコメントを読ま
せて貰いました。
もっと早くチェックしてれば、こんなに時間をかけずに済んだのに・・・。
ありがとうございました。