/// <summary> /// Private Constructor, creates new CShItem from the item's parent folder and /// the item's PIDL relative to that folder.</summary> /// <param name="folder">the folder interface of the parent</param> /// <param name="pidl">the Relative PIDL of this item</param> /// <param name="parent">the CShitem of the parent</param> /// private CShItem(ExpTreeLib.ShellDll.IShellFolder folder, IntPtr pidl, CShItem parent) { if (DesktopBase == null) { DesktopBase = new CShItem(); //This initializes the Desktop folder } m_Parent = parent; m_Pidl = concatPidls(parent.PIDL, pidl); //Get some attributes SetUpAttributes(folder, pidl); //Set unfetched value for IconIndex.... m_IconIndexNormal = - 1; m_IconIndexOpen = - 1; //finally, set up my Folder if (m_IsFolder) { int HR; HR = folder.BindToObject(pidl, IntPtr.Zero, ref ExpTreeLib.ShellDll.IID_IShellFolder, ref m_Folder); if (HR != ExpTreeLib.ShellDll.NOERROR) { Marshal.ThrowExceptionForHR(HR); } } }
/// <summary>Get the base attributes of the folder/file that this CShItem represents</summary> /// <param name="folder">Parent Folder of this Item</param> /// <param name="pidl">Relative Pidl of this Item.</param> /// private void SetUpAttributes(ExpTreeLib.ShellDll.IShellFolder folder, IntPtr pidl) { ExpTreeLib.ShellDll.SFGAO attrFlag; attrFlag = ExpTreeLib.ShellDll.SFGAO.BROWSABLE; attrFlag = attrFlag | ExpTreeLib.ShellDll.SFGAO.FILESYSTEM; attrFlag = attrFlag | ExpTreeLib.ShellDll.SFGAO.HASSUBFOLDER; attrFlag = attrFlag | ExpTreeLib.ShellDll.SFGAO.FOLDER; attrFlag = attrFlag | ExpTreeLib.ShellDll.SFGAO.LINK; attrFlag = attrFlag | ExpTreeLib.ShellDll.SFGAO.SHARE; attrFlag = attrFlag | ExpTreeLib.ShellDll.SFGAO.HIDDEN; attrFlag = attrFlag | ExpTreeLib.ShellDll.SFGAO.REMOVABLE; //attrFlag = attrFlag Or SFGAO.RDONLY 'made into an on-demand attribute attrFlag = attrFlag | ExpTreeLib.ShellDll.SFGAO.CANCOPY; attrFlag = attrFlag | ExpTreeLib.ShellDll.SFGAO.CANDELETE; attrFlag = attrFlag | ExpTreeLib.ShellDll.SFGAO.CANLINK; attrFlag = attrFlag | ExpTreeLib.ShellDll.SFGAO.CANMOVE; attrFlag = attrFlag | ExpTreeLib.ShellDll.SFGAO.DROPTARGET; //Note: for GetAttributesOf, we must provide an array, in all cases with 1 element IntPtr[] aPidl = new IntPtr[1]; aPidl[0] = pidl; folder.GetAttributesOf(1, aPidl, ref attrFlag); m_Attributes = attrFlag; m_IsBrowsable = (attrFlag & ExpTreeLib.ShellDll.SFGAO.BROWSABLE)!=0; m_IsFileSystem = (attrFlag & ExpTreeLib.ShellDll.SFGAO.FILESYSTEM)!=0; m_HasSubFolders = (attrFlag & ExpTreeLib.ShellDll.SFGAO.HASSUBFOLDER)!=0; m_IsFolder = (attrFlag & ExpTreeLib.ShellDll.SFGAO.FOLDER)!=0; m_IsLink = (attrFlag & ExpTreeLib.ShellDll.SFGAO.LINK)!=0; m_IsShared = (attrFlag & ExpTreeLib.ShellDll.SFGAO.SHARE)!=0; m_IsHidden = (attrFlag & ExpTreeLib.ShellDll.SFGAO.HIDDEN)!=0; m_IsRemovable = (attrFlag & ExpTreeLib.ShellDll.SFGAO.REMOVABLE)!=0; //m_IsReadOnly = CBool(attrFlag And SFGAO.RDONLY) 'made into an on-demand attribute m_CanCopy = (attrFlag & ExpTreeLib.ShellDll.SFGAO.CANCOPY)!=0; m_CanDelete = (attrFlag & ExpTreeLib.ShellDll.SFGAO.CANDELETE)!=0; m_CanLink = (attrFlag & ExpTreeLib.ShellDll.SFGAO.CANLINK)!=0; m_CanMove = (attrFlag & ExpTreeLib.ShellDll.SFGAO.CANMOVE)!=0; m_IsDropTarget = (attrFlag & ExpTreeLib.ShellDll.SFGAO.DROPTARGET)!=0; //Get the Path IntPtr strr = Marshal.AllocCoTaskMem(ExpTreeLib.ShellDll.MAX_PATH * 2 + 4); Marshal.WriteInt32(strr, 0, 0); StringBuilder buf = new StringBuilder(ExpTreeLib.ShellDll.MAX_PATH); ExpTreeLib.ShellDll.SHGDN itemflags = ExpTreeLib.ShellDll.SHGDN.FORPARSING; folder.GetDisplayNameOf(pidl, itemflags, strr); int HR = ExpTreeLib.ShellDll.StrRetToBuf(strr, pidl, buf, ExpTreeLib.ShellDll.MAX_PATH); Marshal.FreeCoTaskMem(strr); //now done with it if (HR == ExpTreeLib.ShellDll.NOERROR) { m_Path = buf.ToString(); //check for zip file = folder on xp, leave it a file if (m_IsFolder && m_IsFileSystem && XPorAbove) { //Note:meaning of SFGAO.STREAM changed between win2k and winXP //Version 20 code //If File.Exists(m_Path) Then // m_IsFolder = False //End If //Version 21 code aPidl[0] = pidl; attrFlag = ExpTreeLib.ShellDll.SFGAO.STREAM; folder.GetAttributesOf(1, aPidl, ref attrFlag); if ((attrFlag & ExpTreeLib.ShellDll.SFGAO.STREAM)!=0) { m_IsFolder = false; } } if (m_Path.Length == 3 && m_Path.Substring(1).Equals(":\\")) { m_IsDisk = true; } } else { Marshal.ThrowExceptionForHR(HR); } }
///<Summary> /// Returns the requested Items of this Folder as an ArrayList of CShitems /// unless the IntPtrOnly flag is set. If IntPtrOnly is True, return an /// ArrayList of PIDLs. ///</Summary> /// <param name="flags">A set of one or more SHCONTF flags indicating which items to return</param> /// <param name="IntPtrOnly">True to suppress generation of CShItems, returning only an /// ArrayList of IntPtrs to RELATIVE PIDLs for the contents of this Folder</param> private List<IntPtr> GetContentsPIDL(ExpTreeLib.ShellDll.SHCONTF flags) { List<IntPtr> rVal = new List<IntPtr>(); int HR; ShellDll.IEnumIDList IEnum = null; HR = m_Folder.EnumObjects(0, flags, ref IEnum); if (HR == ExpTreeLib.ShellDll.NOERROR) { IntPtr item = IntPtr.Zero; int itemCnt = 0; HR = IEnum.GetNext(1, ref item, ref itemCnt); if (HR == ExpTreeLib.ShellDll.NOERROR) { while (itemCnt > 0 && ! item.Equals(IntPtr.Zero)) { //there is no setting to exclude folders from enumeration, // just one to include non-folders // so we have to screen the results to return only // non-folders if folders are not wanted if ((flags & ExpTreeLib.ShellDll.SHCONTF.FOLDERS)==0) //don't want folders. see if this is one { ExpTreeLib.ShellDll.SFGAO attrFlag = 0; attrFlag = attrFlag | ExpTreeLib.ShellDll.SFGAO.FOLDER | ExpTreeLib.ShellDll.SFGAO.STREAM; //Note: for GetAttributesOf, we must provide an array, in all cases with 1 element IntPtr[] aPidl = new IntPtr[1]; aPidl[0] = item; m_Folder.GetAttributesOf(1, aPidl, ref attrFlag); if (! XPorAbove) { if (System.Convert.ToBoolean(attrFlag & ExpTreeLib.ShellDll.SFGAO.FOLDER)) //Don't need it { goto SKIPONE; } } else //XP or above { if ((attrFlag & ExpTreeLib.ShellDll.SFGAO.FOLDER)!=0 && (attrFlag & ExpTreeLib.ShellDll.SFGAO.STREAM)==0) { goto SKIPONE; } } } //just relative pidls for fast look, no CShITem overhead rVal.Add(PIDLClone(item)); //caller must free SKIPONE: Marshal.FreeCoTaskMem(item); //if New kept it, it kept a copy item = IntPtr.Zero; itemCnt = 0; // Application.DoEvents() HR = IEnum.GetNext(1, ref item, ref itemCnt); } } else { if (HR != 1) { goto HRError; //1 means no more } } } else { goto HRError; } //Normal Exit NORMAL: if (IEnum != null) { Marshal.ReleaseComObject(IEnum); } //rVal.TrimToSize(); return rVal; // Error Exit for all Com errors HRError: //not ready disks will return the following error //If HR = &HFFFFFFFF800704C7 Then // GoTo NORMAL //ElseIf HR = &HFFFFFFFF80070015 Then // GoTo NORMAL // 'unavailable net resources will return these //ElseIf HR = &HFFFFFFFF80040E96 Or HR = &HFFFFFFFF80040E19 Then // GoTo NORMAL //ElseIf HR = &HFFFFFFFF80004001 Then 'Certain "Not Implemented" features will return this // GoTo NORMAL //ElseIf HR = &HFFFFFFFF80004005 Then // GoTo NORMAL //ElseIf HR = &HFFFFFFFF800704C6 Then // GoTo NORMAL //End If if (IEnum != null) { Marshal.ReleaseComObject(IEnum); } //#If Debug Then // Marshal.ThrowExceptionForHR(HR) //#End If rVal = new List<IntPtr>(); //sometimes it is a non-fatal error,ignored goto NORMAL; }
private List<CShItem> GetContents(ExpTreeLib.ShellDll.SHCONTF flags) { List<IntPtr> pidlList = GetContentsPIDL(flags); List<CShItem> rVal = new List<CShItem>(pidlList.Count); foreach(IntPtr pidl in pidlList) rVal.Add(new CShItem(m_Folder, pidl, this)); return rVal; }
private bool m_XtrInfo; //= False #endregion Fields #region Constructors /// <summary>Create instance based on a non-desktop CSIDL. /// Will create based on any CSIDL Except the DeskTop CSIDL</summary> /// <param name="ID">Value from CSIDL enumeration denoting the folder to create this CShItem of.</param> /// public CShItem(ExpTreeLib.ShellDll.CSIDL ID) { if (DesktopBase == null) { DesktopBase = new CShItem(); //This initializes the Desktop folder } int HR; if (ID == ExpTreeLib.ShellDll.CSIDL.MYDOCUMENTS) { int pchEaten = 0; int pdwAttributes = 0; HR = DesktopBase.m_Folder.ParseDisplayName(0, IntPtr.Zero, "::{450d8fba-ad25-11d0-98a8-0800361b1103}", ref pchEaten, ref m_Pidl, ref pdwAttributes); } else { HR = ExpTreeLib.ShellDll.SHGetSpecialFolderLocation(0, (int)ID, ref m_Pidl); } if (HR == ExpTreeLib.ShellDll.NOERROR) { ShellDll.IShellFolder pParent; IntPtr relPidl = IntPtr.Zero; pParent = GetParentOf(m_Pidl, ref relPidl); //Get the Attributes SetUpAttributes(pParent, relPidl); //Set unfetched value for IconIndex.... m_IconIndexNormal = - 1; m_IconIndexOpen = - 1; //finally, set up my Folder if (m_IsFolder) { HR = pParent.BindToObject(relPidl, IntPtr.Zero, ref ExpTreeLib.ShellDll.IID_IShellFolder, ref m_Folder); if (HR != ExpTreeLib.ShellDll.NOERROR) { Marshal.ThrowExceptionForHR(HR); } } Marshal.ReleaseComObject(pParent); //if PidlCount(m_Pidl) = 1 then relPidl is same as m_Pidl, don't release if (PidlCount(m_Pidl) > 1) { Marshal.FreeCoTaskMem(relPidl); } } else { Marshal.ThrowExceptionForHR(HR); } }
public static CShItem GetCShItem(ExpTreeLib.ShellDll.CSIDL ID) { CShItem returnValue; returnValue = null; //avoid VB2005 Warning if (ID == ExpTreeLib.ShellDll.CSIDL.DESKTOP) { return GetDeskTop(); } int HR; IntPtr tmpPidl = IntPtr.Zero; if (ID == ExpTreeLib.ShellDll.CSIDL.MYDOCUMENTS) { int pchEaten = 0; int pdwAttributes = 0; HR = GetDeskTop().Folder.ParseDisplayName(0, IntPtr.Zero, "::{450d8fba-ad25-11d0-98a8-0800361b1103}", ref pchEaten, ref tmpPidl, ref pdwAttributes); } else { HR = ExpTreeLib.ShellDll.SHGetSpecialFolderLocation(0, (int)ID, ref tmpPidl); } if (HR == ExpTreeLib.ShellDll.NOERROR) { returnValue = FindCShItem(tmpPidl); if (returnValue == null) { try { returnValue = new CShItem(ID); } catch { returnValue = null; } } } if (! tmpPidl.Equals(IntPtr.Zero)) { Marshal.FreeCoTaskMem(tmpPidl); } return returnValue; }