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 | } |