internal ShellItem GetShellItem(PIDL pidlFull) { ShellItem current = DesktopItem; if (pidlFull.Ptr == IntPtr.Zero) { return(current); } foreach (IntPtr pidlRel in pidlFull) { int index; if ((index = current.IndexOf(pidlRel)) > -1) { current = current[index]; } else { current = null; break; } } return(current); }
public PIDL(PIDL pidl, bool clone) { if (clone) this.pidl = ILClone(pidl.Ptr); else this.pidl = pidl.Ptr; }
public bool MoveNext() { if (clonePidl != IntPtr.Zero) { Marshal.FreeCoTaskMem(clonePidl); clonePidl = IntPtr.Zero; } if (start) { start = false; return(true); } else { IntPtr newPidl = ILGetNext(currentPidl); if (!PIDL.IsEmpty(newPidl)) { currentPidl = newPidl; return(true); } else { return(false); } } }
public PIDL(PIDL pidl, bool clone) { if (clone) { this.pidl = ILClone(pidl.Ptr); } else { this.pidl = pidl.Ptr; } }
internal ShellItem(ShellBrowser browser, ShellAPI.CSIDL specialFolder) { IntPtr pidl = IntPtr.Zero; ShellAPI.SHGetSpecialFolderLocation(IntPtr.Zero, specialFolder, out pidl); // IntPtr shellFolderPtr; this.browser = browser; // if (specialFolder == ShellAPI.CSIDL.DESKTOP) { ShellAPI.SHGetDesktopFolder(out shellFolderPtr); // this.shellFolderPtr = shellFolderPtr; this.shellFolder = (IShellFolder)Marshal.GetTypedObjectForIUnknown(shellFolderPtr, typeof(IShellFolder)); } else { this.shellFolder = GetShellFolderFromPidl(pidl, out shellFolderPtr); // this.parentItem = browser.DesktopItem; } // subFiles = new ShellItemCollection(this); subFolders = new ShellItemCollection(this); pidlRel = new PIDL(pidl, false); ShellAPI.SHFILEINFO info = new ShellAPI.SHFILEINFO(); ShellAPI.SHGetFileInfo(pidlRel.Ptr, 0, ref info, ShellAPI.cbFileInfo, ShellAPI.SHGFI.PIDL | ShellAPI.SHGFI.TYPENAME | ShellAPI.SHGFI.SYSICONINDEX | ShellAPI.SHGFI.DISPLAYNAME); type = info.szTypeName; text = info.szDisplayName; // StringBuilder pathBuilder = new StringBuilder(ShellAPI.MAX_PATH); ShellAPI.SHGetFolderPath( IntPtr.Zero, specialFolder, IntPtr.Zero, ShellAPI.SHGFP.TYPE_CURRENT, pathBuilder); this.path = pathBuilder.ToString(); // if (specialFolder == ShellAPI.CSIDL.DESKTOP) { ShellImageList.SetIconIndex(this, info.iIcon, false); ShellImageList.SetIconIndex(this, info.iIcon, true); // SetAttributesDesktop(this); } else { SetAttributesFolder(this); SetInfo(this); } sortFlag = 1; }
protected override void WndProc(ref Message m) { if (m.Msg == (int)ShellAPI.WM.SH_NOTIFY) { ShellAPI.SHNOTIFYSTRUCT shNotify = (ShellAPI.SHNOTIFYSTRUCT)Marshal.PtrToStructure(m.WParam, typeof(ShellAPI.SHNOTIFYSTRUCT)); switch ((ShellAPI.SHCNE)m.LParam) { //#region File Changes //case ShellAPI.SHCNE.CREATE: // #region Create Item // { // if (!PIDL.IsEmpty(shNotify.dwItem1)) // { // IntPtr parent, child, relative; // PIDL.SplitPidl(shNotify.dwItem1, out parent, out child); // PIDL parentPIDL = new PIDL(parent, false); // ShellItem parentItem = br.GetShellItem(parentPIDL); // if (parentItem != null && parentItem.FilesExpanded && !parentItem.SubFiles.Contains(child)) // { // ShellAPI.SHGetRealIDL( // parentItem.ShellFolder, // child, // out relative); // parentItem.AddItem(new ShellItem(br, parentItem, relative)); // } // Marshal.FreeCoTaskMem(child); // parentPIDL.Free(); // } // } // #endregion // break; //case ShellAPI.SHCNE.RENAMEITEM: // #region Rename Item // { // if (!PIDL.IsEmpty(shNotify.dwItem1) && !PIDL.IsEmpty(shNotify.dwItem2)) // { // ShellItem item = br.GetShellItem(new PIDL(shNotify.dwItem1, true)); // if (item != null) // item.Update(shNotify.dwItem2, ShellItemUpdateType.Renamed); // } // } // #endregion // break; //case ShellAPI.SHCNE.DELETE: // #region Delete Item // { // if (!PIDL.IsEmpty(shNotify.dwItem1)) // { // IntPtr parent, child; // PIDL.SplitPidl(shNotify.dwItem1, out parent, out child); // PIDL parentPIDL = new PIDL(parent, false); // ShellItem parentItem = br.GetShellItem(parentPIDL); // if (parentItem != null && parentItem.SubFiles.Contains(child)) // parentItem.RemoveItem(parentItem.SubFiles[child]); // Marshal.FreeCoTaskMem(child); // parentPIDL.Free(); // } // } // #endregion // break; //case ShellAPI.SHCNE.UPDATEITEM: // #region Update Item // { // if (!PIDL.IsEmpty(shNotify.dwItem1)) // { // ShellItem item = br.GetShellItem(new PIDL(shNotify.dwItem1, true)); // if (item != null) // { // Console.Out.WriteLine("Item: {0}", item); // item.Update(IntPtr.Zero, ShellItemUpdateType.Updated); // item.Update(IntPtr.Zero, ShellItemUpdateType.IconChange); // } // } // } // #endregion // break; //#endregion #region Folder Changes case ShellAPI.SHCNE.MKDIR: case ShellAPI.SHCNE.DRIVEADD: case ShellAPI.SHCNE.DRIVEADDGUI: #region Make Directory { if (!PIDL.IsEmpty(shNotify.dwItem1)) { IntPtr parent, child, relative; PIDL.SplitPidl(shNotify.dwItem1, out parent, out child); PIDL parentPIDL = new PIDL(parent, false); ShellItem parentItem = br.GetShellItem(parentPIDL); if (parentItem != null && parentItem.FoldersExpanded && !parentItem.SubFolders.Contains(child)) { ShellAPI.SHGetRealIDL( parentItem.ShellFolder, child, out relative); IntPtr shellFolderPtr; if (parentItem.ShellFolder.BindToObject( relative, IntPtr.Zero, ref ShellAPI.IID_IShellFolder, out shellFolderPtr) == ShellAPI.S_OK) { parentItem.AddItem(new ShellItem(br, parentItem, relative, shellFolderPtr)); } else Marshal.FreeCoTaskMem(relative); } Marshal.FreeCoTaskMem(child); //parentPIDL.Free(); } } #endregion break; case ShellAPI.SHCNE.RENAMEFOLDER: //#region Rename Directory //{ // if (!PIDL.IsEmpty(shNotify.dwItem1) && !PIDL.IsEmpty(shNotify.dwItem2)) // { // ShellItem item = br.GetShellItem(new PIDL(shNotify.dwItem1, false)); // if (item != null) // { // //Console.Out.WriteLine("Update: {0}", item); // item.Update(shNotify.dwItem2, ShellItemUpdateType.Renamed); // } // } //} //#endregion break; case ShellAPI.SHCNE.RMDIR: case ShellAPI.SHCNE.DRIVEREMOVED: //#region Remove Directory //{ // if (!PIDL.IsEmpty(shNotify.dwItem1)) // { // IntPtr parent, child; // PIDL.SplitPidl(shNotify.dwItem1, out parent, out child); // PIDL parentPIDL = new PIDL(parent, false); // ShellItem parentItem = br.GetShellItem(parentPIDL); // if (parentItem != null && parentItem.SubFolders.Contains(child)) // parentItem.RemoveItem(parentItem.SubFolders[child]); // Marshal.FreeCoTaskMem(child); // parentPIDL.Free(); // } //} //#endregion break; case ShellAPI.SHCNE.UPDATEDIR: case ShellAPI.SHCNE.ATTRIBUTES: #region Update Directory { if (!PIDL.IsEmpty(shNotify.dwItem1)) { ShellItem item = br.GetShellItem(new PIDL(shNotify.dwItem1, true)); if (item != null) { item.Update(IntPtr.Zero, ShellItemUpdateType.Updated); item.Update(IntPtr.Zero, ShellItemUpdateType.IconChange); } } } #endregion break; case ShellAPI.SHCNE.MEDIAINSERTED: case ShellAPI.SHCNE.MEDIAREMOVED: #region Media Change { if (!PIDL.IsEmpty(shNotify.dwItem1)) { ShellItem item = br.GetShellItem(new PIDL(shNotify.dwItem1, true)); if (item != null) item.Update(IntPtr.Zero, ShellItemUpdateType.MediaChange); } } #endregion break; #endregion #region Other Changes case ShellAPI.SHCNE.ASSOCCHANGED: break; case ShellAPI.SHCNE.NETSHARE: case ShellAPI.SHCNE.NETUNSHARE: break; case ShellAPI.SHCNE.UPDATEIMAGE: UpdateRecycleBin(); break; #endregion } } base.WndProc(ref m); }
internal ShellItem(ShellBrowser browser, ShellItem parentItem, IntPtr pidl, IntPtr shellFolderPtr) { this.browser = browser; this.parentItem = parentItem; this.shellFolderPtr = shellFolderPtr; this.shellFolder = (IShellFolder)Marshal.GetTypedObjectForIUnknown(shellFolderPtr, typeof(IShellFolder)); subFiles = new ShellItemCollection(this); subFolders = new ShellItemCollection(this); pidlRel = new PIDL(pidl, false); SetText(this); SetPath(this); SetAttributesFolder(this); SetInfo(this); sortFlag = MakeSortFlag(this); }
internal void Update(IntPtr newPidlFull, ShellItemUpdateType changeType) { browser.UpdateCondition.ContinueUpdate = false; lock (browser) { #region Change Pidl and ShellFolder if (newPidlFull != IntPtr.Zero) { IntPtr tempPidl = PIDL.ILClone(PIDL.ILFindLastID(newPidlFull)), newPidlRel, newShellFolderPtr; ShellAPI.SHGetRealIDL(ParentItem.ShellFolder, tempPidl, out newPidlRel); if (IsFolder && ParentItem.ShellFolder.BindToObject( newPidlRel, IntPtr.Zero, ref ShellAPI.IID_IShellFolder, out newShellFolderPtr) == ShellAPI.S_OK) { Marshal.ReleaseComObject(shellFolder); Marshal.Release(shellFolderPtr); pidlRel.Free(); shellFolderPtr = newShellFolderPtr; shellFolder = (IShellFolder)Marshal.GetTypedObjectForIUnknown(shellFolderPtr, typeof(IShellFolder)); pidlRel = new PIDL(newPidlRel, false); foreach (ShellItem child in SubFolders) UpdateShellFolders(child); } else { pidlRel.Free(); pidlRel = new PIDL(newPidlRel, false); } Marshal.FreeCoTaskMem(tempPidl); Marshal.FreeCoTaskMem(newPidlFull); } #endregion #region Make Other Changes switch (changeType) { case ShellItemUpdateType.Renamed: SetText(this); SetPath(this); break; case ShellItemUpdateType.Updated: if (IsFolder) SetAttributesFolder(this); else SetAttributesFile(this); break; case ShellItemUpdateType.MediaChange: SetInfo(this); SetText(this); Clear(true, true); break; case ShellItemUpdateType.IconChange: SetInfo(this); break; } #endregion } if (ShellItemUpdated != null) ShellItemUpdated(this, EventArgs.Empty); Browser.OnShellItemUpdate(ParentItem, new ShellItemUpdateEventArgs(this, this, changeType)); }
internal ShellItem(ShellBrowser browser, ShellItem parentItem, IntPtr pidl) { this.browser = browser; this.parentItem = parentItem; pidlRel = new PIDL(pidl, false); SetText(this); SetPath(this); SetAttributesFile(this); SetInfo(this); sortFlag = MakeSortFlag(this); }
internal ShellItem GetShellItem(PIDL pidlFull) { ShellItem current = DesktopItem; if (pidlFull.Ptr == IntPtr.Zero) return current; foreach (IntPtr pidlRel in pidlFull) { int index; if ((index = current.IndexOf(pidlRel)) > -1) { current = current[index]; } else { current = null; break; } } return current; }
internal static void SetIconIndex(ShellItem item, int index, bool SelectedIcon) { bool HasOverlay = false; //true if it's an overlay int rVal = 0; //The returned Index ShellAPI.SHGFI dwflag = ShellAPI.SHGFI.SYSICONINDEX | ShellAPI.SHGFI.PIDL | ShellAPI.SHGFI.ICON; ShellAPI.FILE_ATTRIBUTE dwAttr = 0; //build Key into HashTable for this Item int Key = index * 256; if (item.IsLink) { Key = Key | 1; dwflag = dwflag | ShellAPI.SHGFI.LINKOVERLAY; HasOverlay = true; } if (item.IsShared) { Key = Key | 2; dwflag = dwflag | ShellAPI.SHGFI.ADDOVERLAYS; HasOverlay = true; } if (SelectedIcon) { Key = Key | 4; dwflag = dwflag | ShellAPI.SHGFI.OPENICON; HasOverlay = true; //not really an overlay, but handled the same } if (imageTable.ContainsKey(Key)) { rVal = (int)imageTable[Key]; } else if (!HasOverlay && !item.IsHidden) //for non-overlay icons, we already have { rVal = (int)System.Math.Floor((double)Key / 256); // the right index -- put in table imageTable[Key] = rVal; } else //don't have iconindex for an overlay, get it. { if (item.IsFileSystem & !item.IsDisk & !item.IsFolder) { dwflag = dwflag | ShellAPI.SHGFI.USEFILEATTRIBUTES; dwAttr = dwAttr | ShellAPI.FILE_ATTRIBUTE.NORMAL; } PIDL pidlFull = item.PIDLFull; ShellAPI.SHFILEINFO shfiSmall = new ShellAPI.SHFILEINFO(); ShellAPI.SHGetFileInfo(pidlFull.Ptr, dwAttr, ref shfiSmall, ShellAPI.cbFileInfo, dwflag | ShellAPI.SHGFI.SMALLICON); ShellAPI.SHFILEINFO shfiLarge = new ShellAPI.SHFILEINFO(); ShellAPI.SHGetFileInfo(pidlFull.Ptr, dwAttr, ref shfiLarge, ShellAPI.cbFileInfo, dwflag | ShellAPI.SHGFI.LARGEICON); Marshal.FreeCoTaskMem(pidlFull.Ptr); lock (imageTable) { rVal = ShellAPI.ImageList_ReplaceIcon(smallImageListHandle, -1, shfiSmall.hIcon); ShellAPI.ImageList_ReplaceIcon(largeImageListHandle, -1, shfiLarge.hIcon); } ShellAPI.DestroyIcon(shfiSmall.hIcon); ShellAPI.DestroyIcon(shfiLarge.hIcon); imageTable[Key] = rVal; } if (SelectedIcon) { item.SelectedImageIndex = rVal; } else { item.ImageIndex = rVal; } }
protected override void WndProc(ref Message m) { if (m.Msg == (int)ShellAPI.WM.SH_NOTIFY) { ShellAPI.SHNOTIFYSTRUCT shNotify = (ShellAPI.SHNOTIFYSTRUCT)Marshal.PtrToStructure(m.WParam, typeof(ShellAPI.SHNOTIFYSTRUCT)); switch ((ShellAPI.SHCNE)m.LParam) { //#region File Changes //case ShellAPI.SHCNE.CREATE: // #region Create Item // { // if (!PIDL.IsEmpty(shNotify.dwItem1)) // { // IntPtr parent, child, relative; // PIDL.SplitPidl(shNotify.dwItem1, out parent, out child); // PIDL parentPIDL = new PIDL(parent, false); // ShellItem parentItem = br.GetShellItem(parentPIDL); // if (parentItem != null && parentItem.FilesExpanded && !parentItem.SubFiles.Contains(child)) // { // ShellAPI.SHGetRealIDL( // parentItem.ShellFolder, // child, // out relative); // parentItem.AddItem(new ShellItem(br, parentItem, relative)); // } // Marshal.FreeCoTaskMem(child); // parentPIDL.Free(); // } // } // #endregion // break; //case ShellAPI.SHCNE.RENAMEITEM: // #region Rename Item // { // if (!PIDL.IsEmpty(shNotify.dwItem1) && !PIDL.IsEmpty(shNotify.dwItem2)) // { // ShellItem item = br.GetShellItem(new PIDL(shNotify.dwItem1, true)); // if (item != null) // item.Update(shNotify.dwItem2, ShellItemUpdateType.Renamed); // } // } // #endregion // break; //case ShellAPI.SHCNE.DELETE: // #region Delete Item // { // if (!PIDL.IsEmpty(shNotify.dwItem1)) // { // IntPtr parent, child; // PIDL.SplitPidl(shNotify.dwItem1, out parent, out child); // PIDL parentPIDL = new PIDL(parent, false); // ShellItem parentItem = br.GetShellItem(parentPIDL); // if (parentItem != null && parentItem.SubFiles.Contains(child)) // parentItem.RemoveItem(parentItem.SubFiles[child]); // Marshal.FreeCoTaskMem(child); // parentPIDL.Free(); // } // } // #endregion // break; //case ShellAPI.SHCNE.UPDATEITEM: // #region Update Item // { // if (!PIDL.IsEmpty(shNotify.dwItem1)) // { // ShellItem item = br.GetShellItem(new PIDL(shNotify.dwItem1, true)); // if (item != null) // { // Console.Out.WriteLine("Item: {0}", item); // item.Update(IntPtr.Zero, ShellItemUpdateType.Updated); // item.Update(IntPtr.Zero, ShellItemUpdateType.IconChange); // } // } // } // #endregion // break; //#endregion #region Folder Changes case ShellAPI.SHCNE.MKDIR: case ShellAPI.SHCNE.DRIVEADD: case ShellAPI.SHCNE.DRIVEADDGUI: #region Make Directory { if (!PIDL.IsEmpty(shNotify.dwItem1)) { IntPtr parent, child, relative; PIDL.SplitPidl(shNotify.dwItem1, out parent, out child); PIDL parentPIDL = new PIDL(parent, false); ShellItem parentItem = br.GetShellItem(parentPIDL); if (parentItem != null && parentItem.FoldersExpanded && !parentItem.SubFolders.Contains(child)) { ShellAPI.SHGetRealIDL( parentItem.ShellFolder, child, out relative); IntPtr shellFolderPtr; if (parentItem.ShellFolder.BindToObject( relative, IntPtr.Zero, ref ShellAPI.IID_IShellFolder, out shellFolderPtr) == ShellAPI.S_OK) { parentItem.AddItem(new ShellItem(br, parentItem, relative, shellFolderPtr)); } else { Marshal.FreeCoTaskMem(relative); } } Marshal.FreeCoTaskMem(child); //parentPIDL.Free(); } } #endregion break; case ShellAPI.SHCNE.RENAMEFOLDER: //#region Rename Directory //{ // if (!PIDL.IsEmpty(shNotify.dwItem1) && !PIDL.IsEmpty(shNotify.dwItem2)) // { // ShellItem item = br.GetShellItem(new PIDL(shNotify.dwItem1, false)); // if (item != null) // { // //Console.Out.WriteLine("Update: {0}", item); // item.Update(shNotify.dwItem2, ShellItemUpdateType.Renamed); // } // } //} //#endregion break; case ShellAPI.SHCNE.RMDIR: case ShellAPI.SHCNE.DRIVEREMOVED: //#region Remove Directory //{ // if (!PIDL.IsEmpty(shNotify.dwItem1)) // { // IntPtr parent, child; // PIDL.SplitPidl(shNotify.dwItem1, out parent, out child); // PIDL parentPIDL = new PIDL(parent, false); // ShellItem parentItem = br.GetShellItem(parentPIDL); // if (parentItem != null && parentItem.SubFolders.Contains(child)) // parentItem.RemoveItem(parentItem.SubFolders[child]); // Marshal.FreeCoTaskMem(child); // parentPIDL.Free(); // } //} //#endregion break; case ShellAPI.SHCNE.UPDATEDIR: case ShellAPI.SHCNE.ATTRIBUTES: #region Update Directory { if (!PIDL.IsEmpty(shNotify.dwItem1)) { ShellItem item = br.GetShellItem(new PIDL(shNotify.dwItem1, true)); if (item != null) { item.Update(IntPtr.Zero, ShellItemUpdateType.Updated); item.Update(IntPtr.Zero, ShellItemUpdateType.IconChange); } } } #endregion break; case ShellAPI.SHCNE.MEDIAINSERTED: case ShellAPI.SHCNE.MEDIAREMOVED: #region Media Change { if (!PIDL.IsEmpty(shNotify.dwItem1)) { ShellItem item = br.GetShellItem(new PIDL(shNotify.dwItem1, true)); if (item != null) { item.Update(IntPtr.Zero, ShellItemUpdateType.MediaChange); } } } #endregion break; #endregion #region Other Changes case ShellAPI.SHCNE.ASSOCCHANGED: break; case ShellAPI.SHCNE.NETSHARE: case ShellAPI.SHCNE.NETUNSHARE: break; case ShellAPI.SHCNE.UPDATEIMAGE: UpdateRecycleBin(); break; #endregion } } base.WndProc(ref m); }