a)UINT DragQueryFile(HDROP hDrop, UINT iFile, LPTSTR lpszFile, UINT cch)
b)BOOL DragQueryPoint(HDROP hDrop, LPPOINT lppt)
c)void DragFinish(HDROP hDrop)
一般用法如下:
void CListCtrlEx::OnDropFiles(HDROP hDrop)
{
char szFilePathName[_MAX_PATH+1] = {0};
UINT nNumOfFiles = DragQueryFile(hDrop, 0xFFFFFFFF, NULL, 0); //得到文件个数
for (UINT nIndex=0 ; nIndex< nFileCount; ++nIndex)
{
DragQueryFile(hDrop, nIndex, szFilePathName, _MAX_PATH); //得到文件名
}
DragFinish(hDrop);
}
注意了,一个应用程序不需要支持所有的COM接口。如果你的程序想做为一个拖放目标,那么你就实现IDropTarget接口,同样的,如果你需要支持作为数据源的程序,那么就应该实现IDropSource和IDataObject接口。当然,程序也可以同时实现这三个接口,从而可以在同一程序中支持拖放操作。
上面的图描述了拖放操作中所需要的关键组件。左边的表示拖放操作的源,它已经包含了两个对象,一个是IDropSource,另一个是IDataObject,最终是通过API函数DoDragDrop来发现拖放操作。
右边描述了拖放操作的目标,它需要实现IDropTarget接口。这个目标中,它能接收IDataObject对象。当鼠标拖动到目标窗体时,OLE传递一个IDataObject接口到目标对象上面,这是源传给目标的数据,它不能以任何方式得到一个副本。这目标这边它可以根据IDataObject得到该数据格式,从而判断这种格式是不是目标能识别的,如果不能识别,就不接收。它本质上需要调用RegisterDragDrop来把当前目标窗体注册成一个拖放目标。
注意,上面的图所示,源和目标可以是同一进程,也可以是不同进程。在使用之前,需要调用COM和OLE的初始化,使用完后,再调用其反初始化。
WINOLEAPI OleInitialize(LPVOID pvReserved);
WINOLEAPI OleUninitialize();
WINOLEAPI DoDragDrop(
IDataObject * pDataObject, // Pointer to the data object
IDropSource * pDropSource, // Pointer to the source
DWORD dwOKEffect, // Effects allowed by the source
DWORD * pdwEffect // Pointer to effects on the source
);
WINOLEAPI RegisterDragDrop(
HWND hwnd, // Handle to a window that can accept drops
IDropTarget * pDropTarget // Pointer to object that is to be target of drop
);
WINOLEAPI RevokeDragDrop(
HWND hwnd // Handle to a window that can accept drops
);