我正在尝试在我的程序中拖放ListView项目到另一个程序(就像将路径拖放到类似于VLC的东西,它会播放视频文件)。我正在使用CF_HDROP剪贴板格式。CopySelection是设置STGMEDIUM hglobal变量为DROPFILES结构的函数。
代码已正确格式化(我已检查),但不确定为什么它不起作用。我是否使用了正确的OLE剪贴板格式来实现这一点?我不确定要使用哪个,而我找到的文档也不是很好。
谢谢, 罗布
附言:我已尝试调整此示例: http://www.catch22.net/tuts/drop-source 区别在于,他只是移动文本,而我正在尝试移动文件列表(就像在Windows中选择图标并将其拖到vid播放器上)。
void CopySelection(HWND hwndList, STGMEDIUM &stgmed)
{
HGLOBAL hMem;
DROPFILES *ptr;
DROPFILES dfiles;
POINT p;
// get the selection inside the list control
int iPos = SendMessage(hwndList, LVM_GETNEXTITEM, (WPARAM)-1,(LPARAM)LVNI_SELECTED);
cout << "iPos: " << iPos << endl;
LVITEM item;
char buffer[256];
string fileDir = "";
item.iItem = iPos;
item.iSubItem = 1;
item.cchTextMax = 256;
item.pszText = buffer;
item.mask = LVIF_TEXT;
ListView_GetItem(hwndList, &item);
fileDir += string(item.pszText);
fileDir += "\\";
item.iItem = iPos;
item.iSubItem = 0;
ListView_GetItem(hwndList, &item);
fileDir += string(item.pszText);
item.iItem = iPos;
item.iSubItem = 2;
ListView_GetItem(hwndList, &item);
fileDir += string(item.pszText);
cout << "fileDir: " << fileDir << endl;
hMem = GlobalAlloc(GHND, sizeof(DROPFILES));
ptr = (DROPFILES *)GlobalLock(hMem);
dfiles.fNC = TRUE;
dfiles.fWide = FALSE;
memcpy((void*)&dfiles.pFiles, (fileDir.c_str()+'\0'), fileDir.size()+1);
GetCursorPos(&p);
dfiles.pt=p;
// copy the selected text and nul-terminate
memcpy(ptr, (void*)&dfiles, sizeof(DROPFILES));
GlobalUnlock(hMem);
stgmed.hGlobal = hMem;
//return hMem;
}
但是这似乎会导致段错误。以下是调用它的MouseMove列表消息代码:
case WM_MOUSEMOVE:
{
// stop drag-drop from happening when the mouse is released.
if(fMouseDown)
{
IDataObject *pDataObject;
IDropSource *pDropSource;
DWORD dwEffect;
DWORD dwResult;
FORMATETC fmtetc = { CF_HDROP, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
STGMEDIUM stgmed = { TYMED_HGLOBAL , { 0 }, 0 };
// transfer the current selection into the IDataObject
CopySelection(hwnd, stgmed);
cout << "DO WE?" << endl;
// Create IDataObject and IDropSource COM objects
CreateDropSource(&pDropSource);
CreateDataObject(&fmtetc, &stgmed, 1, &pDataObject);
//
// ** ** ** The drag-drop operation starts here! ** ** **
//
//dwResult = DoDragDrop(pDataObject, pDropSource, DROPEFFECT_COPY|DROPEFFECT_MOVE, &dwEffect);
dwResult = DoDragDrop(pDataObject, pDropSource, DROPEFFECT_COPY, &dwEffect);
// success!
if(dwResult == DRAGDROP_S_DROP)
{
if(dwEffect & DROPEFFECT_MOVE)
{
// remove selection from list control
}
else if(dwEffect & DROPEFFECT_LINK)
{
}
}
// cancelled
else if(dwResult == DRAGDROP_S_CANCEL)
{
}
pDataObject->Release();
pDropSource->Release();
ReleaseCapture();
fMouseDown = FALSE;
fDidDragDrop = TRUE;
}
代码已正确格式化(我已检查),但不确定为什么它不起作用。我是否使用了正确的OLE剪贴板格式来实现这一点?我不确定要使用哪个,而我找到的文档也不是很好。
谢谢, 罗布
附言:我已尝试调整此示例: http://www.catch22.net/tuts/drop-source 区别在于,他只是移动文本,而我正在尝试移动文件列表(就像在Windows中选择图标并将其拖到vid播放器上)。
memcpy()
将数据复制到了无效的内存地址,因此第二个memcpy()
很可能尝试访问由第一个memcpy()
损坏的内存。 - Remy Lebeau