ダイアログにファイル名のドラッグ&ドロップを実装する

Visual C++プログラミングのメモ

【Visual C++ 2008】【MFC】

 エクスプローラからダイアログにドラッグ&ドロップしたファイル名(フルパス)を受け取る方法。 CWnd::OnDropFilesをオーバーライドするとよい。

(1)
 リソースビューにて、[プロパティ]-[動作]-[Accept Files]をTrueにする(デフォルトはFalse)。 もしくは、rcファイルを直接書き換えるなら、該当するダイアログのEXSTYLEにWS_EX_ACCEPTFILESを追加する。

(2)
 クラスヘッダのprotectedに、メンバ関数定義を追加。


    afx_msg void OnDropFiles(HDROP hDropInfo);

(3)
 メッセージマップに、ON_WM_DROPFILES()を追加。

(4)
 メンバ関数を記述。


void CXxxxDlg::OnDropFiles(HDROP hDropInfo)
{
    UINT iCount = 0;
    UINT iLength = 0;
    wchar_t *fullPathName;

    // ドラッグされたファイル数を取得
    iCount = DragQueryFile(hDropInfo, 0xFFFFFFFF, NULL, 0);

    // ファイル数でループ
    for (int i = 0; i < (int)iCount; i++)
    {
        // フルパスの長さを取得(NULL終端を含まず)
        iLength = DragQueryFile(hDropInfo, i, NULL, 0);

        // フルパスを受け取る変数を初期化(NULL終端を含む)
        fullPathName = new wchar_t[iLength + 1];
        wmemset(fullPathName, L'\0', iLength + 1);

        // フルパスを取得
        DragQueryFile(hDropInfo, i, fullPathName, iLength + 1);

        // ここでfullPathNameに格納されたフルパスを使用する
        // 
        // 
        // 

        // 変数の解放
        delete [] fullPathName;
    }

    return;
}

 もしくは、「受け取るファイル名は1個だけ」「フルパスの最大長は_MAX_PATH」「メモリの使い方は厳密ではない」と割り切るなら、


void CXxxxDlg::OnDropFiles(HDROP hDropInfo)
{
    wchar_t fullPathName[_MAX_PATH + 1];

    // フルパスを取得(NULL終端も設定される)
    DragQueryFile(hDropInfo, 0, fullPathName, _MAX_PATH + 1);

    // ここでfullPathNameに格納されたフルパスを使用する
    // 
    // 
    // 

    return;
}

(メモ)

  • 受け取るフルパスの文字コードは、Unicode
  • 取得する長さは文字数。byte数と異なる。
  • wchar_tは2byte
  • MSDNライブラリの「CWnd::OnDropFiles」「DragQueryFile」「_MAX_PATH」を参照のこと