public static void BuildMenu(Assembly assem, Platform.ShellRightClickContextMenuClass menuClass, InfoStorageAttribute storage, List <string> list, MenuClick onClick) { try { // filter file extensions if required var filter = new List <string>(storage.FileExtensionFilter); var filesList = storage.ExpandFileNames ? BuildFileList(filter, list) : list; if (filesList.Count > 0) { string menuFormatJson = storage.MenuFormat; var jsonReader = new JsonFx.Json.JsonReader(); dynamic menuFormatObject = jsonReader.Read <dynamic>(menuFormatJson); dynamic menuFormatObjectChildren = menuFormatObject.children; AddChildren(assem, menuClass, storage, IntPtr.Zero, menuFormatObjectChildren, filesList, true, onClick); } } catch (Exception e) { MessageBox.Show(e.Message + "\r\n\r\n" + e.StackTrace, "Error whilst creating menu"); } }
static void AddChildren(Assembly assem, Platform.ShellRightClickContextMenuClass menuClass, InfoStorageAttribute storage, IntPtr menu, dynamic children, List <string> selectedFiles, bool isRoot, MenuClick onClick) { for (var i = 0; i < children.Length; ++i) { dynamic item = children[i]; string name = Util.IsJsonProperty(item, "name") ? (string)item.name : "New Menu Item"; // embed image into assembly and reference that System.Drawing.Bitmap bmp = null; IntPtr subMenu = IntPtr.Zero; if (Util.IsJsonProperty(item, "imageResource")) { var resources = assem.GetManifestResourceStream((string)item.imageResource + ".resources"); var rr = new System.Resources.ResourceReader(resources); string resourceType; byte[] resourceData; rr.GetResourceData("image.bmp", out resourceType, out resourceData); // For some reason the resource compiler adds 4 bytes to the start of our data. bmp = new System.Drawing.Bitmap(new System.IO.MemoryStream(resourceData, 4, resourceData.Length - 4)); } if (Util.IsJsonProperty(item, "children")) { subMenu = menuClass.CreateSubMenu(); AddChildren(assem, menuClass, storage, subMenu, item.children, selectedFiles, false, onClick); } int position = i + 1; if (isRoot) { position = Util.IsJsonProperty(item, "position") ? (int)item.position : position; } if (menu == IntPtr.Zero) { // root element if (subMenu == IntPtr.Zero) { uint id = menuClass.InsertMenuItem(name, position, (List <string> s) => { onClick(item, selectedFiles); }); if (bmp != null) { menuClass.SetMenuItemBitmap(id, bmp); } } else { menuClass.InsertSubMenu(subMenu, name, position, bmp); } } else { // sub menu if (subMenu == IntPtr.Zero) { menuClass.InsertMenuItemIntoSubMenu(menu, name, position, bmp, (List <string> s) => { onClick(item, selectedFiles); }); } else { uint id = menuClass.InsertSubMenuIntoSubMenu(menu, subMenu, name, position); if (bmp != null) { menuClass.SetMenuItemBitmap(id, bmp); } } } } }