2 using System.Diagnostics;
5 using System.Runtime.InteropServices;
6 using System.Runtime.InteropServices.ComTypes;
9 namespace Pithos.ShellExtensions
11 #region Shell Interfaces
21 [Guid("0C6C4200-C589-11D0-999A-00C04FD655E1")]
22 [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
23 public interface IShellIconOverlayIdentifier
28 [MarshalAs(UnmanagedType.LPWStr)] string path,
34 IntPtr iconFileBuffer,
35 int iconFileBufferSize,
47 [ComImport(), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
48 [Guid("000214e8-0000-0000-c000-000000000046")]
49 internal interface IShellExtInit
52 IntPtr /*LPCITEMIDLIST*/ pidlFolder,
53 IntPtr /*LPDATAOBJECT*/ pDataObj,
54 IntPtr /*HKEY*/ hKeyProgID);
58 [ComImport(), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
59 [Guid("000214e4-0000-0000-c000-000000000046")]
60 internal interface IContextMenu
64 IntPtr /*HMENU*/ hMenu,
70 void InvokeCommand(IntPtr pici);
72 void GetCommandString(
76 StringBuilder pszName,
83 #region Shell Registration
85 internal class ShellExtReg
87 private const string _approvedKey = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Shell Extensions\Approved";
89 public static void RegisterIconOverlayIdentifier(Guid clsid,
92 if (clsid == Guid.Empty)
94 throw new ArgumentException("clsid must not be empty");
96 if (string.IsNullOrEmpty(friendlyName))
98 throw new ArgumentException("friendlyName must not be null or empty");
101 // Create the key HKLM\SOFTWARE\TortoiseOverlays\<IconName>\Pithos={<CLSID>}.
102 string keyName = string.Format(@"SOFTWARE\TortoiseOverlays\{0}",
104 using (RegistryKey key = Registry.LocalMachine.OpenSubKey(keyName,true))
106 // Set the default value of the key.
107 if (key != null)//&& !string.IsNullOrEmpty(clsid.ToString("B")))
109 key.SetValue("Pithos", clsid.ToString("B"),RegistryValueKind.String);
114 internal static void UnregisterIconOverlayIdentifier(Guid clsid,
119 throw new ArgumentException("clsid must not be null");
121 if (string.IsNullOrEmpty(friendlyName))
123 throw new ArgumentException("friendlyName must not be null or empty");
127 string keyName = string.Format(@"SOFTWARE\TortoiseOverlays\{0}",
129 using (RegistryKey key = Registry.LocalMachine.OpenSubKey(keyName, true))
131 // Set the default value of the key.
132 if (key != null)//&& !string.IsNullOrEmpty(clsid.ToString("B")))
134 key.DeleteValue("Pithos");
141 /// Register the context menu handler.
143 /// <param name="clsid">The CLSID of the component.</param>
144 /// <param name="fileType">
145 /// The file type that the context menu handler is associated with. For
146 /// example, '*' means all file types; '.txt' means all .txt files. The
147 /// parameter must not be NULL or an empty string.
149 /// <param name="friendlyName">The friendly name of the component.</param>
150 public static void RegisterShellExtContextMenuHandler(Guid clsid,
151 string fileType, string friendlyName)
153 if (clsid == Guid.Empty)
155 throw new ArgumentException("clsid must not be empty");
157 if (string.IsNullOrEmpty(fileType))
159 throw new ArgumentException("fileType must not be null or empty");
162 // If fileType starts with '.', try to read the default value of the
163 // HKCR\<File Type> key which contains the ProgID to which the file type
165 if (fileType.StartsWith("."))
167 using (RegistryKey key = Registry.ClassesRoot.OpenSubKey(fileType))
171 // If the key exists and its default value is not empty, use
172 // the ProgID as the file type.
173 string defaultVal = key.GetValue(null) as string;
174 if (!string.IsNullOrEmpty(defaultVal))
176 fileType = defaultVal;
182 // Create the key HKCR\<File Type>\shellex\ContextMenuHandlers\{<CLSID>}.
183 string keyName = string.Format(@"{0}\shellex\ContextMenuHandlers\{1}",
184 fileType, friendlyName);
185 using (RegistryKey key = Registry.ClassesRoot.CreateSubKey(keyName))
187 // Set the default value of the key.
188 if (key != null)//&& !string.IsNullOrEmpty(clsid.ToString("B")))
190 key.SetValue(null, clsid.ToString("B"));
196 /// Unregister the context menu handler.
198 /// <param name="clsid">The CLSID of the component.</param>
199 /// <param name="fileType">
200 /// The file type that the context menu handler is associated with. For
201 /// example, '*' means all file types; '.txt' means all .txt files. The
202 /// parameter must not be NULL or an empty string.
204 public static void UnregisterShellExtContextMenuHandler(Guid clsid,
205 string fileType, string friendlyName)
209 throw new ArgumentException("clsid must not be null");
211 if (string.IsNullOrEmpty(fileType))
213 throw new ArgumentException("fileType must not be null or empty");
216 // If fileType starts with '.', try to read the default value of the
217 // HKCR\<File Type> key which contains the ProgID to which the file type
219 if (fileType.StartsWith("."))
221 using (RegistryKey key = Registry.ClassesRoot.OpenSubKey(fileType))
225 // If the key exists and its default value is not empty, use
226 // the ProgID as the file type.
227 string defaultVal = key.GetValue(null) as string;
228 if (!string.IsNullOrEmpty(defaultVal))
230 fileType = defaultVal;
236 // Remove the key HKCR\<File Type>\shellex\ContextMenuHandlers\{<CLSID>}.
237 string keyName = string.Format(@"{0}\shellex\ContextMenuHandlers\{1}",
238 fileType, friendlyName);
239 Registry.ClassesRoot.DeleteSubKeyTree(keyName, false);
242 public static void MarkApproved(Guid guid, string friendlyName)
244 Debug.WriteLine(String.Format("Marking approved {0} {1}", guid, friendlyName), LogCategories.Shell);
245 using (RegistryKey key = Registry.LocalMachine.OpenSubKey(_approvedKey))
247 // Set the default value of the key.
248 if (key != null)//&& !string.IsNullOrEmpty(clsid.ToString("B")))
250 key.SetValue(guid.ToString("B"), friendlyName, RegistryValueKind.String);
254 Debug.WriteLine("Error - failed to open key " + _approvedKey,LogCategories.Shell);
259 public static void RemoveApproved(Guid guid)
261 using (RegistryKey key = Registry.LocalMachine.OpenSubKey(_approvedKey))
263 // Set the default value of the key.
264 if (key != null)//&& !string.IsNullOrEmpty(clsid.ToString("B")))
266 key.DeleteValue(guid.ToString("B"), false);
270 Debug.WriteLine("Error - failed to open key " + _approvedKey, LogCategories.Shell);
279 #region Enums & Structs
281 #region enum HChangeNotifyEventID
283 /// Describes the event that has occurred.
284 /// Typically, only one event is specified at a time.
285 /// If more than one event is specified, the values contained
286 /// in the <i>dwItem1</i> and <i>dwItem2</i>
287 /// parameters must be the same, respectively, for all specified events.
288 /// This parameter can be one or more of the following values.
291 /// <para><b>Windows NT/2000/XP:</b> <i>dwItem2</i> contains the index
292 /// in the system image list that has changed.
293 /// <i>dwItem1</i> is not used and should be <see langword="null"/>.</para>
294 /// <para><b>Windows 95/98:</b> <i>dwItem1</i> contains the index
295 /// in the system image list that has changed.
296 /// <i>dwItem2</i> is not used and should be <see langword="null"/>.</para>
299 enum HChangeNotifyEventID
302 /// All events have occurred.
304 SHCNE_ALLEVENTS = 0x7FFFFFFF,
307 /// A file type association has changed. <see cref="HChangeNotifyFlags.SHCNF_IDLIST"/>
308 /// must be specified in the <i>uFlags</i> parameter.
309 /// <i>dwItem1</i> and <i>dwItem2</i> are not used and must be <see langword="null"/>.
311 SHCNE_ASSOCCHANGED = 0x08000000,
314 /// The attributes of an item or folder have changed.
315 /// <see cref="HChangeNotifyFlags.SHCNF_IDLIST"/> or
316 /// <see cref="HChangeNotifyFlags.SHCNF_PATH"/> must be specified in <i>uFlags</i>.
317 /// <i>dwItem1</i> contains the item or folder that has changed.
318 /// <i>dwItem2</i> is not used and should be <see langword="null"/>.
320 SHCNE_ATTRIBUTES = 0x00000800,
323 /// A nonfolder item has been created.
324 /// <see cref="HChangeNotifyFlags.SHCNF_IDLIST"/> or
325 /// <see cref="HChangeNotifyFlags.SHCNF_PATH"/> must be specified in <i>uFlags</i>.
326 /// <i>dwItem1</i> contains the item that was created.
327 /// <i>dwItem2</i> is not used and should be <see langword="null"/>.
329 SHCNE_CREATE = 0x00000002,
332 /// A nonfolder item has been deleted.
333 /// <see cref="HChangeNotifyFlags.SHCNF_IDLIST"/> or
334 /// <see cref="HChangeNotifyFlags.SHCNF_PATH"/> must be specified in <i>uFlags</i>.
335 /// <i>dwItem1</i> contains the item that was deleted.
336 /// <i>dwItem2</i> is not used and should be <see langword="null"/>.
338 SHCNE_DELETE = 0x00000004,
341 /// A drive has been added.
342 /// <see cref="HChangeNotifyFlags.SHCNF_IDLIST"/> or
343 /// <see cref="HChangeNotifyFlags.SHCNF_PATH"/> must be specified in <i>uFlags</i>.
344 /// <i>dwItem1</i> contains the root of the drive that was added.
345 /// <i>dwItem2</i> is not used and should be <see langword="null"/>.
347 SHCNE_DRIVEADD = 0x00000100,
350 /// A drive has been added and the Shell should create a new window for the drive.
351 /// <see cref="HChangeNotifyFlags.SHCNF_IDLIST"/> or
352 /// <see cref="HChangeNotifyFlags.SHCNF_PATH"/> must be specified in <i>uFlags</i>.
353 /// <i>dwItem1</i> contains the root of the drive that was added.
354 /// <i>dwItem2</i> is not used and should be <see langword="null"/>.
356 SHCNE_DRIVEADDGUI = 0x00010000,
359 /// A drive has been removed. <see cref="HChangeNotifyFlags.SHCNF_IDLIST"/> or
360 /// <see cref="HChangeNotifyFlags.SHCNF_PATH"/> must be specified in <i>uFlags</i>.
361 /// <i>dwItem1</i> contains the root of the drive that was removed.
362 /// <i>dwItem2</i> is not used and should be <see langword="null"/>.
364 SHCNE_DRIVEREMOVED = 0x00000080,
367 /// Not currently used.
369 SHCNE_EXTENDED_EVENT = 0x04000000,
372 /// The amount of free space on a drive has changed.
373 /// <see cref="HChangeNotifyFlags.SHCNF_IDLIST"/> or
374 /// <see cref="HChangeNotifyFlags.SHCNF_PATH"/> must be specified in <i>uFlags</i>.
375 /// <i>dwItem1</i> contains the root of the drive on which the free space changed.
376 /// <i>dwItem2</i> is not used and should be <see langword="null"/>.
378 SHCNE_FREESPACE = 0x00040000,
381 /// Storage media has been inserted into a drive.
382 /// <see cref="HChangeNotifyFlags.SHCNF_IDLIST"/> or
383 /// <see cref="HChangeNotifyFlags.SHCNF_PATH"/> must be specified in <i>uFlags</i>.
384 /// <i>dwItem1</i> contains the root of the drive that contains the new media.
385 /// <i>dwItem2</i> is not used and should be <see langword="null"/>.
387 SHCNE_MEDIAINSERTED = 0x00000020,
390 /// Storage media has been removed from a drive.
391 /// <see cref="HChangeNotifyFlags.SHCNF_IDLIST"/> or
392 /// <see cref="HChangeNotifyFlags.SHCNF_PATH"/> must be specified in <i>uFlags</i>.
393 /// <i>dwItem1</i> contains the root of the drive from which the media was removed.
394 /// <i>dwItem2</i> is not used and should be <see langword="null"/>.
396 SHCNE_MEDIAREMOVED = 0x00000040,
399 /// A folder has been created. <see cref="HChangeNotifyFlags.SHCNF_IDLIST"/>
400 /// or <see cref="HChangeNotifyFlags.SHCNF_PATH"/> must be specified in <i>uFlags</i>.
401 /// <i>dwItem1</i> contains the folder that was created.
402 /// <i>dwItem2</i> is not used and should be <see langword="null"/>.
404 SHCNE_MKDIR = 0x00000008,
407 /// A folder on the local computer is being shared via the network.
408 /// <see cref="HChangeNotifyFlags.SHCNF_IDLIST"/> or
409 /// <see cref="HChangeNotifyFlags.SHCNF_PATH"/> must be specified in <i>uFlags</i>.
410 /// <i>dwItem1</i> contains the folder that is being shared.
411 /// <i>dwItem2</i> is not used and should be <see langword="null"/>.
413 SHCNE_NETSHARE = 0x00000200,
416 /// A folder on the local computer is no longer being shared via the network.
417 /// <see cref="HChangeNotifyFlags.SHCNF_IDLIST"/> or
418 /// <see cref="HChangeNotifyFlags.SHCNF_PATH"/> must be specified in <i>uFlags</i>.
419 /// <i>dwItem1</i> contains the folder that is no longer being shared.
420 /// <i>dwItem2</i> is not used and should be <see langword="null"/>.
422 SHCNE_NETUNSHARE = 0x00000400,
425 /// The name of a folder has changed.
426 /// <see cref="HChangeNotifyFlags.SHCNF_IDLIST"/> or
427 /// <see cref="HChangeNotifyFlags.SHCNF_PATH"/> must be specified in <i>uFlags</i>.
428 /// <i>dwItem1</i> contains the previous pointer to an item identifier list (PIDL) or name of the folder.
429 /// <i>dwItem2</i> contains the new PIDL or name of the folder.
431 SHCNE_RENAMEFOLDER = 0x00020000,
434 /// The name of a nonfolder item has changed.
435 /// <see cref="HChangeNotifyFlags.SHCNF_IDLIST"/> or
436 /// <see cref="HChangeNotifyFlags.SHCNF_PATH"/> must be specified in <i>uFlags</i>.
437 /// <i>dwItem1</i> contains the previous PIDL or name of the item.
438 /// <i>dwItem2</i> contains the new PIDL or name of the item.
440 SHCNE_RENAMEITEM = 0x00000001,
443 /// A folder has been removed.
444 /// <see cref="HChangeNotifyFlags.SHCNF_IDLIST"/> or
445 /// <see cref="HChangeNotifyFlags.SHCNF_PATH"/> must be specified in <i>uFlags</i>.
446 /// <i>dwItem1</i> contains the folder that was removed.
447 /// <i>dwItem2</i> is not used and should be <see langword="null"/>.
449 SHCNE_RMDIR = 0x00000010,
452 /// The computer has disconnected from a server.
453 /// <see cref="HChangeNotifyFlags.SHCNF_IDLIST"/> or
454 /// <see cref="HChangeNotifyFlags.SHCNF_PATH"/> must be specified in <i>uFlags</i>.
455 /// <i>dwItem1</i> contains the server from which the computer was disconnected.
456 /// <i>dwItem2</i> is not used and should be <see langword="null"/>.
458 SHCNE_SERVERDISCONNECT = 0x00004000,
461 /// The contents of an existing folder have changed,
462 /// but the folder still exists and has not been renamed.
463 /// <see cref="HChangeNotifyFlags.SHCNF_IDLIST"/> or
464 /// <see cref="HChangeNotifyFlags.SHCNF_PATH"/> must be specified in <i>uFlags</i>.
465 /// <i>dwItem1</i> contains the folder that has changed.
466 /// <i>dwItem2</i> is not used and should be <see langword="null"/>.
467 /// If a folder has been created, deleted, or renamed, use SHCNE_MKDIR, SHCNE_RMDIR, or
468 /// SHCNE_RENAMEFOLDER, respectively, instead.
470 SHCNE_UPDATEDIR = 0x00001000,
473 /// An image in the system image list has changed.
474 /// <see cref="HChangeNotifyFlags.SHCNF_DWORD"/> must be specified in <i>uFlags</i>.
476 SHCNE_UPDATEIMAGE = 0x00008000,
479 #endregion // enum HChangeNotifyEventID
481 #region public enum HChangeNotifyFlags
483 /// Flags that indicate the meaning of the <i>dwItem1</i> and <i>dwItem2</i> parameters.
484 /// The uFlags parameter must be one of the following values.
487 public enum HChangeNotifyFlags
490 /// The <i>dwItem1</i> and <i>dwItem2</i> parameters are DWORD values.
492 SHCNF_DWORD = 0x0003,
494 /// <i>dwItem1</i> and <i>dwItem2</i> are the addresses of ITEMIDLIST structures that
495 /// represent the item(s) affected by the change.
496 /// Each ITEMIDLIST must be relative to the desktop folder.
498 SHCNF_IDLIST = 0x0000,
500 /// <i>dwItem1</i> and <i>dwItem2</i> are the addresses of null-terminated strings of
501 /// maximum length MAX_PATH that contain the full path names
502 /// of the items affected by the change.
504 SHCNF_PATHA = 0x0001,
506 /// <i>dwItem1</i> and <i>dwItem2</i> are the addresses of null-terminated strings of
507 /// maximum length MAX_PATH that contain the full path names
508 /// of the items affected by the change.
510 SHCNF_PATHW = 0x0005,
512 /// <i>dwItem1</i> and <i>dwItem2</i> are the addresses of null-terminated strings that
513 /// represent the friendly names of the printer(s) affected by the change.
515 SHCNF_PRINTERA = 0x0002,
517 /// <i>dwItem1</i> and <i>dwItem2</i> are the addresses of null-terminated strings that
518 /// represent the friendly names of the printer(s) affected by the change.
520 SHCNF_PRINTERW = 0x0006,
522 /// The function should not return until the notification
523 /// has been delivered to all affected components.
524 /// As this flag modifies other data-type flags, it cannot by used by itself.
526 SHCNF_FLUSH = 0x1000,
528 /// The function should begin delivering notifications to all affected components
529 /// but should return as soon as the notification process has begun.
530 /// As this flag modifies other data-type flags, it cannot by used by itself.
532 SHCNF_FLUSHNOWAIT = 0x2000
534 #endregion // enum HChangeNotifyFlags
536 internal enum GCS : uint
538 GCS_VERBA = 0x00000000,
539 GCS_HELPTEXTA = 0x00000001,
540 GCS_VALIDATEA = 0x00000002,
541 GCS_VERBW = 0x00000004,
542 GCS_HELPTEXTW = 0x00000005,
543 GCS_VALIDATEW = 0x00000006,
544 GCS_VERBICONW = 0x00000014,
545 GCS_UNICODE = 0x00000004
548 [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
549 internal struct CMINVOKECOMMANDINFO
555 [MarshalAs(UnmanagedType.LPStr)]
556 public string parameters;
557 [MarshalAs(UnmanagedType.LPStr)]
558 public string directory;
560 public uint dwHotKey;
564 [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
565 internal struct CMINVOKECOMMANDINFOEX
571 [MarshalAs(UnmanagedType.LPStr)]
572 public string parameters;
573 [MarshalAs(UnmanagedType.LPStr)]
574 public string directory;
576 public uint dwHotKey;
578 [MarshalAs(UnmanagedType.LPStr)]
581 public string parametersW;
582 public string directoryW;
583 public string titleW;
588 internal enum CMIC : uint
590 CMIC_MASK_ICON = 0x00000010,
591 CMIC_MASK_HOTKEY = 0x00000020,
592 CMIC_MASK_NOASYNC = 0x00000100,
593 CMIC_MASK_FLAG_NO_UI = 0x00000400,
594 CMIC_MASK_UNICODE = 0x00004000,
595 CMIC_MASK_NO_CONSOLE = 0x00008000,
596 CMIC_MASK_ASYNCOK = 0x00100000,
597 CMIC_MASK_NOZONECHECKS = 0x00800000,
598 CMIC_MASK_FLAG_LOG_USAGE = 0x04000000,
599 CMIC_MASK_SHIFT_DOWN = 0x10000000,
600 CMIC_MASK_PTINVOKE = 0x20000000,
601 CMIC_MASK_CONTROL_DOWN = 0x40000000
604 [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
611 internal enum CLIPFORMAT : uint
631 CF_OWNERDISPLAY = 0x0080,
633 CF_DSPBITMAP = 0x0082,
634 CF_DSPMETAFILEPICT = 0x0083,
635 CF_DSPENHMETAFILE = 0x008E,
637 CF_PRIVATEFIRST = 0x0200,
638 CF_PRIVATELAST = 0x02FF,
640 CF_GDIOBJFIRST = 0x0300,
641 CF_GDIOBJLAST = 0x03FF
645 internal enum CMF : uint
647 CMF_NORMAL = 0x00000000,
648 CMF_DEFAULTONLY = 0x00000001,
649 CMF_VERBSONLY = 0x00000002,
650 CMF_EXPLORE = 0x00000004,
651 CMF_NOVERBS = 0x00000008,
652 CMF_CANRENAME = 0x00000010,
653 CMF_NODEFAULT = 0x00000020,
654 CMF_INCLUDESTATIC = 0x00000040,
655 CMF_ITEMMENU = 0x00000080,
656 CMF_EXTENDEDVERBS = 0x00000100,
657 CMF_DISABLEDVERBS = 0x00000200,
658 CMF_ASYNCVERBSTATE = 0x00000400,
659 CMF_OPTIMIZEFORINVOKE = 0x00000800,
660 CMF_SYNCCASCADEMENU = 0x00001000,
661 CMF_DONOTPICKDEFAULT = 0x00002000,
662 CMF_RESERVED = 0xFFFF0000
665 [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
666 internal struct MENUITEMINFO
673 public IntPtr hSubMenu;
674 public IntPtr hbmpChecked;
675 public IntPtr hbmpUnchecked;
676 public UIntPtr dwItemData;
677 public string dwTypeData;
679 public IntPtr hbmpItem;
683 internal enum MIIM : uint
685 MIIM_STATE = 0x00000001,
686 MIIM_ID = 0x00000002,
687 MIIM_SUBMENU = 0x00000004,
688 MIIM_CHECKMARKS = 0x00000008,
689 MIIM_TYPE = 0x00000010,
690 MIIM_DATA = 0x00000020,
691 MIIM_STRING = 0x00000040,
692 MIIM_BITMAP = 0x00000080,
693 MIIM_FTYPE = 0x00000100
696 internal enum MFT : uint
698 MFT_STRING = 0x00000000,
699 MFT_BITMAP = 0x00000004,
700 MFT_MENUBARBREAK = 0x00000020,
701 MFT_MENUBREAK = 0x00000040,
702 MFT_OWNERDRAW = 0x00000100,
703 MFT_RADIOCHECK = 0x00000200,
704 MFT_SEPARATOR = 0x00000800,
705 MFT_RIGHTORDER = 0x00002000,
706 MFT_RIGHTJUSTIFY = 0x00004000
710 internal enum MFS : uint
712 MFS_ENABLED = 0x00000000,
713 MFS_UNCHECKED = 0x00000000,
714 MFS_UNHILITE = 0x00000000,
715 MFS_GRAYED = 0x00000003,
716 MFS_DISABLED = 0x00000003,
717 MFS_CHECKED = 0x00000008,
718 MFS_HILITE = 0x00000080,
719 MFS_DEFAULT = 0x00001000
723 internal enum MF: uint
725 MF_BYCOMMAND = 0x00000000,
726 MF_ENABLED = 0x00000000,
727 MF_DISABLED = 0x00000002,
728 MF_BITMAP = 0x00000004,
729 MF_CHECKED = 0x00000008,
730 MF_BYPOSITION = 0x00000400,
731 MF_SEPARATOR = 0x00000800
737 internal class NativeMethods
740 /// Retrieve the names of dropped files that result from a successful drag-
741 /// and-drop operation.
743 /// <param name="hDrop">
744 /// Identifier of the structure that contains the file names of the dropped
747 /// <param name="iFile">
748 /// Index of the file to query. If the value of this parameter is 0xFFFFFFFF,
749 /// DragQueryFile returns a count of the files dropped.
751 /// <param name="pszFile">
752 /// The address of a buffer that receives the file name of a dropped file
753 /// when the function returns.
755 /// <param name="cch">
756 /// The size, in characters, of the pszFile buffer.
758 /// <returns>A non-zero value indicates a successful call.</returns>
759 [DllImport("shell32", CharSet = CharSet.Unicode)]
760 public static extern uint DragQueryFile(
763 StringBuilder pszFile,
767 /// Free the specified storage medium.
769 /// <param name="pmedium">
770 /// Reference of the storage medium that is to be freed.
772 [DllImport("ole32.dll", CharSet = CharSet.Unicode)]
773 public static extern void ReleaseStgMedium(ref STGMEDIUM pmedium);
776 /// Insert a new menu item at the specified position in a menu.
778 /// <param name="hMenu">
779 /// A handle to the menu in which the new menu item is inserted.
781 /// <param name="uItem">
782 /// The identifier or position of the menu item before which to insert the
783 /// new item. The meaning of this parameter depends on the value of
786 /// <param name="fByPosition">
787 /// Controls the meaning of uItem. If this parameter is false, uItem is a
788 /// menu item identifier. Otherwise, it is a menu item position.
790 /// <param name="mii">
791 /// A reference of a MENUITEMINFO structure that contains information about
792 /// the new menu item.
795 /// If the function succeeds, the return value is true.
797 [DllImport("user32", CharSet = CharSet.Unicode, SetLastError = true)]
798 [return: MarshalAs(UnmanagedType.Bool)]
799 public static extern bool InsertMenuItem(
802 [MarshalAs(UnmanagedType.Bool)]bool fByPosition,
803 ref MENUITEMINFO mii);
805 [DllImport("user32", CharSet = CharSet.Unicode, SetLastError = true)]
806 [return: MarshalAs(UnmanagedType.Bool)]
807 public static extern bool InsertMenu(
815 [DllImport("shell32", CharSet = CharSet.Unicode, SetLastError = true)]
816 [return: MarshalAs(UnmanagedType.Bool)]
817 public static extern bool SHGetPathFromIDList(
819 StringBuilder pszpath);
821 [DllImport("shell32.dll")]
822 public static extern void SHChangeNotify(HChangeNotifyEventID wEventId,
823 HChangeNotifyFlags uFlags,
827 [DllImport("gdi32.dll")]
828 public static extern bool DeleteObject(IntPtr hObject);
832 public static int HighWord(int number)
834 return ((number & 0x80000000) == 0x80000000) ?
835 (number >> 16) : ((number >> 16) & 0xffff);
838 public static int LowWord(int number)
840 return number & 0xffff;
844 internal static class WinError
846 public const int S_OK = 0x0000;
847 public const int S_FALSE = 0x0001;
848 public const int E_FAIL = -2147467259;
849 public const int E_INVALIDARG = -2147024809;
850 public const int E_OUTOFMEMORY = -2147024882;
851 public const int STRSAFE_E_INSUFFICIENT_BUFFER = -2147024774;
853 public const uint SEVERITY_SUCCESS = 0;
854 public const uint SEVERITY_ERROR = 1;
857 /// Create an HRESULT value from component pieces.
859 /// <param name="sev">The severity to be used</param>
860 /// <param name="fac">The facility to be used</param>
861 /// <param name="code">The error number</param>
862 /// <returns>A HRESULT constructed from the above 3 values</returns>
863 public static int MAKE_HRESULT(uint sev, uint fac, uint code)
865 return (int)((sev << 31) | (fac << 16) | code);