人気ブログランキング | 話題のタグを見る
エクスプローラ上でのファイル等のドラッグ&ドロップと同等のドラッグアンドドロップを開始する方法

エクスプローラ上でのファイル等のドラッグ&ドロップと同等のドラッグアンドドロップを開始する方法を、MFCを使用して実装する。
リストコントロールに登録されたファイルのドラッグアンドドロップが出来るようにした。


void CXXXListView::InitiateDragAndDropFiles()
{
    CListCtrl& list = GetListCtrl();

    // リストコントロールからファイルのリストを作成
    std::vector files;
    POSITION pos = list.GetFirstSelectedItemPosition();
    while(pos)
    {
        int nItem = list.GetNextSelectedItem(pos);
        // ここでは、各リストアイテムが CFileAttributes というクラスをデータとして持っており、
        // そのクラスが、ファイルのパスを提供する事を前提に作成しています。
        CFileAttributes* pAtt = (CFileAttributes*)list.GetItemData(nItem);
        if(pAtt)
        {
            CString strFilePath = pAtt->GetPathName();
            int nLen = strFilePath.GetLength();
            const char* top = strFilePath;
            files.insert(files.end(), top , top + nLen);
            files.push_back(0);    // 文字区切りとして、NULL文字(\0)を挿入します。
        }
    }
    files.push_back(0);    // ファイル名リストの終端は、 NULL NULL (\0\0) にします。

    // DROPFILES の データ構造は、
    // DROPFILES構造体と、構造体の先頭から pFilesバイト の位置から始まるファイル名リスト
    // から構成されているらしい。
    // ちなみに、pFilesを大きくすると、隙間に他のデータを埋め込む事が出来るっぽい。
    // それに新しくCFのIDを付ければ、HDROP互換のまま、お手軽にファイル+αの情報を
    // 伝えることが出来る。
    
    // グローバルメモリを割当
    HDROP hDrop = (HDROP)::GlobalAlloc(GHND, sizeof(DROPFILES) + files.size());
    if (hDrop == NULL)
        return;

    // グローバルメモリをロックして、ポインタを取得
    LPDROPFILES pDropFile = (LPDROPFILES)::GlobalLock(hDrop);
    pDropFile->pFiles = sizeof(DROPFILES);    
    pDropFile->pt.x = 0;
    pDropFile->pt.y = 0;
    pDropFile->fNC = FALSE;
    pDropFile->fWide = FALSE;

    // ファイル名リストをコピー
    char* lpNams = (char *)(pDropFile);
    lpNams += pDropFile->pFiles;
    ::memcpy(lpNams, &files[0], files.size());
    ::GlobalUnlock(hDrop);

    // ドラッグを開始
    COleDataSource oleDataSrc;
    oleDataSrc.CacheGlobalData(CF_HDROP, hDrop);
    DROPEFFECT dropEffect = oleDataSrc.DoDragDrop();

    if(dropEffect == DROPEFFECT_MOVE)
    {
        // なぜか、dropEffect が正しく返ってこない・・・不思議
    }
}

ソニーストア

by isoq | 2010-08-11 13:23 | C/C++/Win32
<< テスト 木星が見頃を迎えています! >>