OK,看起來是可以自定義菜單項添加到Windows外殼上下文菜單,只需在您的應用程序(不需要做任何事情,會影響整個Windows系統)。以下是我所做的。請記住,此答案應在首先提到的MSDN代碼的上下文中進行。這裏我們再次鏈接:
ShellContextMenu class on MSDN
在這一類,準確地說,方法ShowContextMenu
,是QueryContextMenu
的電話,其目的我學到的是填充菜單的項目 - 在這種情況下,適當的Windows要顯示其上下文菜單的文件/文件夾的外殼菜單項。這一呼籲之後,我加入了下面的代碼添加子菜單和分隔符:
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, 0, true, ref mii);
mii = new MENUITEMINFO();
mii.fMask = MIIM.FTYPE;
mii.fType = MFT.SEPARATOR;
mii.cbSize = Marshal.SizeOf(mii);
success = InsertMenuItem(pMenu, 1, true, ref mii);
子是System.Windows.Forms.ContextMenu
類型。通過這種方式,整個上下文菜單有點混合,由託管菜單項和非託管菜單項組成。到目前爲止,我沒有看到這個問題。它只是意味着處理選擇兩種類型的菜單項必須以不同的方式完成,如下所述......
將管理項目插入菜單後,ShowContextMenu
方法調用TrackPopupMenu
。對於Shell菜單項,已經寫好的類負責處理他們的選擇。對於我自己的菜單項,我必須採取額外的步驟,因爲TrackPopupMenu
是Windows API函數,所以對於託管子菜單項「Click
」事件不起作用。您可以將Click
事件處理程序掛接到您的子菜單項,但是當從Shell上下文菜單中選擇它們時,它們的Click
事件不會觸發。即使有時我只是自己顯示我的管理菜單,我仍然連線他們的Click
。
採取行動以響應於來自殼牌上下文菜單中的管理菜單項選擇,我使用的TrackPopupMenu
返回值,它是被選擇該菜單項的資源ID。這是事情有點迂迴的地方。當創建託管上下文菜單時,每個菜單項都有一個索引。您可以在Windows API函數GetMenuItemID中使用此函數,該函數返回菜單項的資源ID。我從受管理的ContextMenu
類繼承,並封裝了一個Dictionary
,它幫助我從此資源ID映射到菜單項,稍後在調用TrackPopupMenu
後稍後使用。出於我的目的,這就是爲了調用處理程序所需的全部內容,因爲在我的應用程序中,我使用命令模式,並在創建菜單時將命令對象存儲在菜單項的Tag
屬性中。 (一旦字典給了我正確的菜單項,我就能夠通過從Tag
中提取命令對象來執行相應的處理程序)。
這幾天現在運行良好。如果有人發現漏洞,比如我應該清理的非託管資源,請提及。
1:不,我只是在QueryContextMenu中測試一個已命名的互斥體。一個只有你的應用程序創建。 – 2012-07-10 04:44:59
因此,即使我有一個殼牌上下文菜單的句柄,我不能只爲該實例添加它? – 2012-07-10 19:42:14