场景,做一个类似桌面功能的explorer程序,需要获取桌面那个文件夹的各个文件,包括快捷方式等;还有其中的右键行为,拖放的暂时不考虑。
输入:窗口句柄,文件名
行为:弹出对应文件的右键菜单,菜单里面的行为需要和真实右键点击文件的行为一样。
实现情况:以下实现的功能,右键中除了复制,剪切不能做,其他行为都可以实现;我想是因为没有真正绑定原来的文件,而只是取了原文件的菜单行为,导致复制粘贴没法找到原来的文件对象造成的。
void MyGetMenu(HWND hWnd,TCHAR* FilePath)
{
DWORD dwErr = 0;
IShellFolder *pIShellFolder = NULL;
HRESULT hr = SHGetDesktopFolder(&pIShellFolder);
if(NOERROR != hr)
{
return;
}
LPITEMIDLIST pidl;
ULONG cbEaten;
DWORD dwAttribs = SFGAO_COMPRESSED;
WCHAR wchPath[256];
MultiByteToWideChar (CP_ACP, 0, FilePath, -1, wchPath, sizeof (wchPath) / sizeof (WCHAR));
hr = pIShellFolder->ParseDisplayName(NULL, NULL, wchPath, &cbEaten, &pidl, &dwAttribs);
if(S_OK != hr)
{
return;
}
IShellFolder *psfParent;
LPCITEMIDLIST pidlRelative = NULL;
hr = SHBindToParent(pidl, IID_IShellFolder, (void**)&psfParent, &pidlRelative);
if(S_OK != hr)
{
return;
}
HMENU myMenu = NULL;
myMenu = CreatePopupMenu();
//LPCONTEXTMENU ppv = NULL;
IContextMenu *ppv = NULL;
pIShellFolder->GetUIObjectOf(NULL, 1, &pidlRelative, IID_IContextMenu, NULL, (void**)&ppv);
ppv->QueryContextMenu(myMenu, GetMenuItemCount(myMenu), 0, 10000, CMF_NORMAL | CMF_EXPLORE);
int i= GetMenuItemCount(myMenu);
MENUITEMINFO MenuItemInfo;
MenuItemInfo.cbSize = sizeof(MENUITEMINFO);
MenuItemInfo.dwTypeData = NULL;
MenuItemInfo.fMask = MIIM_STRING;
MenuItemInfo.fType = MFT_STRING;
UINT itemid = GetMenuItemID(myMenu,1);
if (0==GetMenuItemInfo(myMenu,itemid,FALSE,&MenuItemInfo))
{
dwErr = GetLastError();
}
MenuItemInfo.dwTypeData = new TCHAR[MenuItemInfo.cch+1];
if (0==GetMenuItemInfo(myMenu,itemid,FALSE,&MenuItemInfo))
{
dwErr = GetLastError();
}
POINT pt;
GetCursorPos(&pt);
UINT nCmd = ::TrackPopupMenu(myMenu,TPM_LEFTALIGN | TPM_LEFTBUTTON | TPM_RIGHTBUTTON | TPM_RETURNCMD, pt.x,pt.y,0,hWnd,0);
BOOL bResult = FALSE;
CMINVOKECOMMANDINFO ici;
// If a command was selected from the menu, execute it.
if (nCmd)
{
ici.cbSize = sizeof (CMINVOKECOMMANDINFO);
ici.fMask = 0;
ici.hwnd = hWnd;
ici.lpVerb = MAKEINTRESOURCE (nCmd);
ici.lpParameters = NULL;
ici.lpDirectory = NULL;
ici.nShow = SW_SHOWNORMAL;
ici.dwHotKey = 0;
ici.hIcon = NULL;
if (SUCCEEDED (ppv->InvokeCommand(&ici)))
bResult = TRUE;
}
DestroyMenu (myMenu);
ppv->Release ();
}