I’m working on a drag and drop problem now and trying to get the PIDLs of the items being dragged from windows shell to my application.
The code below can get correct PIDLs if the dragged item is ‘My Computer’ or ‘Control Panel’ itself, but it doesn’t work when the dragged item is an item in the ‘Control Panel’.
What’s wrong with my code?
#define GetPIDLFolder(pida) (LPCITEMIDLIST)(((LPBYTE)pida)+(pida)->aoffset[0])
#define GetPIDLItem(pida, i) (LPCITEMIDLIST)(((LPBYTE)pida)+(pida)->aoffset[i+1])
STGMEDIUM medium;
UINT fmt = RegisterClipboardFormat(CFSTR_SHELLIDLIST);
FORMATETC fe= {fmt, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
HRESULT GETDATA_RESULT = pDataObject->GetData(&fe, &medium);
if (SUCCEEDED(GETDATA_RESULT))
{
LPIDA pida = (LPIDA)GlobalLock(medium.hGlobal);
LPCITEMIDLIST pidlFolder = GetPIDLFolder(pida);
int n = pida->cidl; // the n is always correct
if( n > 0 )
{
LPCITEMIDLIST pidlItem = GetPIDLItem(pida, 0);
// the pidlItem is wrong when the dragged object is an item in 'Control Panel'
}
GlobalUnlock(medium.hGlobal);
}
ReleaseStgMedium(&medium);
Any idea? Thanks
Zach@Shine
If I D&D Mouse, Network Connections and Fonts I get the following output in my test app:
0 Mouse | sfgao=4 hr=01 ::{20D04FE0-3AEA-1069-A2D8-08002B30309D}\::{21EC2020-3AEA-1069-A2DD-08002B30309D}\::{7007ACC7-3202-11D1-AAD2-00805FC1270E} | sfgao=20000004 hr=02 C:\WINDOWS\Fonts | sfgao=60000004 hr=0The Network Connections and Fonts pidls can be converted to fully qualified shell paths while Mouse only returns a relative path/displayname.
This makes sense if you check the documentation for IShellFolder::GetDisplayNameOf:
It is clear that when dealing with controlpanel items, you need to keep the pidl around and only use GetDisplayNameOf for display strings in your UI.
(IShellLink::SetIDList on the Mouse pidl will create a working shortcut so the pidl is valid)