dポイントプレゼントキャンペーン実施中!

CListCtrlに表示している複数ファイルを他アプリへドラッグ&ドロップするソースに手間取っていますのでご教授をお願いします。
(VC++ 6.0のサンプルコードがあまりなくて)

なんとか、1つのファイルはできるようになったのですが複数にするやり方がわかりません。
どのようにすればよいでしょうか?
また、おかしい箇所などありましたら合わせてお願いします。


※単純の繋げるだけじゃないんですよね?※
CString fname = "C:\\aaa.txt";
fname += "C:\\bbb.txt";

-環境-
・VC++ 6.0
・MFC
・ダイアログベース

-ソース-
void aaaDlg::OnBegindragListView(NMHDR* pNMHDR, LRESULT* pResult)
{
NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
// TODO: この位置にコントロール通知ハンドラ用のコードを追加してください
if(pNMListView->iItem != -1)
{
CString fname = "C:\\aaa.txt";// 動作確認のため固定

HDROP hptr = DragCreateFiles(fname);
if (hptr == NULL)
{
*pResult = 0;
return;
}

m_DropData.CacheGlobalData(CF_HDROP, hptr);

CRect rect(0,0,0,0);
DROPEFFECT effect = m_DropData.DoDragDrop(DROPEFFECT_COPY, rect);
}

*pResult = 0;
}

static HDROP DragCreateFiles (LPCSTR fname)
{
HDROP hDrop;
LPDROPFILES lpDropFileStruct;

// Allocate dynamic memory for the DROPFILESTRUCT data
// structure and for the extra zero-character identifying
// that there are no pathnames in the block yet.
int flen = lstrlen(fname);
hDrop = (HDROP)GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT,
sizeof(DROPFILES) + flen + 2);

// If unsuccessful, return NULL
if (hDrop == NULL)
return(hDrop);

// Lock block and initialize the data members
lpDropFileStruct = (LPDROPFILES) GlobalLock(hDrop);
memset(lpDropFileStruct,0,sizeof(DROPFILES) + flen + 2);
lpDropFileStruct->pFiles = sizeof(DROPFILES);
lpDropFileStruct->pt.x = 0;
lpDropFileStruct->pt.y = 0;
lpDropFileStruct->fNC = FALSE;
lpDropFileStruct->fWide = FALSE;

char* szPathA = (char*) (&lpDropFileStruct[1]);

lstrcpy(szPathA,fname);

// Unlock the block and return its handle.
GlobalUnlock(hDrop);
return(hDrop);
}

A 回答 (1件)

 こんばんは。



 複数の場合はNULL文字で区切ってファイル名を並べ、最後にもう1つNULL文字を置くので、例えば

 2個ならば、
 C:\\aaa.txt\0C:\\bbb.txt\0\0

 sizeof(DROPFILES) + 23文字

 3個ならば、
 C:\\aaa.txt\0C:\\bbb.txt\0C:\\ccc.txt\0\0

 sizeof(DROPFILES) + 34文字

 となるのではないでしょうか。
 以下、送信と受信をまとめて実装して、同じアプリを2つ立ち上げて試していますが、ドロップされた側に複数のファイル名が入ってきています。
 実験的なコードなのですが、参考程度に。

static HDROP DragCreateFiles(const CStringArray& fileList)
{
//最後にもう1つNULLを含めておく
int len = 1;
for(int i = 0; i < fileList.GetSize(); ++i)
{
len += fileList[i].GetLength() + 1;
}

HDROP hDrop = (HDROP)GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, sizeof(DROPFILES) + len);

if(hDrop == NULL)
return(hDrop);

LPDROPFILES lpDropFileStruct = (LPDROPFILES)GlobalLock(hDrop);
memset(lpDropFileStruct,0,sizeof(DROPFILES) + len);
lpDropFileStruct->pFiles = sizeof(DROPFILES);
lpDropFileStruct->pt.x = 0;
lpDropFileStruct->pt.y = 0;
lpDropFileStruct->fNC = FALSE;
lpDropFileStruct->fWide = FALSE;

char* szPathA = (char*)(&lpDropFileStruct[1]);

//文字列を書き込む
for(int i = 0; i < fileList.GetSize(); ++i)
{
lstrcpy(szPathA, fileList[i].GetString());
szPathA += fileList[i].GetLength() + 1;
}

GlobalUnlock(hDrop);
return(hDrop);
}

void CTestDlg::OnLvnBegindragList1(NMHDR *pNMHDR, LRESULT *pResult)
{
LPNMLISTVIEW pNMLV = reinterpret_cast<LPNMLISTVIEW>(pNMHDR);
// TODO: ここにコントロール通知ハンドラ コードを追加します。

if(pNMLV->iItem != -1)
{
//3つ分送る
CStringArray fileList;
fileList.Add("C:\\aaa.txt");
fileList.Add("C:\\bbb.txt");
fileList.Add("C:\\ccc.txt");

HDROP hDrop = DragCreateFiles(fileList);
if (hDrop == NULL)
{
*pResult = 0;
return;
}

COleDataSource OleDataSrc;
OleDataSrc.CacheGlobalData(CF_HDROP, hDrop);
DROPEFFECT DropEffect = OleDataSrc.DoDragDrop(DROPEFFECT_COPY);

*pResult = 0;
}
}

//受け取りテスト
void CTestDlg::OnDropFiles(HDROP hDropInfo)
{
// TODO: ここにメッセージ ハンドラ コードを追加するか、既定の処理を呼び出します。

CDialog::OnDropFiles(hDropInfo);

CHAR sz[MAX_PATH + 1];
const int fileCount = DragQueryFile(hDropInfo, -1, NULL, 0);
for(int i = 0; i < fileCount; ++i)
{
DragQueryFile(hDropInfo, i, sz, MAX_PATH);
}
DragFinish(hDropInfo);
}
    • good
    • 0
この回答へのお礼

ありがとうございます

合計ファイルパス長 = (ファイルパス長 + 1(\0)) * ファイル数
で解決しました

お礼日時:2010/03/18 10:40

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!