【发布时间】:2012-05-19 19:57:52
【问题描述】:
我想显示 Windows 资源管理器上下文菜单。
我不想将我的应用程序添加到其中,我只想在我的应用程序中显示它。
我需要的一个很好的实现示例是 Total Commander。
如果按住鼠标右键,TC 将显示上下文菜单,这与 Windows 资源管理器中的完全相同。
我使用的是 C++/Qt,但语言在这里并不重要。
【问题讨论】:
标签: c++ windows windows-explorer
我想显示 Windows 资源管理器上下文菜单。
我不想将我的应用程序添加到其中,我只想在我的应用程序中显示它。
我需要的一个很好的实现示例是 Total Commander。
如果按住鼠标右键,TC 将显示上下文菜单,这与 Windows 资源管理器中的完全相同。
我使用的是 C++/Qt,但语言在这里并不重要。
【问题讨论】:
标签: c++ windows windows-explorer
我找到了几个可能对您有所帮助的示例。你不可能单独使用 Qt 来做到这一点,因为 shell 上下文菜单是高度特定于操作系统的;可能还需要一些 Win32 调用。
A Raymond Chen blog series "How to host an IContextMenu"
还有一些非 C++ 示例:
以及相关的 SO 问题:
【讨论】:
你有两个选择:
1) 自行实现每个功能,在自定义上下文菜单上创建相应的操作,或者
2) 访问 Windows API...考虑到 Qt 是跨平台的,这正是 Qt 不打算这样做。
【讨论】:
我是这样做的:
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;
}
【讨论】:
http://www.ffuts.org/blog/right-click-context-menus-with-qt/
右键单击弹出上下文菜单非常简单 在 Qt 中。有几件事需要注意……
// myWidget is any QWidget-derived class
myWidget->setContextMenuPolicy(Qt::CustomContextMenu);
connect(myWidget, SIGNAL(customContextMenuRequested(const QPoint&)),
this, SLOT(ShowContextMenu(const QPoint&)));
另一方面,如果您正在寻找“Windows 资源管理器集成”或“Windows Shell 集成”之类的东西,这里有一个很好的(尽管不是 QT 特定的)示例:
http://www.codeproject.com/Articles/15171/Simple-shell-context-menu
关键是实现这两个 Windows shell 接口:
IContextMenu
IShellExtInt
【讨论】: