#region
/* -----------------------------------------------------------------------
*
*
* Copyright 2011-2012 GRNET S.A. All rights reserved.
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* 1. Redistributions of source code must retain the above
* copyright notice, this list of conditions and the following
* disclaimer.
*
* 2. Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
*
* THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and
* documentation are those of the authors and should not be
* interpreted as representing official policies, either expressed
* or implied, of GRNET S.A.
*
* -----------------------------------------------------------------------
*/
#endregion
using System;
using System.Diagnostics;
using System.Text;
using Microsoft.Win32;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.ComTypes;
namespace Pithos.ShellExtensions
{
#region Shell Interfaces
[Flags]
public enum ISIOI
{
ISIOI_ICONFILE = 1,
ISIOI_ICONINDEX = 2
}
[ComVisible(false)]
[ComImport]
[Guid("0C6C4200-C589-11D0-999A-00C04FD655E1")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IShellIconOverlayIdentifier
{
[PreserveSig]
int IsMemberOf(
[MarshalAs(UnmanagedType.LPWStr)] string path,
uint attributes);
[PreserveSig]
int GetOverlayInfo(
IntPtr iconFileBuffer,
int iconFileBufferSize,
out int iconIndex,
out uint flags);
[PreserveSig]
int GetPriority(
out int priority);
}
[ComImport(), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[Guid("000214e8-0000-0000-c000-000000000046")]
internal interface IShellExtInit
{
void Initialize(
IntPtr /*LPCITEMIDLIST*/ pidlFolder,
IntPtr /*LPDATAOBJECT*/ pDataObj,
IntPtr /*HKEY*/ hKeyProgID);
}
[ComImport(), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[Guid("000214e4-0000-0000-c000-000000000046")]
internal interface IContextMenu
{
[PreserveSig]
int QueryContextMenu(
IntPtr /*HMENU*/ hMenu,
uint iMenu,
uint idCmdFirst,
uint idCmdLast,
uint uFlags);
void InvokeCommand(IntPtr pici);
void GetCommandString(
UIntPtr idCmd,
uint uFlags,
IntPtr pReserved,
StringBuilder pszName,
uint cchMax);
}
#endregion
#region Shell Registration
internal class ShellExtReg
{
private const string _approvedKey = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Shell Extensions\Approved";
public static void RegisterIconOverlayIdentifier(Guid clsid,
string friendlyName)
{
if (clsid == Guid.Empty)
{
throw new ArgumentException("clsid must not be empty");
}
if (string.IsNullOrEmpty(friendlyName))
{
throw new ArgumentException("friendlyName must not be null or empty");
}
// Create the key HKLM\SOFTWARE\TortoiseOverlays\\Pithos={}.
string keyName = string.Format(@"SOFTWARE\TortoiseOverlays\{0}",
friendlyName);
using (RegistryKey key = Registry.LocalMachine.OpenSubKey(keyName,true))
{
// Set the default value of the key.
if (key != null)//&& !string.IsNullOrEmpty(clsid.ToString("B")))
{
key.SetValue("Pithos", clsid.ToString("B"),RegistryValueKind.String);
}
}
}
internal static void UnregisterIconOverlayIdentifier(Guid clsid,
string friendlyName)
{
if (clsid == null)
{
throw new ArgumentException("clsid must not be null");
}
if (string.IsNullOrEmpty(friendlyName))
{
throw new ArgumentException("friendlyName must not be null or empty");
}
string keyName = string.Format(@"SOFTWARE\TortoiseOverlays\{0}",
friendlyName);
using (RegistryKey key = Registry.LocalMachine.OpenSubKey(keyName, true))
{
// Set the default value of the key.
if (key != null)//&& !string.IsNullOrEmpty(clsid.ToString("B")))
{
key.DeleteValue("Pithos");
}
}
}
///
/// Register the context menu handler.
///
/// The CLSID of the component.
///
/// The file type that the context menu handler is associated with. For
/// example, '*' means all file types; '.txt' means all .txt files. The
/// parameter must not be NULL or an empty string.
///
/// The friendly name of the component.
public static void RegisterShellExtContextMenuHandler(Guid clsid,
string fileType, string friendlyName)
{
if (clsid == Guid.Empty)
{
throw new ArgumentException("clsid must not be empty");
}
if (string.IsNullOrEmpty(fileType))
{
throw new ArgumentException("fileType must not be null or empty");
}
// If fileType starts with '.', try to read the default value of the
// HKCR\ key which contains the ProgID to which the file type
// is linked.
if (fileType.StartsWith("."))
{
using (RegistryKey key = Registry.ClassesRoot.OpenSubKey(fileType))
{
if (key != null)
{
// If the key exists and its default value is not empty, use
// the ProgID as the file type.
string defaultVal = key.GetValue(null) as string;
if (!string.IsNullOrEmpty(defaultVal))
{
fileType = defaultVal;
}
}
}
}
// Create the key HKCR\\shellex\ContextMenuHandlers\{}.
string keyName = string.Format(@"{0}\shellex\ContextMenuHandlers\{1}",
fileType, friendlyName);
using (RegistryKey key = Registry.ClassesRoot.CreateSubKey(keyName))
{
// Set the default value of the key.
if (key != null)//&& !string.IsNullOrEmpty(clsid.ToString("B")))
{
key.SetValue(null, clsid.ToString("B"));
}
}
}
///
/// Unregister the context menu handler.
///
/// The CLSID of the component.
///
/// The file type that the context menu handler is associated with. For
/// example, '*' means all file types; '.txt' means all .txt files. The
/// parameter must not be NULL or an empty string.
///
public static void UnregisterShellExtContextMenuHandler(Guid clsid,
string fileType, string friendlyName)
{
if (clsid == null)
{
throw new ArgumentException("clsid must not be null");
}
if (string.IsNullOrEmpty(fileType))
{
throw new ArgumentException("fileType must not be null or empty");
}
// If fileType starts with '.', try to read the default value of the
// HKCR\ key which contains the ProgID to which the file type
// is linked.
if (fileType.StartsWith("."))
{
using (RegistryKey key = Registry.ClassesRoot.OpenSubKey(fileType))
{
if (key != null)
{
// If the key exists and its default value is not empty, use
// the ProgID as the file type.
string defaultVal = key.GetValue(null) as string;
if (!string.IsNullOrEmpty(defaultVal))
{
fileType = defaultVal;
}
}
}
}
// Remove the key HKCR\\shellex\ContextMenuHandlers\{}.
string keyName = string.Format(@"{0}\shellex\ContextMenuHandlers\{1}",
fileType, friendlyName);
Registry.ClassesRoot.DeleteSubKeyTree(keyName, false);
}
public static void MarkApproved(Guid guid, string friendlyName)
{
Debug.WriteLine(String.Format("Marking approved {0} {1}", guid, friendlyName), LogCategories.Shell);
using (RegistryKey key = Registry.LocalMachine.OpenSubKey(_approvedKey))
{
// Set the default value of the key.
if (key != null)//&& !string.IsNullOrEmpty(clsid.ToString("B")))
{
key.SetValue(guid.ToString("B"), friendlyName, RegistryValueKind.String);
}
else
{
Debug.WriteLine("Error - failed to open key " + _approvedKey,LogCategories.Shell);
}
}
}
public static void RemoveApproved(Guid guid)
{
using (RegistryKey key = Registry.LocalMachine.OpenSubKey(_approvedKey))
{
// Set the default value of the key.
if (key != null)//&& !string.IsNullOrEmpty(clsid.ToString("B")))
{
key.DeleteValue(guid.ToString("B"), false);
}
else
{
Debug.WriteLine("Error - failed to open key " + _approvedKey, LogCategories.Shell);
}
}
}
}
#endregion
#region Enums & Structs
#region enum HChangeNotifyEventID
///
/// Describes the event that has occurred.
/// Typically, only one event is specified at a time.
/// If more than one event is specified, the values contained
/// in the dwItem1 and dwItem2
/// parameters must be the same, respectively, for all specified events.
/// This parameter can be one or more of the following values.
///
///
/// Windows NT/2000/XP: dwItem2 contains the index
/// in the system image list that has changed.
/// dwItem1 is not used and should be .
/// Windows 95/98: dwItem1 contains the index
/// in the system image list that has changed.
/// dwItem2 is not used and should be .
///
[Flags]
enum HChangeNotifyEventID
{
///
/// All events have occurred.
///
SHCNE_ALLEVENTS = 0x7FFFFFFF,
///
/// A file type association has changed.
/// must be specified in the uFlags parameter.
/// dwItem1 and dwItem2 are not used and must be .
///
SHCNE_ASSOCCHANGED = 0x08000000,
///
/// The attributes of an item or folder have changed.
/// or
/// must be specified in uFlags.
/// dwItem1 contains the item or folder that has changed.
/// dwItem2 is not used and should be .
///
SHCNE_ATTRIBUTES = 0x00000800,
///
/// A nonfolder item has been created.
/// or
/// must be specified in uFlags.
/// dwItem1 contains the item that was created.
/// dwItem2 is not used and should be .
///
SHCNE_CREATE = 0x00000002,
///
/// A nonfolder item has been deleted.
/// or
/// must be specified in uFlags.
/// dwItem1 contains the item that was deleted.
/// dwItem2 is not used and should be .
///
SHCNE_DELETE = 0x00000004,
///
/// A drive has been added.
/// or
/// must be specified in uFlags.
/// dwItem1 contains the root of the drive that was added.
/// dwItem2 is not used and should be .
///
SHCNE_DRIVEADD = 0x00000100,
///
/// A drive has been added and the Shell should create a new window for the drive.
/// or
/// must be specified in uFlags.
/// dwItem1 contains the root of the drive that was added.
/// dwItem2 is not used and should be .
///
SHCNE_DRIVEADDGUI = 0x00010000,
///
/// A drive has been removed. or
/// must be specified in uFlags.
/// dwItem1 contains the root of the drive that was removed.
/// dwItem2 is not used and should be .
///
SHCNE_DRIVEREMOVED = 0x00000080,
///
/// Not currently used.
///
SHCNE_EXTENDED_EVENT = 0x04000000,
///
/// The amount of free space on a drive has changed.
/// or
/// must be specified in uFlags.
/// dwItem1 contains the root of the drive on which the free space changed.
/// dwItem2 is not used and should be .
///
SHCNE_FREESPACE = 0x00040000,
///
/// Storage media has been inserted into a drive.
/// or
/// must be specified in uFlags.
/// dwItem1 contains the root of the drive that contains the new media.
/// dwItem2 is not used and should be .
///
SHCNE_MEDIAINSERTED = 0x00000020,
///
/// Storage media has been removed from a drive.
/// or
/// must be specified in uFlags.
/// dwItem1 contains the root of the drive from which the media was removed.
/// dwItem2 is not used and should be .
///
SHCNE_MEDIAREMOVED = 0x00000040,
///
/// A folder has been created.
/// or must be specified in uFlags.
/// dwItem1 contains the folder that was created.
/// dwItem2 is not used and should be .
///
SHCNE_MKDIR = 0x00000008,
///
/// A folder on the local computer is being shared via the network.
/// or
/// must be specified in uFlags.
/// dwItem1 contains the folder that is being shared.
/// dwItem2 is not used and should be .
///
SHCNE_NETSHARE = 0x00000200,
///
/// A folder on the local computer is no longer being shared via the network.
/// or
/// must be specified in uFlags.
/// dwItem1 contains the folder that is no longer being shared.
/// dwItem2 is not used and should be .
///
SHCNE_NETUNSHARE = 0x00000400,
///
/// The name of a folder has changed.
/// or
/// must be specified in uFlags.
/// dwItem1 contains the previous pointer to an item identifier list (PIDL) or name of the folder.
/// dwItem2 contains the new PIDL or name of the folder.
///
SHCNE_RENAMEFOLDER = 0x00020000,
///
/// The name of a nonfolder item has changed.
/// or
/// must be specified in uFlags.
/// dwItem1 contains the previous PIDL or name of the item.
/// dwItem2 contains the new PIDL or name of the item.
///
SHCNE_RENAMEITEM = 0x00000001,
///
/// A folder has been removed.
/// or
/// must be specified in uFlags.
/// dwItem1 contains the folder that was removed.
/// dwItem2 is not used and should be .
///
SHCNE_RMDIR = 0x00000010,
///
/// The computer has disconnected from a server.
/// or
/// must be specified in uFlags.
/// dwItem1 contains the server from which the computer was disconnected.
/// dwItem2 is not used and should be .
///
SHCNE_SERVERDISCONNECT = 0x00004000,
///
/// The contents of an existing folder have changed,
/// but the folder still exists and has not been renamed.
/// or
/// must be specified in uFlags.
/// dwItem1 contains the folder that has changed.
/// dwItem2 is not used and should be .
/// If a folder has been created, deleted, or renamed, use SHCNE_MKDIR, SHCNE_RMDIR, or
/// SHCNE_RENAMEFOLDER, respectively, instead.
///
SHCNE_UPDATEDIR = 0x00001000,
///
/// An image in the system image list has changed.
/// must be specified in uFlags.
///
SHCNE_UPDATEIMAGE = 0x00008000,
}
#endregion // enum HChangeNotifyEventID
#region public enum HChangeNotifyFlags
///
/// Flags that indicate the meaning of the dwItem1 and dwItem2 parameters.
/// The uFlags parameter must be one of the following values.
///
[Flags]
public enum HChangeNotifyFlags
{
///
/// The dwItem1 and dwItem2 parameters are DWORD values.
///
SHCNF_DWORD = 0x0003,
///
/// dwItem1 and dwItem2 are the addresses of ITEMIDLIST structures that
/// represent the item(s) affected by the change.
/// Each ITEMIDLIST must be relative to the desktop folder.
///
SHCNF_IDLIST = 0x0000,
///
/// dwItem1 and dwItem2 are the addresses of null-terminated strings of
/// maximum length MAX_PATH that contain the full path names
/// of the items affected by the change.
///
SHCNF_PATHA = 0x0001,
///
/// dwItem1 and dwItem2 are the addresses of null-terminated strings of
/// maximum length MAX_PATH that contain the full path names
/// of the items affected by the change.
///
SHCNF_PATHW = 0x0005,
///
/// dwItem1 and dwItem2 are the addresses of null-terminated strings that
/// represent the friendly names of the printer(s) affected by the change.
///
SHCNF_PRINTERA = 0x0002,
///
/// dwItem1 and dwItem2 are the addresses of null-terminated strings that
/// represent the friendly names of the printer(s) affected by the change.
///
SHCNF_PRINTERW = 0x0006,
///
/// The function should not return until the notification
/// has been delivered to all affected components.
/// As this flag modifies other data-type flags, it cannot by used by itself.
///
SHCNF_FLUSH = 0x1000,
///
/// The function should begin delivering notifications to all affected components
/// but should return as soon as the notification process has begun.
/// As this flag modifies other data-type flags, it cannot by used by itself.
///
SHCNF_FLUSHNOWAIT = 0x2000
}
#endregion // enum HChangeNotifyFlags
internal enum GCS : uint
{
GCS_VERBA = 0x00000000,
GCS_HELPTEXTA = 0x00000001,
GCS_VALIDATEA = 0x00000002,
GCS_VERBW = 0x00000004,
GCS_HELPTEXTW = 0x00000005,
GCS_VALIDATEW = 0x00000006,
GCS_VERBICONW = 0x00000014,
GCS_UNICODE = 0x00000004
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
internal struct CMINVOKECOMMANDINFO
{
public uint cbSize;
public CMIC fMask;
public IntPtr hwnd;
public IntPtr verb;
[MarshalAs(UnmanagedType.LPStr)]
public string parameters;
[MarshalAs(UnmanagedType.LPStr)]
public string directory;
public int nShow;
public uint dwHotKey;
public IntPtr hIcon;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
internal struct CMINVOKECOMMANDINFOEX
{
public uint cbSize;
public CMIC fMask;
public IntPtr hwnd;
public IntPtr verb;
[MarshalAs(UnmanagedType.LPStr)]
public string parameters;
[MarshalAs(UnmanagedType.LPStr)]
public string directory;
public int nShow;
public uint dwHotKey;
public IntPtr hIcon;
[MarshalAs(UnmanagedType.LPStr)]
public string title;
public IntPtr verbW;
public string parametersW;
public string directoryW;
public string titleW;
POINT ptInvoke;
}
[Flags]
internal enum CMIC : uint
{
CMIC_MASK_ICON = 0x00000010,
CMIC_MASK_HOTKEY = 0x00000020,
CMIC_MASK_NOASYNC = 0x00000100,
CMIC_MASK_FLAG_NO_UI = 0x00000400,
CMIC_MASK_UNICODE = 0x00004000,
CMIC_MASK_NO_CONSOLE = 0x00008000,
CMIC_MASK_ASYNCOK = 0x00100000,
CMIC_MASK_NOZONECHECKS = 0x00800000,
CMIC_MASK_FLAG_LOG_USAGE = 0x04000000,
CMIC_MASK_SHIFT_DOWN = 0x10000000,
CMIC_MASK_PTINVOKE = 0x20000000,
CMIC_MASK_CONTROL_DOWN = 0x40000000
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct POINT
{
public int X;
public int Y;
}
internal enum CLIPFORMAT : uint
{
CF_TEXT = 1,
CF_BITMAP = 2,
CF_METAFILEPICT = 3,
CF_SYLK = 4,
CF_DIF = 5,
CF_TIFF = 6,
CF_OEMTEXT = 7,
CF_DIB = 8,
CF_PALETTE = 9,
CF_PENDATA = 10,
CF_RIFF = 11,
CF_WAVE = 12,
CF_UNICODETEXT = 13,
CF_ENHMETAFILE = 14,
CF_HDROP = 15,
CF_LOCALE = 16,
CF_MAX = 17,
CF_OWNERDISPLAY = 0x0080,
CF_DSPTEXT = 0x0081,
CF_DSPBITMAP = 0x0082,
CF_DSPMETAFILEPICT = 0x0083,
CF_DSPENHMETAFILE = 0x008E,
CF_PRIVATEFIRST = 0x0200,
CF_PRIVATELAST = 0x02FF,
CF_GDIOBJFIRST = 0x0300,
CF_GDIOBJLAST = 0x03FF
}
[Flags]
internal enum CMF : uint
{
CMF_NORMAL = 0x00000000,
CMF_DEFAULTONLY = 0x00000001,
CMF_VERBSONLY = 0x00000002,
CMF_EXPLORE = 0x00000004,
CMF_NOVERBS = 0x00000008,
CMF_CANRENAME = 0x00000010,
CMF_NODEFAULT = 0x00000020,
CMF_INCLUDESTATIC = 0x00000040,
CMF_ITEMMENU = 0x00000080,
CMF_EXTENDEDVERBS = 0x00000100,
CMF_DISABLEDVERBS = 0x00000200,
CMF_ASYNCVERBSTATE = 0x00000400,
CMF_OPTIMIZEFORINVOKE = 0x00000800,
CMF_SYNCCASCADEMENU = 0x00001000,
CMF_DONOTPICKDEFAULT = 0x00002000,
CMF_RESERVED = 0xFFFF0000
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
internal struct MENUITEMINFO
{
public uint cbSize;
public MIIM fMask;
public MFT fType;
public MFS fState;
public uint wID;
public IntPtr hSubMenu;
public IntPtr hbmpChecked;
public IntPtr hbmpUnchecked;
public UIntPtr dwItemData;
public string dwTypeData;
public uint cch;
public IntPtr hbmpItem;
}
[Flags]
internal enum MIIM : uint
{
MIIM_STATE = 0x00000001,
MIIM_ID = 0x00000002,
MIIM_SUBMENU = 0x00000004,
MIIM_CHECKMARKS = 0x00000008,
MIIM_TYPE = 0x00000010,
MIIM_DATA = 0x00000020,
MIIM_STRING = 0x00000040,
MIIM_BITMAP = 0x00000080,
MIIM_FTYPE = 0x00000100
}
[Flags]
internal enum MFT : uint
{
MFT_STRING = 0x00000000,
MFT_BITMAP = 0x00000004,
MFT_MENUBARBREAK = 0x00000020,
MFT_MENUBREAK = 0x00000040,
MFT_OWNERDRAW = 0x00000100,
MFT_RADIOCHECK = 0x00000200,
MFT_SEPARATOR = 0x00000800,
MFT_RIGHTORDER = 0x00002000,
MFT_RIGHTJUSTIFY = 0x00004000
}
[Flags]
internal enum MFS : uint
{
MFS_ENABLED = 0x00000000,
MFS_UNCHECKED = 0x00000000,
MFS_UNHILITE = 0x00000000,
MFS_GRAYED = 0x00000003,
MFS_DISABLED = 0x00000003,
MFS_CHECKED = 0x00000008,
MFS_HILITE = 0x00000080,
MFS_DEFAULT = 0x00001000
}
[Flags]
internal enum MF: uint
{
MF_BYCOMMAND = 0x00000000,
MF_ENABLED = 0x00000000,
MF_DISABLED = 0x00000002,
MF_BITMAP = 0x00000004,
MF_CHECKED = 0x00000008,
MF_BYPOSITION = 0x00000400,
MF_SEPARATOR = 0x00000800
}
#endregion
internal class NativeMethods
{
///
/// Retrieve the names of dropped files that result from a successful drag-
/// and-drop operation.
///
///
/// Identifier of the structure that contains the file names of the dropped
/// files.
///
///
/// Index of the file to query. If the value of this parameter is 0xFFFFFFFF,
/// DragQueryFile returns a count of the files dropped.
///
///
/// The address of a buffer that receives the file name of a dropped file
/// when the function returns.
///
///
/// The size, in characters, of the pszFile buffer.
///
/// A non-zero value indicates a successful call.
[DllImport("shell32", CharSet = CharSet.Unicode)]
public static extern uint DragQueryFile(
IntPtr hDrop,
uint iFile,
StringBuilder pszFile,
int cch);
///
/// Free the specified storage medium.
///
///
/// Reference of the storage medium that is to be freed.
///
[DllImport("ole32.dll", CharSet = CharSet.Unicode)]
public static extern void ReleaseStgMedium(ref STGMEDIUM pmedium);
///
/// Insert a new menu item at the specified position in a menu.
///
///
/// A handle to the menu in which the new menu item is inserted.
///
///
/// The identifier or position of the menu item before which to insert the
/// new item. The meaning of this parameter depends on the value of
/// fByPosition.
///
///
/// Controls the meaning of uItem. If this parameter is false, uItem is a
/// menu item identifier. Otherwise, it is a menu item position.
///
///
/// A reference of a MENUITEMINFO structure that contains information about
/// the new menu item.
///
///
/// If the function succeeds, the return value is true.
///
[DllImport("user32", CharSet = CharSet.Unicode, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool InsertMenuItem(
IntPtr hMenu,
uint uItem,
[MarshalAs(UnmanagedType.Bool)]bool fByPosition,
ref MENUITEMINFO mii);
[DllImport("user32", CharSet = CharSet.Unicode, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool InsertMenu(
IntPtr hMenu,
uint uPosition,
MF uFlags,
uint uIDNewItem,
string lpNewItem);
[DllImport("shell32", CharSet = CharSet.Unicode, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool SHGetPathFromIDList(
IntPtr pidl,
StringBuilder pszpath);
[DllImport("shell32.dll")]
public static extern void SHChangeNotify(HChangeNotifyEventID wEventId,
HChangeNotifyFlags uFlags,
IntPtr dwItem1,
IntPtr dwItem2);
[DllImport("gdi32.dll")]
public static extern bool DeleteObject(IntPtr hObject);
public static int HighWord(int number)
{
return ((number & 0x80000000) == 0x80000000) ?
(number >> 16) : ((number >> 16) & 0xffff);
}
public static int LowWord(int number)
{
return number & 0xffff;
}
}
internal static class WinError
{
public const int S_OK = 0x0000;
public const int S_FALSE = 0x0001;
public const int E_FAIL = -2147467259;
public const int E_INVALIDARG = -2147024809;
public const int E_OUTOFMEMORY = -2147024882;
public const int STRSAFE_E_INSUFFICIENT_BUFFER = -2147024774;
public const uint SEVERITY_SUCCESS = 0;
public const uint SEVERITY_ERROR = 1;
///
/// Create an HRESULT value from component pieces.
///
/// The severity to be used
/// The facility to be used
/// The error number
/// A HRESULT constructed from the above 3 values
public static int MAKE_HRESULT(uint sev, uint fac, uint code)
{
return (int)((sev << 31) | (fac << 16) | code);
}
}
}