c# – 仅在我的应用程序中添加到shell上下文菜单
在我的.NET Framework 4应用程序中,我显示文件,文件夹和其他不属于文件系统的东西.对于文件和文件夹,由于
this code on MSDN,我设法显示该项目的Windows Shell上下文菜单.(它仍然无法显示Carbonite Shell扩展但我离题了.)
我的斗争是将我自己的子菜单添加到Shell上下文菜单中.我所有的研究都提到了所谓的Shell Extensions,如果我理解的话,它是一个全系统的变化.我只想在我的应用程序中访问它时添加到Shell上下文菜单. 不可否认,抓住吸管,我试着在上面的类’ShowContextMenu方法中添加以下内容,就在它调用QueryContextMenu之后: var mii = new MENUITEMINFO(); mii.cbSize = Marshal.SizeOf(mii); mii.fMask = MIIM.SUBMENU | MIIM.STRING | MIIM.FTYPE | MIIM.ID; mii.fType = MFT.BYPOSITION; mii.wID = 0; mii.hSubMenu = subMenu.Handle; mii.dwTypeData = "Test"; var success = InsertMenuItem(pMenu,true,ref mii); 但没有“成功”. (subMenu是我之前创建的System.Windows.Forms.ContextMenuStrip.) 我的问题是: >我是否正确我所尝试的与创建Shell扩展不同? 解决方法
好的,看起来可以将自定义菜单项添加到Windows Shell上下文菜单中,就在您的应用程序中(无需执行任何影响整个Windows系统的操作).以下是我的所作所为.请记住,此答案应在首次提到的MSDN代码的上下文中进行.这是链接:
ShellContextMenu class on MSDN 在该类中,具体来说,方法ShowContextMenu是对QueryContextMenu的调用,我学习的目的是用项填充菜单 – 在这种情况下,文件/文件夹的相应Windows Shell菜单项的上下文菜单将是显示.在那次调用之后,我添加了以下代码来添加子菜单和分隔符: var mii = new MENUITEMINFO(); mii.fMask = MIIM.SUBMENU | MIIM.STRING | MIIM.FTYPE | MIIM.ID | MIIM.STATE | MIIM.BITMAP; mii.fState = MFS.ENABLED; mii.fType = MFT.STRING; mii.wID = 0; // Application-defined value that identifies the menu item. mii.hSubMenu = **subMenu**.Handle; mii.dwTypeData = Program.ShortTitle; mii.cch = mii.dwTypeData.Length; var bmp = new System.Drawing.Icon(ac.Properties.NeutralResources.MyAppIcon,16,16).ToBitmap(); this.hMyAppSubmenuIcon = bmp.GetHbitmap(); mii.hbmpItem = this.hMyAppSubmenuIcon; mii.cbSize = Marshal.SizeOf(typeof(MENUITEMINFO)); var success = InsertMenuItem(pMenu,ref mii); mii = new MENUITEMINFO(); mii.fMask = MIIM.FTYPE; mii.fType = MFT.SEPARATOR; mii.cbSize = Marshal.SizeOf(mii); success = InsertMenuItem(pMenu,1,ref mii); subMenu的类型为System.Windows.Forms.ContextMenu.通过这种方式,整个上下文菜单在某种程度上是混合的,包括托管和非托管菜单项.到目前为止,我没有看到这个问题;它只是意味着必须以不同方式处理两种菜单项的选择,如下所述…… 将托管项目插入菜单后,ShowContextMenu方法调用TrackPopupMenu.对于Shell菜单项,已编写的类负责处理它们的选择.对于我自己的菜单项,我不得不采取额外的步骤,因为TrackPopupMenu是一个Windows API函数,因此它对托管子菜单项的Click事件不能很好地工作.您可以将Click事件处理程序连接到子菜单项,但是当从Shell上下文菜单中选择它们时,它们的Click事件不会触发.我甚至还连接了他们的Click,因为有时我只是自己显示我的托管菜单. 为了响应Shell上下文菜单中的托管菜单项选择而采取操作,我使用了TrackPopupMenu的返回值,它是所选菜单项的资源ID.这就是事情变得有点迂回的地方.创建托管上下文菜单时,每个菜单项都有一个索引.您可以将其与Windows API函数GetMenuItemID一起使用,该函数返回菜单项的资源ID.我从托管的ContextMenu类继承并封装了一个Dictionary,它帮助我从这个资源ID映射到菜单项,稍后在调用TrackPopupMenu之后使用.出于我的目的,这就是调用处理程序所需的全部因为在我的应用程序中,我使用命令模式并在创建菜单时将命令对象存储在菜单项的Tag属性中. (一旦字典给了我正确的菜单项,我就能够通过从Tag中提取命令对象来执行相应的处理程序). 这已经好几天了.如果有人看到漏洞,比如我应该清理过的非托管资源,请提及. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |