AppWizardで作成したMDIのMFCアプリケーションでは、ファイルのドロップ処理はデフォルトで行われます。
SDIやダイアログベースのMFCアプリケーションでも、ちょっと処理を書いてやるだけで
けっこう簡単にファイルのドロップを扱う事が出来ます。
以下、SDIの場合を例にして説明します。 ダイアログの例は後ろにあります。
DropView.h:
class CDropView : public CView { 〜 // 生成されたメッセージ マップ関数 protected: //{{AFX_MSG(CDropView) afx_msg void OnDropFiles(HDROP hDropInfo); //}}AFX_MSG DECLARE_MESSAGE_MAP() 〜 };
DropView.cpp:
〜 BEGIN_MESSAGE_MAP(CDropView, CView) //{{AFX_MSG_MAP(CDropView) ON_WM_DROPFILES() //}}AFX_MSG_MAP END_MESSAGE_MAP() 〜 void CDropView::OnDropFiles(HDROP hDropInfo) { // TODO: この位置にメッセージ ハンドラ用のコードを追加するかまたはデフォルトの処理を呼び出してください CView::OnDropFiles(hDropInfo); }
これで、OnDropFiles()が呼ばれるようになります。
class CDropView : public CView
{
〜
// 生成されたメッセージ マップ関数
protected:
//{{AFX_MSG(CDropView)
afx_msg void OnDropFiles(HDROP hDropInfo);
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
〜
};
DropView.cpp:
〜
BEGIN_MESSAGE_MAP(CDropView, CView)
//{{AFX_MSG_MAP(CDropView)
ON_WM_DROPFILES()
ON_WM_CREATE()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
〜
int CDropView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CView::OnCreate(lpCreateStruct) == -1)
return -1;
// TODO: この位置に固有の作成用コードを追加してください
DragAcceptFiles();
return 0;
}
BOOL CDropView::PreCreateWindow(CREATESTRUCT& cs)
{
// TODO: この位置で CREATESTRUCT cs を修正して Window クラスまたはスタイルを
// 修正してください。
cs.dwExStyle |= WS_EX_ACCEPTFILES; //ファイルのドロップを受け付ける
return CListView::PreCreateWindow(cs);
}
DropView.cpp:
void CDropView::OnDropFiles(HDROP hDropInfo)
{
// TODO: この位置にメッセージ ハンドラ用のコードを追加するかまたはデフォルトの処理を呼び出してください
//ドロップされたファイルの個数を取得
UINT uiCount=DragQueryFile(hDropInfo,~0lu,NULL,0);
for(UINT i=0; i<uiCount; i++){
//ファイル名の長さを取得
UINT uiLen=DragQueryFile(hDropInfo,i,NULL,0);
//ファイル名を取得
CString name;
DragQueryFile(hDropInfo,i,name.GetBuffer(uiLen+1),uiLen+1);
name.ReleaseBuffer();
//name(ファイル名)を使って何らかの処理を行う
〜
}
// CView::OnDropFiles(hDropInfo); //必要ないと思われるので呼ばない
}
ただし、ディレクトリがドロップされた場合、そのディレクトリは
ひとつのファイルとして扱われるので注意が必要です。
しかし、ダイアログではClassWizardでWM_DROPFILESが表示されないので、
自分でコーディングする必要があります。
また、初期化としてOnInitDialog関数が呼ばれるので、
OnCreateでなくOnInitDialogでDragAcceptFiles()を呼び出すといいでしょう。
DropDlg.cpp:
BOOL CDropDlg::OnInitDialog()
{
CDialog::OnInitDialog();
〜
// TODO: 特別な初期化を行う時はこの場所に追加してください。
DragAcceptFiles();
return TRUE; // TRUE を返すとコントロールに設定したフォーカスは失われません。
}
[1998-08-22]
しかし、ダイアログの場合、DragAcceptFiles()を呼ばないで済む方法があります。
ダイアログのリソースのプロパティーを開き、「拡張スタイル」タブの「ドラッグアンドドロップを許可」に
チェックを付けるだけです。