问题
I want to show the Windows Explorer context menu.
I don't want to add my application to it, I just want to display it.
A good example of the implementation that I need is Total Commander.
If you press and hold right mouse button, TC will show the context menu, which is exactly the same as in Windows explorer.
I'm using C++/Qt, but language is not important here.
回答1:
I found several samples that may help you. You're not likely to be able to do this with Qt alone, since the shell context menu is highly OS-specific; probably some Win32 calls will be needed also.
- Use Shell ContextMenu in your applications
- Explorer Shell Context Menu
A Raymond Chen blog series "How to host an IContextMenu"
And some non-C++ samples also:
- C# File Browser
- Shell context menu sample in C#
And related SO questions:
- How to access Windows shell context menu items?
- How to obtain full shell context menu of right-click a folder background
回答2:
You have two options:
1) Implement each functionality on your own, creating the corresponing actions on a custom context menu, or
2) Access the Windows API... and this is just what Qt is not intended to considering that Qt is cross-platform.
回答3:
Here's how I do it:
bool CShellMenu::openShellContextMenuForObject(const std::wstring &path, int xPos, int yPos, void * parentWindow)
{
assert (parentWindow);
ITEMIDLIST * id = 0;
std::wstring windowsPath = path;
std::replace(windowsPath.begin(), windowsPath.end(), '/', '\\');
HRESULT result = SHParseDisplayName(windowsPath.c_str(), 0, &id, 0, 0);
if (!SUCCEEDED(result) || !id)
return false;
CItemIdListReleaser idReleaser (id);
IShellFolder * ifolder = 0;
LPCITEMIDLIST idChild = 0;
result = SHBindToParent(id, IID_IShellFolder, (void**)&ifolder, &idChild);
if (!SUCCEEDED(result) || !ifolder)
return false;
CComInterfaceReleaser ifolderReleaser (ifolder);
IContextMenu * imenu = 0;
result = ifolder->GetUIObjectOf((HWND)parentWindow, 1, (const ITEMIDLIST **)&idChild, IID_IContextMenu, 0, (void**)&imenu);
if (!SUCCEEDED(result) || !ifolder)
return false;
CComInterfaceReleaser menuReleaser(imenu);
HMENU hMenu = CreatePopupMenu();
if (!hMenu)
return false;
if (SUCCEEDED(imenu->QueryContextMenu(hMenu, 0, 1, 0x7FFF, CMF_NORMAL)))
{
int iCmd = TrackPopupMenuEx(hMenu, TPM_RETURNCMD, xPos, yPos, (HWND)parentWindow, NULL);
if (iCmd > 0)
{
CMINVOKECOMMANDINFOEX info = { 0 };
info.cbSize = sizeof(info);
info.fMask = CMIC_MASK_UNICODE;
info.hwnd = (HWND)parentWindow;
info.lpVerb = MAKEINTRESOURCEA(iCmd - 1);
info.lpVerbW = MAKEINTRESOURCEW(iCmd - 1);
info.nShow = SW_SHOWNORMAL;
imenu->InvokeCommand((LPCMINVOKECOMMANDINFO)&info);
}
}
DestroyMenu(hMenu);
return true;
}
回答4:
http://www.ffuts.org/blog/right-click-context-menus-with-qt/
Getting right-clicks to popup a context menu is pretty straightforward in Qt. There are just a couple of things to watch out for…
// myWidget is any QWidget-derived class
myWidget->setContextMenuPolicy(Qt::CustomContextMenu);
connect(myWidget, SIGNAL(customContextMenuRequested(const QPoint&)),
this, SLOT(ShowContextMenu(const QPoint&)));
If, on the other hand, you're looking for something like "Windows explorer integration" or "Windows Shell integration", here's a good (albeit non-QT specific) example:
http://www.codeproject.com/Articles/15171/Simple-shell-context-menu
The key is implementing these two Windows shell interfaces:
IContextMenu
IShellExtInt
来源:https://stackoverflow.com/questions/10668456/how-to-show-windows-explorer-context-right-click-menu