📄 shellitem.cs
字号:
return ((expandFiles == filesExpanded || !expandFiles) && (expandFolders == foldersExpanded || !expandFolders));
}
internal void Clear(bool clearFiles, bool clearFolders)
{
if (((clearFiles && filesExpanded) || !clearFiles) &&
((clearFolders && foldersExpanded) || !clearFolders) &&
(clearFiles || clearFolders) && ShellFolder != null && !disposed)
{
lock (browser)
{
try
{
#region Reset Files
if (clearFiles)
{
foreach (IDisposable item in subFiles)
item.Dispose();
subFiles.Clear();
filesExpanded = false;
}
#endregion
#region Reset Folders
if (clearFolders)
{
foreach (IDisposable item in subFolders)
item.Dispose();
subFolders.Clear();
foldersExpanded = false;
}
#endregion
}
catch (Exception) { }
}
}
}
#region Updates
internal void Update(bool updateFiles, bool updateFolders)
{
if (browser.UpdateCondition.ContinueUpdate && (updateFiles || updateFolders) && ShellFolder != null && !disposed)
{
lock (browser)
{
#region Fields
IntPtr fileEnumPtr = IntPtr.Zero, folderEnumPtr = IntPtr.Zero;
IEnumIDList fileEnum = null, folderEnum = null;
IntPtr pidlSubItem;
int celtFetched;
ShellAPI.SHCONTF fileFlag =
ShellAPI.SHCONTF.NONFOLDERS |
ShellAPI.SHCONTF.INCLUDEHIDDEN;
ShellAPI.SHCONTF folderFlag =
ShellAPI.SHCONTF.FOLDERS |
ShellAPI.SHCONTF.INCLUDEHIDDEN;
bool[] fileExists;
fileExists = new bool[subFiles.Count];
bool[] folderExists;
folderExists = new bool[subFolders.Count];
int index;
#endregion
try
{
#region Update Files
if (browser.UpdateCondition.ContinueUpdate && updateFiles)
{
ShellItemCollection add = new ShellItemCollection(this);
ShellItemCollection remove = new ShellItemCollection(this);
bool fileEnumCompleted = false;
#region Add Files
if (this.Equals(browser.DesktopItem) || parentItem.Equals(browser.DesktopItem))
{
if (ShellFolder.EnumObjects(
IntPtr.Zero,
fileFlag,
out fileEnumPtr) == ShellAPI.S_OK)
{
fileEnum = (IEnumIDList)Marshal.GetTypedObjectForIUnknown(fileEnumPtr, typeof(IEnumIDList));
ShellAPI.SFGAO attribs = ShellAPI.SFGAO.FOLDER;
while (browser.UpdateCondition.ContinueUpdate &&
fileEnum.Next(1, out pidlSubItem, out celtFetched) == ShellAPI.S_OK && celtFetched == 1)
{
ShellFolder.GetAttributesOf(1, new IntPtr[] { pidlSubItem }, ref attribs);
if ((attribs & ShellAPI.SFGAO.FOLDER) == 0)
{
if ((index = subFiles.IndexOf(pidlSubItem)) == -1)
{
ShellItem newItem = new ShellItem(browser, this, pidlSubItem);
if (!subFolders.Contains(newItem.Text))
{
add.Add(newItem);
}
}
else if (index < fileExists.Length)
{
fileExists[index] = true;
Marshal.FreeCoTaskMem(pidlSubItem);
}
}
else
Marshal.FreeCoTaskMem(pidlSubItem);
}
fileEnumCompleted = true;
}
}
else
{
if (ShellFolder.EnumObjects(
IntPtr.Zero,
fileFlag,
out fileEnumPtr) == ShellAPI.S_OK)
{
fileEnum = (IEnumIDList)Marshal.GetTypedObjectForIUnknown(fileEnumPtr, typeof(IEnumIDList));
while (browser.UpdateCondition.ContinueUpdate &&
fileEnum.Next(1, out pidlSubItem, out celtFetched) == ShellAPI.S_OK && celtFetched == 1)
{
if ((index = subFiles.IndexOf(pidlSubItem)) == -1)
{
add.Add(new ShellItem(browser, this, pidlSubItem));
}
else if (index < fileExists.Length)
{
fileExists[index] = true;
Marshal.FreeCoTaskMem(pidlSubItem);
}
}
fileEnumCompleted = true;
}
}
#endregion
#region Remove Files
for (int i = 0; fileEnumCompleted && browser.UpdateCondition.ContinueUpdate && i < fileExists.Length; i++)
{
if (!fileExists[i] && subFiles[i] != null)
{
remove.Add(subFiles[i]);
}
}
#endregion
#region Do Events
if (fileEnumCompleted && browser.UpdateCondition.ContinueUpdate)
{
int newIndex;
foreach (ShellItem oldItem in remove)
{
if ((newIndex = add.IndexOf(oldItem.Text)) > -1)
{
ShellItem newItem = add[newIndex];
add.Remove(newItem);
oldItem.pidlRel.Free();
oldItem.pidlRel = new PIDL(newItem.pidlRel.Ptr, true);
oldItem.shellFolder = newItem.shellFolder;
oldItem.shellFolderPtr = newItem.shellFolderPtr;
((IDisposable)newItem).Dispose();
browser.OnShellItemUpdate(this, new ShellItemUpdateEventArgs(oldItem, oldItem, ShellItemUpdateType.Updated));
}
else
{
subFiles.Remove(oldItem);
browser.OnShellItemUpdate(this, new ShellItemUpdateEventArgs(oldItem, null, ShellItemUpdateType.Deleted));
((IDisposable)oldItem).Dispose();
}
}
foreach (ShellItem newItem in add)
{
subFiles.Add(newItem);
browser.OnShellItemUpdate(this, new ShellItemUpdateEventArgs(null, newItem, ShellItemUpdateType.Created));
}
subFiles.Capacity = subFiles.Count;
subFiles.Sort();
filesExpanded = true;
}
#endregion
}
#endregion
#region Update Folders
if (browser.UpdateCondition.ContinueUpdate && updateFolders)
{
ShellItemCollection add = new ShellItemCollection(this);
ShellItemCollection remove = new ShellItemCollection(this);
bool folderEnumCompleted = false;
#region Add Folders
if (ShellFolder.EnumObjects(
IntPtr.Zero,
folderFlag,
out folderEnumPtr) == ShellAPI.S_OK)
{
folderEnum = (IEnumIDList)Marshal.GetTypedObjectForIUnknown(folderEnumPtr, typeof(IEnumIDList));
while (browser.UpdateCondition.ContinueUpdate &&
folderEnum.Next(1, out pidlSubItem, out celtFetched) == ShellAPI.S_OK && celtFetched == 1)
{
if ((index = subFolders.IndexOf(pidlSubItem)) == -1)
{
IntPtr shellFolderPtr;
if (ShellFolder.BindToObject(
pidlSubItem,
IntPtr.Zero,
ref ShellAPI.IID_IShellFolder,
out shellFolderPtr) == ShellAPI.S_OK)
{
add.Add(new ShellItem(
browser,
this,
pidlSubItem,
shellFolderPtr));
}
}
else if (index < folderExists.Length)
{
folderExists[index] = true;
Marshal.FreeCoTaskMem(pidlSubItem);
}
}
folderEnumCompleted = true;
}
#endregion
#region Remove Folders
for (int i = 0; folderEnumCompleted && browser.UpdateCondition.ContinueUpdate && i < folderExists.Length; i++)
{
if (!folderExists[i] && subFolders[i] != null)
{
remove.Add(subFolders[i]);
}
}
#endregion
#region Do Events
if (folderEnumCompleted && browser.UpdateCondition.ContinueUpdate)
{
int newIndex;
foreach (ShellItem oldItem in remove)
{
if ((newIndex = add.IndexOf(oldItem.Text)) > -1)
{
ShellItem newItem = add[newIndex];
add.Remove(newItem);
oldItem.pidlRel.Free();
oldItem.pidlRel = new PIDL(newItem.pidlRel, true);
Marshal.ReleaseComObject(oldItem.shellFolder);
Marshal.Release(oldItem.shellFolderPtr);
oldItem.shellFolder = newItem.shellFolder;
oldItem.shellFolderPtr = newItem.shellFolderPtr;
newItem.shellFolder = null;
newItem.shellFolderPtr = IntPtr.Zero;
((IDisposable)newItem).Dispose();
browser.OnShellItemUpdate(this, new ShellItemUpdateEventArgs(oldItem, oldItem, ShellItemUpdateType.Updated));
}
else
{
subFolders.Remove(oldItem);
browser.OnShellItemUpdate(this, new ShellItemUpdateEventArgs(oldItem, null, ShellItemUpdateType.Deleted));
((IDisposable)oldItem).Dispose();
}
}
foreach (ShellItem newItem in add)
{
subFolders.Add(newItem);
browser.OnShellItemUpdate(this, new ShellItemUpdateEventArgs(null, newItem, ShellItemUpdateType.Created));
}
subFolders.Capacity = subFolders.Count;
subFolders.Sort();
foldersExpanded = true;
}
#endregion
}
#endregion
}
catch (Exception) { }
finally
{
#region Free
if (folderEnum != null)
{
Marshal.ReleaseComObject(folderEnum);
Marshal.Release(folderEnumPtr);
}
if (fileEnum != null)
{
Marshal.ReleaseComObject(fileEnum);
if (!(type == browser.SystemFolderName && string.Compare(text, "Control Panel", true) == 0))
Marshal.Release(fileEnumPtr);
}
#endregion
}
}
}
}
internal void AddItem(ShellItem item)
{
browser.UpdateCondition.ContinueUpdate = false;
lock (browser)
{
try
{
if (item.IsFolder)
SubFolders.Add(item);
else
SubFiles.Add(item);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -