Windows 11重新设计了右键菜单,如何适配,是一个问题。
介绍
首先看Windows Blogs的这篇博文Extending the Context Menu and Share Dialog in Windows 11 :
- 新款右键菜单也可以用于不封包的Win32应用。
- 新款的改进主要针对的问题
- 利用横向空间,改善纵向列表的拖沓
- 有些挨劈劈添加完右键菜单之后就置之不理
- 挨劈们通过IExplorerCommand以及挨劈劈标识来扩展菜单
- 许多命令在Explorer的进程内运行,拖慢了Explorer
- 右键菜单最佳实践
- 关联的文件类型的挨劈劈会自动添加到Open with菜单组
- 针对所有文件类型的,可以注册
*
- 针对所有文件类型的,可以注册
- 注册
Edit with (app)
?- 如HTML这类文件,查看和编辑需要分开,于是就要另注册
Edit with(app)
菜单项
- 如HTML这类文件,查看和编辑需要分开,于是就要另注册
- 注册
Share with (app)
?- 暂不关注
- 关联的文件类型的挨劈劈会自动添加到Open with菜单组
此外,上文中还提供了改进款的分享对话框,例子如https://github.com/microsoft/AppModelSamples/tree/master/Samples/SparsePackages。
文档:IExplorerCommand interface (shobjidl_core.h)
IExplorerCommand直接继承自IUnknown,有如下成员:
- EnumSubCommands,返回IEnumExplorerCommand,可用于遍历子命令,也就是在下拉菜单中显示的命令
- GetCanonicalNa,获取菜单命令的GUID命名
- GetFlags,设置菜单命令的风格样式
- GetIcon,获取图标
- GetState,获取状态
- GetTitle,获取标题
- GetToolTip,获取使用提示
- Invoke,调用命令
- IShellItemArray给出选中的条目
- IBindCtx
文档:How to Create Cascading Menus with the IExplorerCommand Interface
提到可以通过IExplorerCommand::EnumSubCommands来提供子菜单。
SO帖子:How to write a Shell extension in C++ for new Windows 11 context menus?
其他:
例子1
Old Windows 7 example。
例子2
https://github.com/microsoft/Windows-classic-samples/tree/main/Samples/CloudMirror
使用CoRegisterClassObject,在进程内起一个线程提供COM服务。
参考
- Can I create and use a COM class without registering it in the registry?
- https://msdn.microsoft.com/en-us/library/ms973913.aspx
例子3
https://github.com/ikas-mc/ContextMenuForWindows11
未仔细研究
例子4
https://github.com/M2Team/NanaZip
使用cppwinrt实现了一个子菜单,代码在https://github.com/M2Team/NanaZip/blob/main/NanaZipShellExtension/NanaZipShellExtension.cpp。
知识:启动封包的程序
可以使用Windows.System.Launcher,也可以使用
- Windows.ApplicationModel.Package下AppList的LaunchAsync
- 或者Win32的IActivateApplication
使用ActivateApplication的一个例子:
winrt::com_ptr<IApplicationActivationManager> appActivationMgr = nullptr;
RETURN_IF_FAILED(
CoCreateInstance(CLSID_ApplicationActivationManager, nullptr,
CLSCTX_LOCAL_SERVER, IID_PPV_ARGS(appActivationMgr.put())));
DWORD processId;
appActivationMgr->ActivateApplication(
app.AppUserModelId().c_str(),
nullptr,
AO_NONE,
&processId);
appActivationMgr->ActivateForFile
在WindowsAppSdk中不可用。
其他
- https://github.com/BluePointLilac/ContextMenuManager
- 一个纯粹的Windows右键菜单管理程序
- sparse menifest
- https://learn.microsoft.com/en-us/windows/win32/cfapi/build-a-cloud-file-sync-engine
- https://learn.microsoft.com/en-us/windows/uwp/cpp-and-winrt-apis/author-coclasses
- 如何在WinRT中实现COM
- https://learn.microsoft.com/en-us/uwp/schemas/appxpackage/uapmanifestschema/schema-root
- https://learn.microsoft.com/en-us/uwp/schemas/appxpackage/uapmanifestschema/element-com-comserver
- https://learn.microsoft.com/en-us/uwp/schemas/appxpackage/uapmanifestschema/element-com-surrogateserver
- https://docs.microsoft.com/en-us/uwp/schemas/appxpackage/uapmanifestschema/element-desktop4-fileexplorercontextmenus
- https://blogs.windows.com/windowsdeveloper/2017/04/13/com-server-ole-document-support-desktop-bridge/
- https://github.com/microsoft/AppModelSamples/tree/master/Samples/SparsePackages
- https://stackoverflow.com/questions/56146677/how-to-add-an-item-to-explorer-context-menu-for-uwp-application
(到底了)