Click here to Skip to main content
15,886,362 members
Articles / Programming Languages / C#

Implement an Autoplay Handler

Rate me:
Please Sign up or sign in to vote.
5.00/5 (22 votes)
18 Sep 2006CPOL8 min read 117.8K   1.7K   78  
Implementing an Autoplay handler in C#.
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text;

/*****************************************************************************************
 *  Copyright (c) 2006 T. ALmdal
 *
 *  Permission is hereby granted, free of charge, to any person obtaining 
 *  a copy of this software and associated documentation files (the "Software"),
 *  to deal in the Software without restriction, including without limitation 
 *  the rights to use, copy, modify, merge, publish, distribute, sublicense, 
 *  and/or sell copies of the Software, and to permit persons to whom the 
 *  Software is furnished to do so, subject to the following conditions:
 *
 *  The above copyright notice and this permission notice shall be included 
 *  in all copies or substantial portions of the Software.
 *  
 *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 
 *  OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
 *  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 
 *  THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
 *  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 
 *  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 * 
/*******************************************************************************************/
namespace Almdal.AutoPlayListener {
	#region enum SHGNO
	[Flags]
	public enum SHGNO : uint {
		SHGDN_NORMAL = 0x0000,  // default (display purpose)
		SHGDN_INFOLDER = 0x0001,  // displayed under a folder (relative)
		SHGDN_FOREDITING = 0x1000,  // for in-place editing
		SHGDN_FORADDRESSBAR = 0x4000,  // UI friendly parsing name (remove ugly stuff)
		SHGDN_FORPARSING = 0x8000,  // parsing name for ParseDisplayName()
	}
	#endregion

	#region enum SHCONTF
	[Flags]
	public enum SHCONTF : uint {
		SHCONTF_FOLDERS = 0x0020,   // only want folders enumerated (SFGAO_FOLDER)
		SHCONTF_NONFOLDERS = 0x0040,   // include non folders
		SHCONTF_INCLUDEHIDDEN = 0x0080,   // show items normally hidden
		SHCONTF_INIT_ON_FIRST_NEXT = 0x0100,   // allow EnumObject() to return before validating enum
		SHCONTF_NETPRINTERSRCH = 0x0200,   // hint that client is looking for printers
		SHCONTF_SHAREABLE = 0x0400,   // hint that client is looking sharable resources (remote shares)
		SHCONTF_STORAGE = 0x0800,   // include all items with accessible storage and their ancestors
	}
	#endregion

	#region enum SFGAOF
	[Flags]
	public enum SFGAOF : uint {
		SFGAO_NONE = 0x0,
		SFGAO_CANCOPY = 0x1,                // Objects can be copied    (DROPEFFECT_COPY)
		SFGAO_CANMOVE = 0x2,                // Objects can be moved     (DROPEFFECT_MOVE)
		SFGAO_CANLINK = 0x4,                // Objects can be linked    (DROPEFFECT_LINK)
		SFGAO_STORAGE = 0x00000008,         // supports BindToObject(IID_IStorage)
		SFGAO_CANRENAME = 0x00000010,         // Objects can be renamed
		SFGAO_CANDELETE = 0x00000020,         // Objects can be deleted
		SFGAO_HASPROPSHEET = 0x00000040,         // Objects have property sheets
		SFGAO_DROPTARGET = 0x00000100,         // Objects are drop target
		SFGAO_CAPABILITYMASK = 0x00000177,
		SFGAO_ENCRYPTED = 0x00002000,         // object is encrypted (use alt color)
		SFGAO_ISSLOW = 0x00004000,         // 'slow' object
		SFGAO_GHOSTED = 0x00008000,         // ghosted icon
		SFGAO_LINK = 0x00010000,         // Shortcut (link)
		SFGAO_SHARE = 0x00020000,         // shared
		SFGAO_READONLY = 0x00040000,         // read-only
		SFGAO_HIDDEN = 0x00080000,         // hidden object
		SFGAO_DISPLAYATTRMASK = 0x000FC000,
		SFGAO_FILESYSANCESTOR = 0x10000000,         // may contain children with SFGAO_FILESYSTEM
		SFGAO_FOLDER = 0x20000000,         // support BindToObject(IID_IShellFolder)
		SFGAO_FILESYSTEM = 0x40000000,         // is a win32 file system object (file/folder/root)
		SFGAO_HASSUBFOLDER = 0x80000000,         // may contain children with SFGAO_FOLDER
		SFGAO_CONTENTSMASK = 0x80000000,
		SFGAO_VALIDATE = 0x01000000,         // invalidate cached information
		SFGAO_REMOVABLE = 0x02000000,         // is this removeable media?
		SFGAO_COMPRESSED = 0x04000000,         // Object is compressed (use alt color)
		SFGAO_BROWSABLE = 0x08000000,         // supports IShellFolder, but only implements CreateViewObject() (non-folder view)
		SFGAO_NONENUMERATED = 0x00100000,         // is a non-enumerated object
		SFGAO_NEWCONTENT = 0x00200000,         // should show bold in explorer tree
		SFGAO_CANMONIKER = 0x00400000,         // defunct
		SFGAO_HASSTORAGE = 0x00400000,         // defunct
		SFGAO_STREAM = 0x00400000,         // supports BindToObject(IID_IStream)
		SFGAO_STORAGEANCESTOR = 0x00800000,         // may contain children with SFGAO_STORAGE or SFGAO_STREAM
		SFGAO_STORAGECAPMASK = 0x70C50008,         // for determining storage capabilities, ie for open/save semantics
		SFGAO_ALL = 0xffffffff,                 //  all attributes
	}
	#endregion

	#region STRRET
	[StructLayout(LayoutKind.Explicit)]
	public struct STRRET {
		[FieldOffset(0)]
		public UInt32 uType;    // One of the STRRET_* values

		[FieldOffset(4)]
		public IntPtr pOleStr;    // must be freed by caller of GetDisplayNameOf

		[FieldOffset(4)]
		public IntPtr pStr;        // NOT USED

		[FieldOffset(4)]
		public UInt32 uOffset;    // Offset into SHITEMID

		[FieldOffset(4)]
		public IntPtr cStr;        // Buffer to fill in (ANSI)
	}
	#endregion

	public enum DROPEFFECT : ulong {
		NONE = 0,
		COPY = 1,
		MOVE = 2,
		LINK = 4,
		SCROLL = 0x80000000,
	}

	[StructLayout(LayoutKind.Sequential)]
	public struct POINTL {
		public POINTL(long xx, long yy) { x = xx; y = yy; }
		public long x;
		public long y;
		public override string ToString() {
			String s = String.Format("({0},{1})", x, y);
			return s;
		}
	}

	public enum DVASPECT : uint {
		DVASPECT_CONTENT = 1,
		DVASPECT_THUMBNAIL = 2,
		DVASPECT_ICON = 4,
		DVASPECT_DOCPRINT = 8
	}

	public enum TYMED : uint {
		TYMED_HGLOBAL = 1,
		TYMED_FILE = 2,
		TYMED_ISTREAM = 4,
		TYMED_ISTORAGE = 8,
		TYMED_GDI = 16,
		TYMED_MFPICT = 32,
		TYMED_ENHMF = 64,
		TYMED_NULL = 0
	}

	[StructLayout(LayoutKind.Sequential)]
	public struct FORMATETC {
		public uint cfFormat;                   //  CLIPFORMAT
		public IntPtr ptd;
		public DVASPECT dwAspect;
		public int lindex;
		public TYMED tymed;
	}

	[StructLayout(LayoutKind.Sequential)]
	public struct STGMEDIUM {
		public uint tymed;
		public IntPtr hGlobal;
		public IntPtr pUnkForRelease;
	}

	#region Interface IMAlloc
	// C# representation of the IMalloc interface.
	[InterfaceType(ComInterfaceType.InterfaceIsIUnknown),
	   Guid("00000002-0000-0000-C000-000000000046")]
	public interface IMalloc {
		[PreserveSig]
		IntPtr Alloc([In] int cb);
		[PreserveSig]
		IntPtr Realloc([In] IntPtr pv, [In] int cb);
		[PreserveSig]
		void Free([In] IntPtr pv);
		[PreserveSig]
		int GetSize([In] IntPtr pv);
		[PreserveSig]
		int DidAlloc(IntPtr pv);
		[PreserveSig]
		void HeapMinimize();
	}
	#endregion

	#region interface IShellFolder
	[ComImport]
	[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
	[Guid("000214E6-0000-0000-C000-000000000046")]
	public interface IShellFolder {
		// Translates a file object's or folder's display name into an item
		// identifier list.
		// Return value: error code, if any
		[PreserveSig()]
		uint ParseDisplayName(
			IntPtr hwnd,        // Optional window handle
			IntPtr pbc,         // Optional bind context that controls the
			// parsing operation. This parameter is
			// normally set to NULL.
			[In(), MarshalAs(UnmanagedType.LPWStr)]
            string pszDisplayName,  // Null-terminated UNICODE string with the
			// display name.
			out uint pchEaten,      // Pointer to a ULONG value that receives the
			// number of characters of the
			// display name that was parsed.
			out IntPtr ppidl,       // Pointer to an ITEMIDLIST pointer that receives
			// the item identifier list for
			// the object.
			ref uint pdwAttributes); // Optional parameter that can be used to
		// query for file attributes.
		// this can be values from the SFGAO enum

		// Allows a client to determine the contents of a folder by creating
		// an item identifier enumeration object and returning its
		// IEnumIDList interface.
		// Return value: error code, if any
		[PreserveSig()]
		uint EnumObjects(
			IntPtr hwnd,        // If user input is required to perform the
			// enumeration, this window handle
			// should be used by the enumeration object as
			// the parent window to take
			// user input.
			SHCONTF grfFlags,       // Flags indicating which items to include in the
			// enumeration. For a list
			// of possible values, see the SHCONTF enum.
			out IEnumIDList ppenumIDList);  // Address that receives a pointer to the
		// IEnumIDList interface of the
		// enumeration object created by this method.

		// Retrieves an IShellFolder object for a subfolder.
		// Return value: error code, if any
		[PreserveSig()]
		uint BindToObject(
			IntPtr pidl,        // Address of an ITEMIDLIST structure (PIDL)
			// that identifies the subfolder.
			IntPtr pbc,         // Optional address of an IBindCtx interface on
			// a bind context object to be
			// used during this operation.
			[In()]
    ref Guid riid,      // Identifier of the interface to return.
			//[MarshalAs(UnmanagedType.Interface)]
			out IntPtr ppv);    // Address that receives the interface pointer.

		// Requests a pointer to an object's storage interface.
		// Return value: error code, if any
		[PreserveSig()]
		uint BindToStorage(
			IntPtr pidl,        // Address of an ITEMIDLIST structure that
			// identifies the subfolder relative
			// to its parent folder.
			IntPtr pbc,         // Optional address of an IBindCtx interface on a
			// bind context object to be
			// used during this operation.
			[In()]
    ref Guid riid,      // Interface identifier (IID) of the requested
			// storage interface.
			[MarshalAs(UnmanagedType.Interface)]
    out object ppv);    // Address that receives the interface pointer
		// specified by riid.

		// Determines the relative order of two file objects or folders, given
		// their item identifier lists. Return value: If this method is
		// successful, the CODE field of the HRESULT contains one of the
		// following values (the code can be retrived using the helper function
		// GetHResultCode): Negative A
		// negative return value indicates that the first item should precede
		// the second (pidl1 < pidl2).

		// Positive A positive return value indicates that the first item should
		// follow the second (pidl1 > pidl2).  Zero A return value of zero
		// indicates that the two items are the same (pidl1 = pidl2).
		[PreserveSig()]
		int CompareIDs(
			int lParam,         // Value that specifies how the comparison
			// should be performed. The lower
			// Sixteen bits of lParam define the sorting
			// rule.
			// The upper sixteen bits of
			// lParam are used for flags that modify the
			// sorting rule. values can be from
			// the SHCIDS enum
			IntPtr pidl1,       // Pointer to the first item's ITEMIDLIST
			// structure.
			IntPtr pidl2);      // Pointer to the second item's ITEMIDLIST
		// structure.

		// Requests an object that can be used to obtain information from or interact
		// with a folder object.
		// Return value: error code, if any
		[PreserveSig()]
		uint CreateViewObject(
			IntPtr hwndOwner,       // Handle to the owner window.
			[In()]
    ref Guid riid,      // Identifier of the requested interface.
			[MarshalAs(UnmanagedType.Interface)]
    out object ppv);    // Address of a pointer to the requested
		// interface.

		// Retrieves the attributes of one or more file objects or subfolders.
		// Return value: error code, if any
		[PreserveSig()]
		uint GetAttributesOf(
			int cidl,           // Number of file objects from which to retrieve
			// attributes.
			[In(), MarshalAs(UnmanagedType.LPArray)] IntPtr[]
			apidl,          // Address of an array of pointers to ITEMIDLIST
			// structures, each of which
			// uniquely identifies a file object relative to
			// the parent folder.
			[MarshalAs(UnmanagedType.LPArray)] SFGAOF[]
			rgfInOut);          // Address of a single ULONG value that, on
		// entry,
		// contains the attributes that the caller is
		// requesting. On exit, this value contains the
		// requested attributes that are common to all
		// of the specified objects. this value can
		// be from the SFGAO enum

		// Retrieves an OLE interface that can be used to carry out actions on the
		// specified file objects or folders. Return value: error code, if any
		[PreserveSig()]
		uint GetUIObjectOf(
			IntPtr hwndOwner,       // Handle to the owner window that the client
			// should specify if it displays
			// a dialog box or message box.
			int cidl,           // Number of file objects or subfolders specified
			// in the apidl parameter.
			[In(), MarshalAs(UnmanagedType.LPArray)] IntPtr[]
			apidl,          // Address of an array of pointers to ITEMIDLIST
			// structures, each of which
			// uniquely identifies a file object or subfolder
			// relative to the parent folder.
			[In()]
    ref Guid riid,      // Identifier of the COM interface object to
			// return.
			IntPtr rgfReserved,     // Reserved.
			[MarshalAs(UnmanagedType.Interface)]
     out object ppv);    // Pointer to the requested interface.

		// Retrieves the display name for the specified file object or subfolder.
		// Return value: error code, if any
		[PreserveSig()]
		uint GetDisplayNameOf(
			IntPtr pidl,        // Address of an ITEMIDLIST structure (PIDL)
			// that uniquely identifies the file
			// object or subfolder relative to the parent
			// folder.
			SHGNO uFlags,       // Flags used to request the type of display name
			// to return. For a list of possible values.
			out STRRET pName);      // Address of a STRRET structure in which to
		// return the display name.

		// Sets the display name of a file object or subfolder, changing the item
		// identifier in the process.
		// Return value: error code, if any
		[PreserveSig()]
		uint SetNameOf(
			IntPtr hwnd,        // Handle to the owner window of any dialog or
			// message boxes that the client
			// displays.
			IntPtr pidl,        // Pointer to an ITEMIDLIST structure that
			// uniquely
			// identifies the file object
			// or subfolder relative to the parent folder.
			[In(), MarshalAs(UnmanagedType.LPWStr)]
    string pszName,     // Pointer to a null-terminated string that
			// specifies the new display name.
			SHGNO uFlags,       // Flags indicating the type of name specified by
			// the lpszName parameter. For a list of possible
			// values, see the description of the SHGNO
			// enum.
			out IntPtr ppidlOut);   // Address of a pointer to an ITEMIDLIST
		// structure
		// which receives the new ITEMIDLIST.
	}
	#endregion

	#region Interface IEnumIDList
	[ComImport]
	[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
	[Guid("000214F2-0000-0000-C000-000000000046")]

	public interface IEnumIDList {

		// Retrieves the specified number of item identifiers in the
		// enumeration sequence and advances the current position by
		// the number of items retrieved.
		[PreserveSig()]
		uint Next(
			uint celt,                // Number of elements in the array pointed to by the rgelt parameter.

			out IntPtr rgelt,        // Address of an array of ITEMIDLIST pointers that receives the item
			// identifiers. The implementation must allocate these item identifiers
			// using the Shell's allocator (retrieved by the SHGetMalloc function).
			// The calling application is responsible for freeing the item
			// identifiers using the Shell's allocator.

			out IntPtr pceltFetched    // Address of a value that receives a count of the item identifiers
			// actually returned in rgelt. The count can be smaller than the value
			// specified in the celt parameter. This parameter can be NULL only
			// if celt is one.
			);

		// Skips over the specified number of elements in the enumeration sequence.
		[PreserveSig()]
		uint Skip(
			uint celt                // Number of item identifiers to skip.
			);

		// Returns to the beginning of the enumeration sequence.
		[PreserveSig()]
		uint Reset();

		// Creates a new item enumeration object with the same contents and state as the current one.
		[PreserveSig()]
		uint Clone(
			out IEnumIDList ppenum        // Address of a pointer to the new enumeration object. The calling
			// application must eventually free the new object by calling its Release member function.
			);
	}
	#endregion

	#region Interface IDataObject
	[ComImport(),
	InterfaceType(ComInterfaceType.InterfaceIsIUnknown),
	GuidAttribute("0000010e-0000-0000-C000-000000000046")]
	public interface IDataObject {
		[PreserveSig()]
		int GetData(ref FORMATETC a, ref STGMEDIUM b);
		[PreserveSig()]
		void GetDataHere(int a, out STGMEDIUM b);
		[PreserveSig()]
		int QueryGetData(ref FORMATETC a);
		[PreserveSig()]
		int GetCanonicalFormatEtc(FORMATETC a, out FORMATETC b);
		[PreserveSig()]
		int SetData(ref FORMATETC a, ref STGMEDIUM b, [In, MarshalAs(UnmanagedType.Bool)] bool release);
		[PreserveSig()]
		int EnumFormatEtc(uint direction, ref Object b);
		[PreserveSig()]
		int DAdvise(int a, uint b, Object c, ref uint d);
		[PreserveSig()]
		int DUnadvise(uint a);
		[PreserveSig()]
		int EnumDAdvise(ref Object a);
	}
	#endregion

	#region Interface IDropTarget
	[ComImport,
	 InterfaceType(ComInterfaceType.InterfaceIsIUnknown),
	 Guid("00000122-0000-0000-C000-000000000046")]
	public interface IDropTarget {
		[PreserveSig()]
		int DragEnter(IntPtr pDataObj,               //  IDataObject
					  ulong grfKeyState,             //  DWORD
					  POINTL pt,
					  ref ulong pdwEffect);          //  DWORD*

		[PreserveSig()]
		int DragOver(ulong grfKeyState,              //  DWORD
					 POINTL pt,
					 ref ulong pdwEffect);           //  DWORD*

		[PreserveSig()]
		int DragLeave();

		[PreserveSig()]
		int Drop(IntPtr pDataObj,                    //  IDataObject
				 ulong grfKeyState,                  //  DWORD
				 POINTL pt,
				 ref ulong pdwEffect);               //  DWORD*

	}
	#endregion

	public class WinApi {
		public const string CFSTR_AUTOPLAY_SHELLIDLISTS = "Autoplay Enumerated IDList Array";
		public const int MAX_PATH = 260;

		public static Guid IID_IShellFolder = new Guid("{000214E6-0000-0000-C000-000000000046}");

		[DllImport("kernel32", SetLastError = true)]
		public extern static IntPtr GlobalLock(IntPtr hMem);

		[DllImport("kernel32", SetLastError = true)]
		public static extern bool GlobalUnlock(IntPtr hMem);

		[DllImport("Shell32.dll")]
		public static extern IntPtr ILCombine(IntPtr intPtr, IntPtr intPtr_2);

		[DllImport("Shell32.dll")]
		public static extern void ILFree(IntPtr intPtr);

		[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
		public static extern uint RegisterWindowMessage(string lpString);

		[DllImport("user32.dll", SetLastError = true, EntryPoint = "RegisterClipboardFormatW")]
		public static extern uint RegisterClipboardFormat([MarshalAs(UnmanagedType.LPWStr)] String format);

		[DllImport("ole32.dll")]
		public static extern void ReleaseStgMedium(ref STGMEDIUM medium);

		[DllImport("User32.dll", EntryPoint = "SendMessageW")]
		public static extern int SendMessage(IntPtr hwnd, int wMsg, IntPtr wparam, int lparam);

		[DllImport("shell32")]
		public static extern int SHBindToParent(
			IntPtr pidl,
			[MarshalAs(UnmanagedType.LPStruct)]
            Guid riid,
			out IntPtr ppv,                 /* interface whose IID is riid */
			out IntPtr pidlLast);

		[DllImport("Shell32.dll")]
		public static extern int SHGetMalloc(out IMalloc ppMalloc);

		[DllImport("shlwapi.dll", CharSet = CharSet.Auto)]
		public static extern int StrRetToBSTR(ref STRRET displayName, IntPtr pidlRoot, out StringBuilder display);

	}
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Canada Canada
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions