Description
DFM should inform the callback about the invoked folder command (DFM_CMD_*) so that the callback gets to override or cancel it. Windows reports all folder commands, ROS only reports DFM_CMD_PROPERTIES (special cased for some reason).
HRESULT CALLBACK callback(IShellFolder*psf, HWND hwnd, IDataObject*pdo, UINT msg, WPARAM wp, LPARAM lp)
|
{
|
DFMICS *pICS = (DFMICS*)lp;
|
switch(msg) |
{
|
case DFM_MERGECONTEXTMENU: |
printf("DFM_MERGECONTEXTMENU %p %p\n", wp, lp); |
return S_OK; // Yes, we want the static verbs from the registry |
case DFM_INVOKECOMMAND: |
printf("DFM_INVOKECOMMAND %d (DFM_CMD_COPY=%d DFM_CMD_PROPERTIES=%d)\n", (int)wp, DFM_CMD_COPY, DFM_CMD_PROPERTIES); |
return S_FALSE; |
case DFM_INVOKECOMMANDEX: |
printf("DFM_INVOKECOMMANDEX %d %d..%d\n", (int)wp, pICS->idCmdFirst, pICS->idDefMax); |
return E_NOTIMPL; |
}
|
return E_NOTIMPL; |
}
|
void main() |
{
|
OleInitialize(0); |
HWND hwnd = CreateWindowExA(0, "STATIC", "Test", WS_VISIBLE | WS_OVERLAPPEDWINDOW, 1, 1, 1, 1, 0, 0, 0, 0); |
WCHAR path[MAX_PATH];
|
wsprintfW(path + GetWindowsDirectoryW(path, MAX_PATH), L"\\Explorer.exe"); |
PIDLIST_ABSOLUTE pidl;
|
SHParseDisplayName(path, 0, &pidl, 0, 0); |
IShellFolder*psf;
|
PCUITEMID_CHILD child;
|
SHBindToParent(pidl, IID_IShellFolder, (void**)&psf, &child); |
UINT first = 1, last = 0x7fff, cmd, ck = 0, cmf = (Sleep(500), GetAsyncKeyState(VK_CONTROL)) < 0 ? CMF_CANRENAME : 0; |
IContextMenu*pcm;
|
HKEY hKey, hKeys[8]; |
if (!RegOpenKeyExA(HKEY_CLASSES_ROOT, "exefile", 0, KEY_READ, &hKey)) hKeys[ck++] = hKey; |
if (!RegOpenKeyExA(HKEY_CLASSES_ROOT, "SystemFileAssociations\\.exe", 0, KEY_READ, &hKey)) hKeys[ck++] = hKey; |
if (!RegOpenKeyExA(HKEY_CLASSES_ROOT, "*", 0, KEY_READ, &hKey)) hKeys[ck++] = hKey; |
if (!RegOpenKeyExA(HKEY_CLASSES_ROOT, "AllFilesystemObjects", 0, KEY_READ, &hKey)) hKeys[ck++] = hKey; |
HRESULT hr = CDefFolderMenu_Create2(0, hwnd, 1, &child, psf, callback, ck, hKeys, &pcm); |
HMENU hmenu = CreatePopupMenu();
|
hr = pcm->QueryContextMenu(hmenu, 0, first, last, cmf | (GetAsyncKeyState(VK_SHIFT) < 0 ? CMF_EXTENDEDVERBS : 0)); |
if (FAILED(hr)) return ; |
cmd = TrackPopupMenuEx(hmenu, TPM_RETURNCMD, 1, 1, hwnd, 0); |
if (!cmd) return ; |
CMINVOKECOMMANDINFO ici = { sizeof(ici), CMIC_MASK_NOASYNC, hwnd, (char*)(cmd - first), 0, 0, SW_SHOW }; |
pcm->InvokeCommand(&ici);
|
}
|
Choosing "Copy" does not call the callback in ROS: