Files can be copied/pasted using a number of different clipboard formats, and multiple formats can reside on the clipboard at the same time.
- CF_HDROP
- CFSTR_FILECONTENTS
- CFSTR_FILEDESCRIPTOR
- CFSTR_FILENAME
- CFSTR_FILENAMEMAP
- CFSTR_MOUNTEDVOLUME
- CFSTR_SHELLIDLIST
- CFSTR_SHELLIDLISTOFFSET
Refer to Shell Clipboard Formats for specific details about each format. In particular, see Formats for Transferring File System Objects.
So, you would need something like this:
const UINT ui_CFSTR_SHELLIDLIST = RegisterClipboardFormat(CFSTR_SHELLIDLIST);
const UINT ui_CFSTR_FILENAMEA = RegisterClipboardFormat(CFSTR_FILENAMEA);
const UINT ui_CFSTR_FILENAMEW = RegisterClipboardFormat(CFSTR_FILENAMEW);
...
HANDLE WINAPI mySetClipBoardData (UINT uFormat, HANDLE hMem)
{
if (!hMem) // DELAYED RENDERING! The real data will come later...
return SetClipboardData(uFormat, hMem);
if (uFormat == CF_HDROP)
{
LPDROPFILES pDF = (LPDROPFILES) GlobalLock(hMem);
if (pDF->fWide)
{
LPWSTR pFiles = (LPWSTR) (((LPBYTE)pDF) + pDF->pFiles);
while (*pFiles)
{
LPWSTR pFile = pFiles;
if (pFile refers to the desired file)
{
GlobalUnlock(hMem);
SetLastError(...);
return NULL;
// alternatively, build up a new string to place on the clipboard that omits this file...
}
pFiles += (lstrlenW(pFile) + 1);
}
}
else
{
LPSTR pFiles = (LPSTR) (((LPBYTE)pDF) + pDF->pFiles);
while (*pFiles)
{
LPSTR pFile = pFiles;
if (pFile refers to the desired file)
{
GlobalUnlock(hMem);
SetLastError(...);
return NULL;
// alternatively, build up a new string to place on the clipboard that omits this file...
}
pFiles += (lstrlenA(pFile) + 1);
}
}
GlobalUnlock(hMem);
/* alternatively:
TCHAR szFile[MAX_PATH];
UINT count = DragQueryFile((HDROP)hMem, (UINT)-1, NULL, 0);
for (UINT i = 0; i < count; ++i)
{
DragQueryFile((HDROP)hMem, i, szFile, MAX_PATH);
if (szFile refers to the desired file)
{
SetLastError(...);
return NULL;
// alternatively, build up a new string to place on the clipboard that omits this file...
}
}
*/
}
else if (uFormat == ui_CFSTR_SHELLIDLIST)
{
#define HIDA_GetPIDLFolder(pida) (LPCITEMIDLIST)(((LPBYTE)pida)+(pida)->aoffset[0])
#define HIDA_GetPIDLItem(pida, i) (LPCITEMIDLIST)(((LPBYTE)pida)+(pida)->aoffset[i+1])
LPIDA pIDA = (LPIDA) GlobalLock(hMem);
LPCITEMIDLIST pidlParent = HIDA_GetPIDLFolder(pIDA);
for (UINT i = 0; i < pIDA->cidl; ++i)
{
LPCITEMIDLIST pidlFile = HIDA_GetPIDLItem(pIDA, i);
if (pidlParent+pidlFile refers to the desired file)
{
GlobalUnlock(hMem);
SetLastError(...);
return NULL;
// alternatively, build up a new array to place on the clipboard that omits this file...
}
}
GlobalUnlock(hMem);
}
else if (uFormat == ui_CFSTR_FILENAMEA)
{
LPSTR pFile = (LPSTR) GlobalLock(hMem);
if (pFile refers to the desired file)
{
GlobalUnlock(hMem);
SetLastError(...);
return NULL;
}
GlobalUnlock(hMem);
}
else if (uFormat == ui_CFSTR_FILENAMEW)
{
LPWSTR pFile = (LPWSTR) GlobalLock(hMem);
if (pFile refers to the desired file)
{
GlobalUnlock(hMem);
SetLastError(...);
return NULL;
}
GlobalUnlock(hMem);
}
else
{
// handle other shell formats as needed...
}
return SetClipboardData(uFormat, hMem);
}