Statistics
| Branch: | Revision:

root / trunk / Pithos.ShellExtensions / Menus / FileContextMenu.cs @ 5bcf6d70

History | View | Annotate | Download (21.7 kB)

1 d78cbf09 Panagiotis Kanavos
using System;
2 d78cbf09 Panagiotis Kanavos
using System.Collections.Generic;
3 d78cbf09 Panagiotis Kanavos
using System.ComponentModel.Composition;
4 d78cbf09 Panagiotis Kanavos
using System.Diagnostics;
5 d78cbf09 Panagiotis Kanavos
using System.Diagnostics.Contracts;
6 5bcf6d70 Panagiotis Kanavos
using System.Drawing;
7 d78cbf09 Panagiotis Kanavos
using System.Linq;
8 d78cbf09 Panagiotis Kanavos
using System.Runtime.InteropServices;
9 d78cbf09 Panagiotis Kanavos
using System.Runtime.InteropServices.ComTypes;
10 d78cbf09 Panagiotis Kanavos
using System.Text;
11 5bcf6d70 Panagiotis Kanavos
using Pithos.ShellExtensions.Properties;
12 d78cbf09 Panagiotis Kanavos
13 d78cbf09 Panagiotis Kanavos
namespace Pithos.ShellExtensions.Menus
14 d78cbf09 Panagiotis Kanavos
{
15 d78cbf09 Panagiotis Kanavos
    [ClassInterface(ClassInterfaceType.None)]
16 d78cbf09 Panagiotis Kanavos
    [Guid("B1F1405D-94A1-4692-B72F-FC8CAF8B8700"), ComVisible(true)]
17 d78cbf09 Panagiotis Kanavos
    public class FileContextMenu : IShellExtInit, IContextMenu
18 d78cbf09 Panagiotis Kanavos
    {
19 d78cbf09 Panagiotis Kanavos
        private const string MenuHandlername = "CSShellExtContextMenuHandler.FileContextMenuExt";
20 d78cbf09 Panagiotis Kanavos
21 d78cbf09 Panagiotis Kanavos
22 d78cbf09 Panagiotis Kanavos
        private readonly Dictionary<string, MenuItem> _items;
23 d78cbf09 Panagiotis Kanavos
24 d78cbf09 Panagiotis Kanavos
25 5bcf6d70 Panagiotis Kanavos
        [Import]
26 5bcf6d70 Panagiotis Kanavos
        public FileContext Context { get; set; }
27 5bcf6d70 Panagiotis Kanavos
28 5bcf6d70 Panagiotis Kanavos
        private IntPtr _gotoBitmap=IntPtr.Zero;
29 5bcf6d70 Panagiotis Kanavos
        private IntPtr _versionBitmap = IntPtr.Zero;
30 d78cbf09 Panagiotis Kanavos
31 d78cbf09 Panagiotis Kanavos
        public FileContextMenu()
32 5bcf6d70 Panagiotis Kanavos
        {                        
33 5bcf6d70 Panagiotis Kanavos
            _gotoBitmap = GetBitmapPtr(Resources.MenuGoToPithos);
34 5bcf6d70 Panagiotis Kanavos
            _versionBitmap = GetBitmapPtr(Resources.MenuHistory);
35 5bcf6d70 Panagiotis Kanavos
36 5bcf6d70 Panagiotis Kanavos
37 5bcf6d70 Panagiotis Kanavos
            
38 5bcf6d70 Panagiotis Kanavos
39 d78cbf09 Panagiotis Kanavos
            _items = new Dictionary<string, MenuItem>{
40 d78cbf09 Panagiotis Kanavos
                {"gotoPithos",new MenuItem{
41 d78cbf09 Panagiotis Kanavos
                                           MenuText = "&Go to Pithos",
42 d78cbf09 Panagiotis Kanavos
                                            Verb = "gotoPithos",
43 d78cbf09 Panagiotis Kanavos
                                             VerbCanonicalName = "PITHOSGoTo",
44 d78cbf09 Panagiotis Kanavos
                                              VerbHelpText = "Go to Pithos",
45 d78cbf09 Panagiotis Kanavos
                                               MenuDisplayId = 0,
46 5bcf6d70 Panagiotis Kanavos
                                               MenuCommand=OnGotoPithos,
47 5bcf6d70 Panagiotis Kanavos
                                               DisplayFlags=DisplayFlags.All,
48 5bcf6d70 Panagiotis Kanavos
                                               MenuBitmap = _gotoBitmap
49 d78cbf09 Panagiotis Kanavos
                                           }},
50 d78cbf09 Panagiotis Kanavos
                {"prevVersions",new MenuItem{
51 d78cbf09 Panagiotis Kanavos
                                           MenuText = "&Show Previous Versions",
52 d78cbf09 Panagiotis Kanavos
                                            Verb = "prevVersions",
53 d78cbf09 Panagiotis Kanavos
                                             VerbCanonicalName = "PITHOSPrevVersions",
54 d78cbf09 Panagiotis Kanavos
                                              VerbHelpText = "Go to Pithos and display previous versions",
55 d78cbf09 Panagiotis Kanavos
                                               MenuDisplayId = 1,
56 d78cbf09 Panagiotis Kanavos
                                               MenuCommand=OnVerbDisplayFileName,
57 5bcf6d70 Panagiotis Kanavos
                                               DisplayFlags=DisplayFlags.File,
58 5bcf6d70 Panagiotis Kanavos
                                               MenuBitmap=_versionBitmap
59 d78cbf09 Panagiotis Kanavos
                                           }}
60 d78cbf09 Panagiotis Kanavos
            };
61 d78cbf09 Panagiotis Kanavos
62 5bcf6d70 Panagiotis Kanavos
            IoC.Current.Compose(this);
63 5bcf6d70 Panagiotis Kanavos
64 5bcf6d70 Panagiotis Kanavos
65 5bcf6d70 Panagiotis Kanavos
        }
66 5bcf6d70 Panagiotis Kanavos
67 5bcf6d70 Panagiotis Kanavos
68 5bcf6d70 Panagiotis Kanavos
        ~FileContextMenu()
69 5bcf6d70 Panagiotis Kanavos
        {
70 5bcf6d70 Panagiotis Kanavos
            if (_gotoBitmap != IntPtr.Zero)
71 5bcf6d70 Panagiotis Kanavos
            {
72 5bcf6d70 Panagiotis Kanavos
                NativeMethods.DeleteObject(_gotoBitmap);
73 5bcf6d70 Panagiotis Kanavos
                _gotoBitmap= IntPtr.Zero;
74 5bcf6d70 Panagiotis Kanavos
            }
75 5bcf6d70 Panagiotis Kanavos
            if (_versionBitmap != IntPtr.Zero)
76 5bcf6d70 Panagiotis Kanavos
            {
77 5bcf6d70 Panagiotis Kanavos
                NativeMethods.DeleteObject(_versionBitmap);
78 5bcf6d70 Panagiotis Kanavos
                _versionBitmap = IntPtr.Zero;
79 5bcf6d70 Panagiotis Kanavos
            }
80 5bcf6d70 Panagiotis Kanavos
81 5bcf6d70 Panagiotis Kanavos
        }
82 5bcf6d70 Panagiotis Kanavos
        private static IntPtr GetBitmapPtr(Bitmap gotoBitmap)
83 5bcf6d70 Panagiotis Kanavos
        {
84 5bcf6d70 Panagiotis Kanavos
            gotoBitmap.MakeTransparent(gotoBitmap.GetPixel(0, 0));
85 5bcf6d70 Panagiotis Kanavos
            var hbitmap = gotoBitmap.GetHbitmap();
86 5bcf6d70 Panagiotis Kanavos
            return hbitmap;
87 d78cbf09 Panagiotis Kanavos
        }
88 d78cbf09 Panagiotis Kanavos
89 d78cbf09 Panagiotis Kanavos
90 d78cbf09 Panagiotis Kanavos
        void OnVerbDisplayFileName(IntPtr hWnd)
91 d78cbf09 Panagiotis Kanavos
        {
92 d78cbf09 Panagiotis Kanavos
            string message = String.Format("The selected file is {0}\r\n\r\nThe selected Path is {1}",
93 d78cbf09 Panagiotis Kanavos
                                           Context.CurrentFile,
94 d78cbf09 Panagiotis Kanavos
                                           Context.CurrentFolder);
95 d78cbf09 Panagiotis Kanavos
96 d78cbf09 Panagiotis Kanavos
            System.Windows.Forms.MessageBox.Show(
97 d78cbf09 Panagiotis Kanavos
                message,
98 d78cbf09 Panagiotis Kanavos
                "CSShellExtContextMenuHandler");
99 d78cbf09 Panagiotis Kanavos
            NativeMethods.SHChangeNotify(HChangeNotifyEventID.SHCNE_ASSOCCHANGED, HChangeNotifyFlags.SHCNF_IDLIST,
100 d78cbf09 Panagiotis Kanavos
                                             IntPtr.Zero, IntPtr.Zero);
101 d78cbf09 Panagiotis Kanavos
        }
102 5bcf6d70 Panagiotis Kanavos
103 5bcf6d70 Panagiotis Kanavos
        void OnGotoPithos(IntPtr hWnd)
104 5bcf6d70 Panagiotis Kanavos
        {
105 5bcf6d70 Panagiotis Kanavos
            Context.Settings.Reload();
106 5bcf6d70 Panagiotis Kanavos
            Process.Start(Context.Settings.PithosSite);
107 5bcf6d70 Panagiotis Kanavos
        }
108 d78cbf09 Panagiotis Kanavos
        
109 d78cbf09 Panagiotis Kanavos
110 d78cbf09 Panagiotis Kanavos
        #region Shell Extension Registration
111 d78cbf09 Panagiotis Kanavos
112 d78cbf09 Panagiotis Kanavos
        [ComRegisterFunction]
113 d78cbf09 Panagiotis Kanavos
        public static void Register(Type t)
114 d78cbf09 Panagiotis Kanavos
        {
115 d78cbf09 Panagiotis Kanavos
            try
116 d78cbf09 Panagiotis Kanavos
            {
117 d78cbf09 Panagiotis Kanavos
                ShellExtReg.RegisterShellExtContextMenuHandler(t.GUID, ".cs",
118 d78cbf09 Panagiotis Kanavos
                    MenuHandlername);
119 d78cbf09 Panagiotis Kanavos
                ShellExtReg.RegisterShellExtContextMenuHandler(t.GUID, "Directory",
120 d78cbf09 Panagiotis Kanavos
                    MenuHandlername);
121 d78cbf09 Panagiotis Kanavos
                ShellExtReg.RegisterShellExtContextMenuHandler(t.GUID, @"Directory\Background",
122 d78cbf09 Panagiotis Kanavos
                    MenuHandlername);
123 d78cbf09 Panagiotis Kanavos
                ShellExtReg.RegisterShellExtContextMenuHandler(t.GUID, "*",
124 d78cbf09 Panagiotis Kanavos
                    MenuHandlername);
125 d78cbf09 Panagiotis Kanavos
126 d78cbf09 Panagiotis Kanavos
                //ShellExtReg.MarkApproved(t.GUID, MenuHandlername);
127 d78cbf09 Panagiotis Kanavos
            }
128 d78cbf09 Panagiotis Kanavos
            catch (Exception ex)
129 d78cbf09 Panagiotis Kanavos
            {
130 d78cbf09 Panagiotis Kanavos
                Console.WriteLine(ex.Message); // Log the error
131 d78cbf09 Panagiotis Kanavos
                throw;  // Re-throw the exception
132 d78cbf09 Panagiotis Kanavos
            }
133 d78cbf09 Panagiotis Kanavos
        }
134 d78cbf09 Panagiotis Kanavos
135 d78cbf09 Panagiotis Kanavos
        [ComUnregisterFunction]
136 d78cbf09 Panagiotis Kanavos
        public static void Unregister(Type t)
137 d78cbf09 Panagiotis Kanavos
        {
138 d78cbf09 Panagiotis Kanavos
            try
139 d78cbf09 Panagiotis Kanavos
            {
140 d78cbf09 Panagiotis Kanavos
                ShellExtReg.UnregisterShellExtContextMenuHandler(t.GUID, ".cs", MenuHandlername);
141 d78cbf09 Panagiotis Kanavos
                ShellExtReg.UnregisterShellExtContextMenuHandler(t.GUID, "Directory", MenuHandlername);
142 d78cbf09 Panagiotis Kanavos
                ShellExtReg.UnregisterShellExtContextMenuHandler(t.GUID, @"Directory\Background", MenuHandlername);
143 d78cbf09 Panagiotis Kanavos
                ShellExtReg.UnregisterShellExtContextMenuHandler(t.GUID, "*", MenuHandlername);
144 d78cbf09 Panagiotis Kanavos
145 d78cbf09 Panagiotis Kanavos
                //ShellExtReg.RemoveApproved(t.GUID, MenuHandlername);
146 d78cbf09 Panagiotis Kanavos
            }
147 d78cbf09 Panagiotis Kanavos
            catch (Exception ex)
148 d78cbf09 Panagiotis Kanavos
            {
149 d78cbf09 Panagiotis Kanavos
                Console.WriteLine(ex.Message); // Log the error
150 d78cbf09 Panagiotis Kanavos
                throw;  // Re-throw the exception
151 d78cbf09 Panagiotis Kanavos
            }
152 d78cbf09 Panagiotis Kanavos
        }
153 d78cbf09 Panagiotis Kanavos
154 d78cbf09 Panagiotis Kanavos
        #endregion
155 d78cbf09 Panagiotis Kanavos
156 d78cbf09 Panagiotis Kanavos
157 d78cbf09 Panagiotis Kanavos
        #region IShellExtInit Members
158 d78cbf09 Panagiotis Kanavos
159 d78cbf09 Panagiotis Kanavos
        /// <summary>
160 d78cbf09 Panagiotis Kanavos
        /// Initialize the context menu handler.
161 d78cbf09 Panagiotis Kanavos
        /// </summary>
162 d78cbf09 Panagiotis Kanavos
        /// <param name="pidlFolder">
163 d78cbf09 Panagiotis Kanavos
        /// A pointer to an ITEMIDLIST structure that uniquely identifies a folder.
164 d78cbf09 Panagiotis Kanavos
        /// </param>
165 d78cbf09 Panagiotis Kanavos
        /// <param name="pDataObj">
166 d78cbf09 Panagiotis Kanavos
        /// A pointer to an IDataObject interface object that can be used to retrieve 
167 d78cbf09 Panagiotis Kanavos
        /// the objects being acted upon.
168 d78cbf09 Panagiotis Kanavos
        /// </param>
169 d78cbf09 Panagiotis Kanavos
        /// <param name="hKeyProgID">
170 d78cbf09 Panagiotis Kanavos
        /// The registry key for the file object or folder type.
171 d78cbf09 Panagiotis Kanavos
        /// </param>
172 d78cbf09 Panagiotis Kanavos
        public void Initialize(IntPtr pidlFolder, IntPtr pDataObj, IntPtr hKeyProgID)
173 d78cbf09 Panagiotis Kanavos
        {
174 d78cbf09 Panagiotis Kanavos
            
175 d78cbf09 Panagiotis Kanavos
            if(pDataObj == IntPtr.Zero && pidlFolder == IntPtr.Zero)
176 d78cbf09 Panagiotis Kanavos
            {
177 d78cbf09 Panagiotis Kanavos
                throw new ArgumentException("pidlFolder and pDataObj shouldn't be null at the same time");
178 d78cbf09 Panagiotis Kanavos
            }
179 d78cbf09 Panagiotis Kanavos
180 d78cbf09 Panagiotis Kanavos
181 d78cbf09 Panagiotis Kanavos
            Trace.Write("Initializing");
182 d78cbf09 Panagiotis Kanavos
183 d78cbf09 Panagiotis Kanavos
            if (pDataObj != IntPtr.Zero)
184 d78cbf09 Panagiotis Kanavos
            {
185 d78cbf09 Panagiotis Kanavos
                Trace.Write("Got a data object");
186 d78cbf09 Panagiotis Kanavos
187 d78cbf09 Panagiotis Kanavos
                FORMATETC fe = new FORMATETC();
188 d78cbf09 Panagiotis Kanavos
                fe.cfFormat = (short)CLIPFORMAT.CF_HDROP;
189 d78cbf09 Panagiotis Kanavos
                fe.ptd = IntPtr.Zero;
190 d78cbf09 Panagiotis Kanavos
                fe.dwAspect = DVASPECT.DVASPECT_CONTENT;
191 d78cbf09 Panagiotis Kanavos
                fe.lindex = -1;
192 d78cbf09 Panagiotis Kanavos
                fe.tymed = TYMED.TYMED_HGLOBAL;
193 d78cbf09 Panagiotis Kanavos
                STGMEDIUM stm = new STGMEDIUM();
194 d78cbf09 Panagiotis Kanavos
195 d78cbf09 Panagiotis Kanavos
                // The pDataObj pointer contains the objects being acted upon. In this 
196 d78cbf09 Panagiotis Kanavos
                // example, we get an HDROP handle for enumerating the selected files 
197 d78cbf09 Panagiotis Kanavos
                // and folders.
198 d78cbf09 Panagiotis Kanavos
                IDataObject dataObject = (IDataObject)Marshal.GetObjectForIUnknown(pDataObj);
199 d78cbf09 Panagiotis Kanavos
                dataObject.GetData(ref fe, out stm);
200 d78cbf09 Panagiotis Kanavos
201 d78cbf09 Panagiotis Kanavos
                try
202 d78cbf09 Panagiotis Kanavos
                {
203 d78cbf09 Panagiotis Kanavos
                    // Get an HDROP handle.
204 d78cbf09 Panagiotis Kanavos
                    IntPtr hDrop = stm.unionmember;
205 d78cbf09 Panagiotis Kanavos
                    if (hDrop == IntPtr.Zero)
206 d78cbf09 Panagiotis Kanavos
                    {
207 d78cbf09 Panagiotis Kanavos
                        throw new ArgumentException();
208 d78cbf09 Panagiotis Kanavos
                    }
209 d78cbf09 Panagiotis Kanavos
210 d78cbf09 Panagiotis Kanavos
                    // Determine how many files are involved in this operation.
211 d78cbf09 Panagiotis Kanavos
                    uint nFiles = NativeMethods.DragQueryFile(hDrop, UInt32.MaxValue, null, 0);
212 d78cbf09 Panagiotis Kanavos
213 d78cbf09 Panagiotis Kanavos
                    Trace.Write(String.Format("Got {0} files", nFiles));
214 d78cbf09 Panagiotis Kanavos
                    // This code sample displays the custom context menu item when only 
215 d78cbf09 Panagiotis Kanavos
                    // one file is selected. 
216 d78cbf09 Panagiotis Kanavos
                    if (nFiles == 1)
217 d78cbf09 Panagiotis Kanavos
                    {
218 d78cbf09 Panagiotis Kanavos
                        // Get the path of the file.
219 d78cbf09 Panagiotis Kanavos
                        var fileName = new StringBuilder(260);
220 d78cbf09 Panagiotis Kanavos
                        if (0 == NativeMethods.DragQueryFile(hDrop, 0, fileName,
221 d78cbf09 Panagiotis Kanavos
                                                             fileName.Capacity))
222 d78cbf09 Panagiotis Kanavos
                        {
223 d78cbf09 Panagiotis Kanavos
                            Marshal.ThrowExceptionForHR(WinError.E_FAIL);
224 d78cbf09 Panagiotis Kanavos
                        }
225 d78cbf09 Panagiotis Kanavos
                        Context.CurrentFile = fileName.ToString();
226 d78cbf09 Panagiotis Kanavos
                    }
227 d78cbf09 Panagiotis Kanavos
                    /* else
228 d78cbf09 Panagiotis Kanavos
                     {
229 d78cbf09 Panagiotis Kanavos
                         Marshal.ThrowExceptionForHR(WinError.E_FAIL);
230 d78cbf09 Panagiotis Kanavos
                     }*/
231 d78cbf09 Panagiotis Kanavos
232 d78cbf09 Panagiotis Kanavos
                    // [-or-]
233 d78cbf09 Panagiotis Kanavos
234 d78cbf09 Panagiotis Kanavos
                    // Enumerate the selected files and folders.
235 d78cbf09 Panagiotis Kanavos
                    //if (nFiles > 0)
236 d78cbf09 Panagiotis Kanavos
                    //{
237 d78cbf09 Panagiotis Kanavos
                    //    StringCollection selectedFiles = new StringCollection();
238 d78cbf09 Panagiotis Kanavos
                    //    StringBuilder fileName = new StringBuilder(260);
239 d78cbf09 Panagiotis Kanavos
                    //    for (uint i = 0; i < nFiles; i++)
240 d78cbf09 Panagiotis Kanavos
                    //    {
241 d78cbf09 Panagiotis Kanavos
                    //        // Get the next file name.
242 d78cbf09 Panagiotis Kanavos
                    //        if (0 != NativeMethods.DragQueryFile(hDrop, i, fileName,
243 d78cbf09 Panagiotis Kanavos
                    //            fileName.Capacity))
244 d78cbf09 Panagiotis Kanavos
                    //        {
245 d78cbf09 Panagiotis Kanavos
                    //            // Add the file name to the list.
246 d78cbf09 Panagiotis Kanavos
                    //            selectedFiles.Add(fileName.ToString());
247 d78cbf09 Panagiotis Kanavos
                    //        }
248 d78cbf09 Panagiotis Kanavos
                    //    }
249 d78cbf09 Panagiotis Kanavos
                    //
250 d78cbf09 Panagiotis Kanavos
                    //    // If we did not find any files we can work with, throw 
251 d78cbf09 Panagiotis Kanavos
                    //    // exception.
252 d78cbf09 Panagiotis Kanavos
                    //    if (selectedFiles.Count == 0)
253 d78cbf09 Panagiotis Kanavos
                    //    {
254 d78cbf09 Panagiotis Kanavos
                    //        Marshal.ThrowExceptionForHR(WinError.E_FAIL);
255 d78cbf09 Panagiotis Kanavos
                    //    }
256 d78cbf09 Panagiotis Kanavos
                    //}
257 d78cbf09 Panagiotis Kanavos
                    //else
258 d78cbf09 Panagiotis Kanavos
                    //{
259 d78cbf09 Panagiotis Kanavos
                    //    Marshal.ThrowExceptionForHR(WinError.E_FAIL);
260 d78cbf09 Panagiotis Kanavos
                    //}
261 d78cbf09 Panagiotis Kanavos
                }
262 d78cbf09 Panagiotis Kanavos
                finally
263 d78cbf09 Panagiotis Kanavos
                {
264 d78cbf09 Panagiotis Kanavos
                    NativeMethods.ReleaseStgMedium(ref stm);
265 d78cbf09 Panagiotis Kanavos
                }
266 d78cbf09 Panagiotis Kanavos
            }
267 d78cbf09 Panagiotis Kanavos
268 d78cbf09 Panagiotis Kanavos
            if (pidlFolder != IntPtr.Zero)
269 d78cbf09 Panagiotis Kanavos
            {
270 d78cbf09 Panagiotis Kanavos
                Trace.Write("Got a folder");
271 d78cbf09 Panagiotis Kanavos
                StringBuilder path = new StringBuilder();
272 d78cbf09 Panagiotis Kanavos
                if (!NativeMethods.SHGetPathFromIDList(pidlFolder, path))
273 d78cbf09 Panagiotis Kanavos
                {
274 d78cbf09 Panagiotis Kanavos
                    int error = Marshal.GetHRForLastWin32Error();
275 d78cbf09 Panagiotis Kanavos
                    Marshal.ThrowExceptionForHR(error);
276 d78cbf09 Panagiotis Kanavos
                }
277 d78cbf09 Panagiotis Kanavos
                Context.CurrentFolder = path.ToString();
278 d78cbf09 Panagiotis Kanavos
                Trace.Write(String.Format("Folder is {0}", Context.CurrentFolder));
279 d78cbf09 Panagiotis Kanavos
            }
280 d78cbf09 Panagiotis Kanavos
        }
281 d78cbf09 Panagiotis Kanavos
282 d78cbf09 Panagiotis Kanavos
        #endregion
283 d78cbf09 Panagiotis Kanavos
284 d78cbf09 Panagiotis Kanavos
285 d78cbf09 Panagiotis Kanavos
        #region IContextMenu Members
286 d78cbf09 Panagiotis Kanavos
287 d78cbf09 Panagiotis Kanavos
        /// <summary>
288 d78cbf09 Panagiotis Kanavos
        /// Add commands to a shortcut menu.
289 d78cbf09 Panagiotis Kanavos
        /// </summary>
290 d78cbf09 Panagiotis Kanavos
        /// <param name="hMenu">A handle to the shortcut menu.</param>
291 d78cbf09 Panagiotis Kanavos
        /// <param name="iMenu">
292 d78cbf09 Panagiotis Kanavos
        /// The zero-based position at which to insert the first new menu item.
293 d78cbf09 Panagiotis Kanavos
        /// </param>
294 d78cbf09 Panagiotis Kanavos
        /// <param name="idCmdFirst">
295 d78cbf09 Panagiotis Kanavos
        /// The minimum value that the handler can specify for a menu item ID.
296 d78cbf09 Panagiotis Kanavos
        /// </param>
297 d78cbf09 Panagiotis Kanavos
        /// <param name="idCmdLast">
298 d78cbf09 Panagiotis Kanavos
        /// The maximum value that the handler can specify for a menu item ID.
299 d78cbf09 Panagiotis Kanavos
        /// </param>
300 d78cbf09 Panagiotis Kanavos
        /// <param name="uFlags">
301 d78cbf09 Panagiotis Kanavos
        /// Optional flags that specify how the shortcut menu can be changed.
302 d78cbf09 Panagiotis Kanavos
        /// </param>
303 d78cbf09 Panagiotis Kanavos
        /// <returns>
304 d78cbf09 Panagiotis Kanavos
        /// If successful, returns an HRESULT value that has its severity value set 
305 d78cbf09 Panagiotis Kanavos
        /// to SEVERITY_SUCCESS and its code value set to the offset of the largest 
306 d78cbf09 Panagiotis Kanavos
        /// command identifier that was assigned, plus one.
307 d78cbf09 Panagiotis Kanavos
        /// </returns>
308 d78cbf09 Panagiotis Kanavos
        public int QueryContextMenu(
309 d78cbf09 Panagiotis Kanavos
            IntPtr hMenu,
310 d78cbf09 Panagiotis Kanavos
            uint iMenu,
311 d78cbf09 Panagiotis Kanavos
            uint idCmdFirst,
312 d78cbf09 Panagiotis Kanavos
            uint idCmdLast,
313 d78cbf09 Panagiotis Kanavos
            uint uFlags)
314 d78cbf09 Panagiotis Kanavos
        {
315 d78cbf09 Panagiotis Kanavos
            Trace.Write("Start qcm");
316 d78cbf09 Panagiotis Kanavos
            // If uFlags include CMF_DEFAULTONLY then we should not do anything.
317 d78cbf09 Panagiotis Kanavos
            Trace.Write(String.Format("Flags {0}", uFlags));
318 d78cbf09 Panagiotis Kanavos
319 d78cbf09 Panagiotis Kanavos
            if (((uint)CMF.CMF_DEFAULTONLY & uFlags) != 0)
320 d78cbf09 Panagiotis Kanavos
            {
321 d78cbf09 Panagiotis Kanavos
                Trace.Write("Default only flag, returning");
322 d78cbf09 Panagiotis Kanavos
                return WinError.MAKE_HRESULT(WinError.SEVERITY_SUCCESS, 0, 0);
323 d78cbf09 Panagiotis Kanavos
            }
324 d78cbf09 Panagiotis Kanavos
325 d78cbf09 Panagiotis Kanavos
            if (!Context.IsManaged)
326 d78cbf09 Panagiotis Kanavos
            {
327 d78cbf09 Panagiotis Kanavos
                Trace.Write("Not a PITHOS folder");
328 d78cbf09 Panagiotis Kanavos
                return WinError.MAKE_HRESULT(WinError.SEVERITY_SUCCESS, 0, 0);
329 d78cbf09 Panagiotis Kanavos
            }
330 d78cbf09 Panagiotis Kanavos
331 d78cbf09 Panagiotis Kanavos
            /*
332 d78cbf09 Panagiotis Kanavos
                        if (!selectedFolder.ToLower().Contains("pithos"))
333 d78cbf09 Panagiotis Kanavos
                            return WinError.MAKE_HRESULT(WinError.SEVERITY_SUCCESS, 0, 0);
334 d78cbf09 Panagiotis Kanavos
            */
335 d78cbf09 Panagiotis Kanavos
336 d78cbf09 Panagiotis Kanavos
            // Use either InsertMenu or InsertMenuItem to add menu items.
337 d78cbf09 Panagiotis Kanavos
338 d78cbf09 Panagiotis Kanavos
            uint largestID = 0;
339 d78cbf09 Panagiotis Kanavos
340 d78cbf09 Panagiotis Kanavos
            DisplayFlags itemType = (Context.IsFolder) ? DisplayFlags.Folder : DisplayFlags.File;
341 d78cbf09 Panagiotis Kanavos
342 d78cbf09 Panagiotis Kanavos
            Trace.Write(String.Format("Item Flags {0}", itemType));
343 d78cbf09 Panagiotis Kanavos
344 d78cbf09 Panagiotis Kanavos
            foreach (var menuItem in _items.Values)
345 d78cbf09 Panagiotis Kanavos
            {
346 d78cbf09 Panagiotis Kanavos
                Trace.Write(String.Format("Menu Flags {0}", menuItem.DisplayFlags));
347 d78cbf09 Panagiotis Kanavos
                if ((itemType & menuItem.DisplayFlags) != DisplayFlags.None)
348 d78cbf09 Panagiotis Kanavos
                {
349 d78cbf09 Panagiotis Kanavos
                    Trace.Write("Adding Menu");
350 d78cbf09 Panagiotis Kanavos
351 d78cbf09 Panagiotis Kanavos
                    MENUITEMINFO mii = menuItem.CreateInfo(idCmdFirst);
352 d78cbf09 Panagiotis Kanavos
                    if (!NativeMethods.InsertMenuItem(hMenu, iMenu, true, ref mii))
353 d78cbf09 Panagiotis Kanavos
                    {
354 5bcf6d70 Panagiotis Kanavos
                        var lastError = Marshal.GetLastWin32Error();
355 5bcf6d70 Panagiotis Kanavos
                        var lastErrorHR = Marshal.GetHRForLastWin32Error();
356 5bcf6d70 Panagiotis Kanavos
                        return lastErrorHR;
357 d78cbf09 Panagiotis Kanavos
                    }
358 d78cbf09 Panagiotis Kanavos
                    if (largestID < menuItem.MenuDisplayId)
359 d78cbf09 Panagiotis Kanavos
                        largestID = menuItem.MenuDisplayId;
360 d78cbf09 Panagiotis Kanavos
                }
361 d78cbf09 Panagiotis Kanavos
            }
362 d78cbf09 Panagiotis Kanavos
363 d78cbf09 Panagiotis Kanavos
            Trace.Write("Adding Separator 1");
364 d78cbf09 Panagiotis Kanavos
            // Add a separator.
365 d78cbf09 Panagiotis Kanavos
            MENUITEMINFO sep = new MENUITEMINFO();
366 d78cbf09 Panagiotis Kanavos
            sep.cbSize = (uint)Marshal.SizeOf(sep);
367 d78cbf09 Panagiotis Kanavos
            sep.fMask = MIIM.MIIM_TYPE;
368 d78cbf09 Panagiotis Kanavos
            sep.fType = MFT.MFT_SEPARATOR;
369 d78cbf09 Panagiotis Kanavos
            if (!NativeMethods.InsertMenuItem(hMenu, iMenu, true, ref sep))
370 d78cbf09 Panagiotis Kanavos
            {
371 d78cbf09 Panagiotis Kanavos
                Trace.TraceError("Error adding separator 1\r\n{0}", Marshal.GetLastWin32Error());
372 d78cbf09 Panagiotis Kanavos
                return Marshal.GetHRForLastWin32Error();
373 d78cbf09 Panagiotis Kanavos
            }
374 d78cbf09 Panagiotis Kanavos
375 d78cbf09 Panagiotis Kanavos
376 d78cbf09 Panagiotis Kanavos
377 d78cbf09 Panagiotis Kanavos
378 d78cbf09 Panagiotis Kanavos
            Trace.Write("Menus added");
379 d78cbf09 Panagiotis Kanavos
            // Return an HRESULT value with the severity set to SEVERITY_SUCCESS. 
380 d78cbf09 Panagiotis Kanavos
            // Set the code value to the offset of the largest command identifier 
381 d78cbf09 Panagiotis Kanavos
            // that was assigned, plus one (1).
382 d78cbf09 Panagiotis Kanavos
            return WinError.MAKE_HRESULT(WinError.SEVERITY_SUCCESS, 0,
383 d78cbf09 Panagiotis Kanavos
                largestID + 1);
384 d78cbf09 Panagiotis Kanavos
        }
385 d78cbf09 Panagiotis Kanavos
386 d78cbf09 Panagiotis Kanavos
        /// <summary>
387 d78cbf09 Panagiotis Kanavos
        /// Carry out the command associated with a shortcut menu item.
388 d78cbf09 Panagiotis Kanavos
        /// </summary>
389 d78cbf09 Panagiotis Kanavos
        /// <param name="pici">
390 d78cbf09 Panagiotis Kanavos
        /// A pointer to a CMINVOKECOMMANDINFO or CMINVOKECOMMANDINFOEX structure 
391 d78cbf09 Panagiotis Kanavos
        /// containing information about the command. 
392 d78cbf09 Panagiotis Kanavos
        /// </param>
393 d78cbf09 Panagiotis Kanavos
        public void InvokeCommand(IntPtr pici)
394 d78cbf09 Panagiotis Kanavos
        {
395 d78cbf09 Panagiotis Kanavos
            bool isUnicode = false;
396 d78cbf09 Panagiotis Kanavos
397 d78cbf09 Panagiotis Kanavos
            // Determine which structure is being passed in, CMINVOKECOMMANDINFO or 
398 d78cbf09 Panagiotis Kanavos
            // CMINVOKECOMMANDINFOEX based on the cbSize member of lpcmi. Although 
399 d78cbf09 Panagiotis Kanavos
            // the lpcmi parameter is declared in Shlobj.h as a CMINVOKECOMMANDINFO 
400 d78cbf09 Panagiotis Kanavos
            // structure, in practice it often points to a CMINVOKECOMMANDINFOEX 
401 d78cbf09 Panagiotis Kanavos
            // structure. This struct is an extended version of CMINVOKECOMMANDINFO 
402 d78cbf09 Panagiotis Kanavos
            // and has additional members that allow Unicode strings to be passed.
403 d78cbf09 Panagiotis Kanavos
            CMINVOKECOMMANDINFO ici = (CMINVOKECOMMANDINFO)Marshal.PtrToStructure(
404 d78cbf09 Panagiotis Kanavos
                pici, typeof(CMINVOKECOMMANDINFO));
405 d78cbf09 Panagiotis Kanavos
            CMINVOKECOMMANDINFOEX iciex = new CMINVOKECOMMANDINFOEX();
406 d78cbf09 Panagiotis Kanavos
            if (ici.cbSize == Marshal.SizeOf(typeof(CMINVOKECOMMANDINFOEX)))
407 d78cbf09 Panagiotis Kanavos
            {
408 d78cbf09 Panagiotis Kanavos
                if ((ici.fMask & CMIC.CMIC_MASK_UNICODE) != 0)
409 d78cbf09 Panagiotis Kanavos
                {
410 d78cbf09 Panagiotis Kanavos
                    isUnicode = true;
411 d78cbf09 Panagiotis Kanavos
                    iciex = (CMINVOKECOMMANDINFOEX)Marshal.PtrToStructure(pici,
412 d78cbf09 Panagiotis Kanavos
                        typeof(CMINVOKECOMMANDINFOEX));
413 d78cbf09 Panagiotis Kanavos
                }
414 d78cbf09 Panagiotis Kanavos
            }
415 d78cbf09 Panagiotis Kanavos
416 d78cbf09 Panagiotis Kanavos
            // Determines whether the command is identified by its offset or verb.
417 d78cbf09 Panagiotis Kanavos
            // There are two ways to identify commands:
418 d78cbf09 Panagiotis Kanavos
            // 
419 d78cbf09 Panagiotis Kanavos
            //   1) The command's verb string 
420 d78cbf09 Panagiotis Kanavos
            //   2) The command's identifier offset
421 d78cbf09 Panagiotis Kanavos
            // 
422 d78cbf09 Panagiotis Kanavos
            // If the high-order word of lpcmi->lpVerb (for the ANSI case) or 
423 d78cbf09 Panagiotis Kanavos
            // lpcmi->lpVerbW (for the Unicode case) is nonzero, lpVerb or lpVerbW 
424 d78cbf09 Panagiotis Kanavos
            // holds a verb string. If the high-order word is zero, the command 
425 d78cbf09 Panagiotis Kanavos
            // offset is in the low-order word of lpcmi->lpVerb.
426 d78cbf09 Panagiotis Kanavos
427 d78cbf09 Panagiotis Kanavos
            // For the ANSI case, if the high-order word is not zero, the command's 
428 d78cbf09 Panagiotis Kanavos
            // verb string is in lpcmi->lpVerb. 
429 d78cbf09 Panagiotis Kanavos
            if (!isUnicode && NativeMethods.HighWord(ici.verb.ToInt32()) != 0)
430 d78cbf09 Panagiotis Kanavos
            {
431 d78cbf09 Panagiotis Kanavos
                // Is the verb supported by this context menu extension?
432 d78cbf09 Panagiotis Kanavos
                string verbAnsi = Marshal.PtrToStringAnsi(ici.verb);
433 d78cbf09 Panagiotis Kanavos
                if (_items.ContainsKey(verbAnsi))
434 d78cbf09 Panagiotis Kanavos
                {
435 d78cbf09 Panagiotis Kanavos
                    _items[verbAnsi].MenuCommand(ici.hwnd);
436 d78cbf09 Panagiotis Kanavos
                }
437 d78cbf09 Panagiotis Kanavos
                else
438 d78cbf09 Panagiotis Kanavos
                {
439 d78cbf09 Panagiotis Kanavos
                    // If the verb is not recognized by the context menu handler, it 
440 d78cbf09 Panagiotis Kanavos
                    // must return E_FAIL to allow it to be passed on to the other 
441 d78cbf09 Panagiotis Kanavos
                    // context menu handlers that might implement that verb.
442 d78cbf09 Panagiotis Kanavos
                    Marshal.ThrowExceptionForHR(WinError.E_FAIL);
443 d78cbf09 Panagiotis Kanavos
                }
444 d78cbf09 Panagiotis Kanavos
            }
445 d78cbf09 Panagiotis Kanavos
446 d78cbf09 Panagiotis Kanavos
                // For the Unicode case, if the high-order word is not zero, the 
447 d78cbf09 Panagiotis Kanavos
            // command's verb string is in lpcmi->lpVerbW. 
448 d78cbf09 Panagiotis Kanavos
            else if (isUnicode && NativeMethods.HighWord(iciex.verbW.ToInt32()) != 0)
449 d78cbf09 Panagiotis Kanavos
            {
450 d78cbf09 Panagiotis Kanavos
                // Is the verb supported by this context menu extension?
451 d78cbf09 Panagiotis Kanavos
                string verbUTF = Marshal.PtrToStringUni(iciex.verbW);
452 d78cbf09 Panagiotis Kanavos
                if (_items.ContainsKey(verbUTF))
453 d78cbf09 Panagiotis Kanavos
                {
454 d78cbf09 Panagiotis Kanavos
                    _items[verbUTF].MenuCommand(ici.hwnd);
455 d78cbf09 Panagiotis Kanavos
                }
456 d78cbf09 Panagiotis Kanavos
                else
457 d78cbf09 Panagiotis Kanavos
                {
458 d78cbf09 Panagiotis Kanavos
                    // If the verb is not recognized by the context menu handler, it 
459 d78cbf09 Panagiotis Kanavos
                    // must return E_FAIL to allow it to be passed on to the other 
460 d78cbf09 Panagiotis Kanavos
                    // context menu handlers that might implement that verb.
461 d78cbf09 Panagiotis Kanavos
                    Marshal.ThrowExceptionForHR(WinError.E_FAIL);
462 d78cbf09 Panagiotis Kanavos
                }
463 d78cbf09 Panagiotis Kanavos
            }
464 d78cbf09 Panagiotis Kanavos
465 d78cbf09 Panagiotis Kanavos
                // If the command cannot be identified through the verb string, then 
466 d78cbf09 Panagiotis Kanavos
            // check the identifier offset.
467 d78cbf09 Panagiotis Kanavos
            else
468 d78cbf09 Panagiotis Kanavos
            {
469 d78cbf09 Panagiotis Kanavos
                // Is the command identifier offset supported by this context menu 
470 d78cbf09 Panagiotis Kanavos
                // extension?
471 d78cbf09 Panagiotis Kanavos
                int menuID = NativeMethods.LowWord(ici.verb.ToInt32());
472 d78cbf09 Panagiotis Kanavos
                var menuItem = _items.FirstOrDefault(item => item.Value.MenuDisplayId == menuID).Value;
473 d78cbf09 Panagiotis Kanavos
                if (menuItem != null)
474 d78cbf09 Panagiotis Kanavos
                {
475 d78cbf09 Panagiotis Kanavos
                    menuItem.MenuCommand(ici.hwnd);
476 d78cbf09 Panagiotis Kanavos
                }
477 d78cbf09 Panagiotis Kanavos
                else
478 d78cbf09 Panagiotis Kanavos
                {
479 d78cbf09 Panagiotis Kanavos
                    // If the verb is not recognized by the context menu handler, it 
480 d78cbf09 Panagiotis Kanavos
                    // must return E_FAIL to allow it to be passed on to the other 
481 d78cbf09 Panagiotis Kanavos
                    // context menu handlers that might implement that verb.
482 d78cbf09 Panagiotis Kanavos
                    Marshal.ThrowExceptionForHR(WinError.E_FAIL);
483 d78cbf09 Panagiotis Kanavos
                }
484 d78cbf09 Panagiotis Kanavos
            }
485 d78cbf09 Panagiotis Kanavos
        }
486 d78cbf09 Panagiotis Kanavos
487 d78cbf09 Panagiotis Kanavos
        /// <summary>
488 d78cbf09 Panagiotis Kanavos
        /// Get information about a shortcut menu command, including the help string 
489 d78cbf09 Panagiotis Kanavos
        /// and the language-independent, or canonical, name for the command.
490 d78cbf09 Panagiotis Kanavos
        /// </summary>
491 d78cbf09 Panagiotis Kanavos
        /// <param name="idCmd">Menu command identifier offset.</param>
492 d78cbf09 Panagiotis Kanavos
        /// <param name="uFlags">
493 d78cbf09 Panagiotis Kanavos
        /// Flags specifying the information to return. This parameter can have one 
494 d78cbf09 Panagiotis Kanavos
        /// of the following values: GCS_HELPTEXTA, GCS_HELPTEXTW, GCS_VALIDATEA, 
495 d78cbf09 Panagiotis Kanavos
        /// GCS_VALIDATEW, GCS_VERBA, GCS_VERBW.
496 d78cbf09 Panagiotis Kanavos
        /// </param>
497 d78cbf09 Panagiotis Kanavos
        /// <param name="pReserved">Reserved. Must be IntPtr.Zero</param>
498 d78cbf09 Panagiotis Kanavos
        /// <param name="pszName">
499 d78cbf09 Panagiotis Kanavos
        /// The address of the buffer to receive the null-terminated string being 
500 d78cbf09 Panagiotis Kanavos
        /// retrieved.
501 d78cbf09 Panagiotis Kanavos
        /// </param>
502 d78cbf09 Panagiotis Kanavos
        /// <param name="cchMax">
503 d78cbf09 Panagiotis Kanavos
        /// Size of the buffer, in characters, to receive the null-terminated string.
504 d78cbf09 Panagiotis Kanavos
        /// </param>
505 d78cbf09 Panagiotis Kanavos
        public void GetCommandString(
506 d78cbf09 Panagiotis Kanavos
            UIntPtr idCmd,
507 d78cbf09 Panagiotis Kanavos
            uint uFlags,
508 d78cbf09 Panagiotis Kanavos
            IntPtr pReserved,
509 d78cbf09 Panagiotis Kanavos
            StringBuilder pszName,
510 d78cbf09 Panagiotis Kanavos
            uint cchMax)
511 d78cbf09 Panagiotis Kanavos
        {
512 d78cbf09 Panagiotis Kanavos
            uint menuID = idCmd.ToUInt32();
513 d78cbf09 Panagiotis Kanavos
            var menuItem = _items.FirstOrDefault(item => item.Value.MenuDisplayId == menuID).Value;
514 d78cbf09 Panagiotis Kanavos
            if (menuItem != null)
515 d78cbf09 Panagiotis Kanavos
            {
516 d78cbf09 Panagiotis Kanavos
                switch ((GCS)uFlags)
517 d78cbf09 Panagiotis Kanavos
                {
518 d78cbf09 Panagiotis Kanavos
                    case GCS.GCS_VERBW:
519 d78cbf09 Panagiotis Kanavos
                        if (menuItem.VerbCanonicalName.Length > cchMax - 1)
520 d78cbf09 Panagiotis Kanavos
                        {
521 d78cbf09 Panagiotis Kanavos
                            Marshal.ThrowExceptionForHR(WinError.STRSAFE_E_INSUFFICIENT_BUFFER);
522 d78cbf09 Panagiotis Kanavos
                        }
523 d78cbf09 Panagiotis Kanavos
                        else
524 d78cbf09 Panagiotis Kanavos
                        {
525 d78cbf09 Panagiotis Kanavos
                            pszName.Clear();
526 d78cbf09 Panagiotis Kanavos
                            pszName.Append(menuItem.VerbCanonicalName);
527 d78cbf09 Panagiotis Kanavos
                        }
528 d78cbf09 Panagiotis Kanavos
                        break;
529 d78cbf09 Panagiotis Kanavos
530 d78cbf09 Panagiotis Kanavos
                    case GCS.GCS_HELPTEXTW:
531 d78cbf09 Panagiotis Kanavos
                        if (menuItem.VerbHelpText.Length > cchMax - 1)
532 d78cbf09 Panagiotis Kanavos
                        {
533 d78cbf09 Panagiotis Kanavos
                            Marshal.ThrowExceptionForHR(WinError.STRSAFE_E_INSUFFICIENT_BUFFER);
534 d78cbf09 Panagiotis Kanavos
                        }
535 d78cbf09 Panagiotis Kanavos
                        else
536 d78cbf09 Panagiotis Kanavos
                        {
537 d78cbf09 Panagiotis Kanavos
                            pszName.Clear();
538 d78cbf09 Panagiotis Kanavos
                            pszName.Append(menuItem.VerbHelpText);
539 d78cbf09 Panagiotis Kanavos
                        }
540 d78cbf09 Panagiotis Kanavos
                        break;
541 d78cbf09 Panagiotis Kanavos
                }
542 d78cbf09 Panagiotis Kanavos
            }
543 d78cbf09 Panagiotis Kanavos
        }
544 d78cbf09 Panagiotis Kanavos
545 d78cbf09 Panagiotis Kanavos
        #endregion
546 d78cbf09 Panagiotis Kanavos
    }
547 d78cbf09 Panagiotis Kanavos
}