2012-07-10 48 views
4

在我的.NET Framework 4應用程序中,我顯示文件,文件夾和其他不屬於文件系統的東西。對於文件和文件夾,我設法顯示該項目的Windows Shell上下文菜單,這要歸功於this code on MSDN。 (它仍然無法顯示Carbonite Shell擴展,但我離題了)。僅在我的應用程序中添加到shell上下文菜單

我的奮鬥是將我自己的子菜單添加到Shell上下文菜單。我所有的研究都提到了所謂的Shell 擴展,如果我理解正確的話,它是一個系統範圍的變化。我只想在我的應用程序中訪問它時,將其添加到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, 0, true, ref mii); 

,但沒有‘成功’。 (subMenuSystem.Windows.Forms.ContextMenuStrip我前面創建的。)

我的問題是:

  1. 我是正確什麼我試圖從創建一個Shell擴展不同?

  2. 這是否仍被認爲是託管代碼中的危險活動,按照this post

  3. 這其實是怎麼做到的?

+0

1:不,我只是在QueryContextMenu中測試一個已命名的互斥體。一個只有你的應用程序創建。 – 2012-07-10 04:44:59

+0

因此,即使我有一個殼牌上下文菜單的句柄,我不能只爲該實例添加它? – 2012-07-10 19:42:14

回答

1

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中提取命令對象來執行相應的處理程序)。

這幾天現在運行良好。如果有人發現漏洞,比如我應該清理的非託管資源,請提及。

相關問題