/// <summary> /// Retrieves the handle of the system image list. /// </summary> /// <exception cref="Exception"> /// The system image list handle has already been retrieved. /// or /// Unable to retrieve system image list handle. /// </exception> private static void InitImageList() { // Only initialize once. if (m_bImgInit) { throw new Exception("The system image list handle has already been retrieved."); } // Retrieve the info for a fake file so we can get the image list handle. SHFILEINFO shInfo = new SHFILEINFO(); SHGFI dwAttribs = SHGFI.SHGFI_USEFILEATTRIBUTES | SHGFI.SHGFI_SMALLICON | SHGFI.SHGFI_SYSICONINDEX; m_pImgHandle = NativeShellApi.SHGetFileInfo(".txt", NativeShellApi.FILE_ATTRIBUTE_NORMAL, out shInfo, (uint)Marshal.SizeOf(shInfo), dwAttribs); // Make sure we got the handle. if (m_pImgHandle.Equals(IntPtr.Zero)) { throw new Exception("Unable to retrieve system image list handle."); } // Only allow one initialization. m_bImgInit = true; }
/// <summary> /// Constructor. Creates the ShellItem object for the Desktop. /// </summary> public ShellItem() { // new ShellItem() can only be called once. if (m_bHaveRootShell) { throw new Exception("The Desktop shell item already exists so cannot be created again."); } // Obtain the root IShellFolder interface. int hRes = NativeShellApi.SHGetDesktopFolder(ref m_shRootShell); if (hRes != 0) { Marshal.ThrowExceptionForHR(hRes); } // Now get the PIDL for the Desktop shell item. hRes = NativeShellApi.SHGetSpecialFolderLocation(IntPtr.Zero, CSIDL.CSIDL_DESKTOP, ref m_pIDL); if (hRes != 0) { Marshal.ThrowExceptionForHR(hRes); } // Now retrieve some attributes for the root shell item. SHFILEINFO shInfo = new SHFILEINFO(); NativeShellApi.SHGetFileInfo(m_pIDL, 0, out shInfo, (uint)Marshal.SizeOf(shInfo), SHGFI.SHGFI_DISPLAYNAME | SHGFI.SHGFI_PIDL | SHGFI.SHGFI_SMALLICON | SHGFI.SHGFI_SYSICONINDEX ); // Set the arributes to object properties. DisplayName = shInfo.szDisplayName; IconIndex = shInfo.iIcon; IsFolder = true; HasSubFolder = true; Path = GetPath(); // Internal with no set{} mutator. m_shShellFolder = RootShellFolder; m_bHaveRootShell = true; }
/// <summary> /// Constructor. Create a sub-item shell item object. /// </summary> /// <param name="shDesktop">IShellFolder interface of the Desktop</param> /// <param name="pIDL">The fully qualified PIDL for this shell item</param> /// <param name="shParent">The ShellItem object for this item's parent</param> public ShellItem(IShellFolder shDesktop, IntPtr pIDL, ShellItem shParent) { // We need the Desktop shell item to exist first. if (m_bHaveRootShell == false) { throw new Exception("The root shell item must be created before creating a sub-item"); } // Create the FQ PIDL for this new item. m_pIDL = NativeShellApi.ILCombine(shParent.PIDL, pIDL); // Get the properties of this item. SFGAOF uFlags = SFGAOF.SFGAO_FOLDER | SFGAOF.SFGAO_HASSUBFOLDER; // Here we get some basic attributes. shDesktop.GetAttributesOf(1, out m_pIDL, out uFlags); IsFolder = Convert.ToBoolean(uFlags & SFGAOF.SFGAO_FOLDER); HasSubFolder = Convert.ToBoolean(uFlags & SFGAOF.SFGAO_HASSUBFOLDER); // Now we want to get extended attributes such as the icon index etc. SHFILEINFO shInfo = new SHFILEINFO(); SHGFI vFlags = SHGFI.SHGFI_SMALLICON | SHGFI.SHGFI_SYSICONINDEX | SHGFI.SHGFI_PIDL | SHGFI.SHGFI_DISPLAYNAME; NativeShellApi.SHGetFileInfo(m_pIDL, 0, out shInfo, (uint)Marshal.SizeOf(shInfo), vFlags); DisplayName = shInfo.szDisplayName; IconIndex = shInfo.iIcon; Path = GetPath(); // Create the IShellFolder interface for this item. if (IsFolder) { uint hRes = shParent.m_shShellFolder.BindToObject(pIDL, IntPtr.Zero, ref NativeShellApi.IID_IShellFolder, out m_shShellFolder); if (hRes != 0) { Marshal.ThrowExceptionForHR((int)hRes); } } }