private void NavigateSearch(IListItemEx destination, Boolean isInSameTab = false, Boolean refresh = false, Boolean isCancel = false) { SaveSettingsToDatabase(this.CurrentFolder); if (destination == null) return; if (this.RequestedCurrentLocation == destination && !refresh) return; //if (this._RequestedCurrentLocation != destination) { //} _ResetEvent.Set(); if (this._Threads.Any()) { _Mre.Set(); this._ResetEvent.Set(); foreach (var thread in this._Threads.ToArray()) { thread.Abort(); this._Threads.Remove(thread); } } this._UnvalidateTimer.Stop(); this._IsDisplayEmptyText = false; User32.SendMessage(this.LVHandle, MSG.LVM_SETITEMCOUNT, 0, 0); this.DisableGroups(); this._ItemForRename = -1; this._LastItemForRename = -1; Items.Clear(); this._AddedItems.Clear(); this.LargeImageList.ReInitQueues(); this.SmallImageList.ReInitQueues(); this._CuttedIndexes.Clear(); this.RequestedCurrentLocation = destination; if (!refresh) Navigating?.Invoke(this, new NavigatingEventArgs(destination, isInSameTab)); var columns = new Collumns(); Int32 CurrentI = 0, LastI = 0, K = 0; this.IsNavigationInProgress = true; _ResetTimer.Stop(); this.RemoveAllCollumns(); this.AddDefaultColumns(false, true); this.IsViewSelectionAllowed = true; this.Invoke((Action)(() => this._NavWaitTimer.Start())); var navigationThread = new Thread(() => { destination = FileSystemListItem.ToFileSystemItem(destination.ParentHandle, destination.PIDL); this.RequestedCurrentLocation = destination; this.Invoke((Action)(() => { if (!this._SearchTimer.Enabled) { this._SearchTimer.Start(); } })); foreach (var shellItem in destination.TakeWhile(shellItem => !this.IsCancelRequested)) { CurrentI++; _Smre.WaitOne(); if (this.ShowHidden || !shellItem.IsHidden) { shellItem.ItemIndex = K++; this.Items.Add(shellItem); if (CurrentI == 1) { this.Invoke((Action)(() => { this._NavWaitTimer.Stop(); this._IsDisplayEmptyText = false; this._IIListView.ResetEmptyText(); })); } } var delta = CurrentI - LastI; if (delta >= (this.IsSearchNavigating ? 1 : 5000)) { LastI = CurrentI; } if (this.IsSearchNavigating && delta >= 20) Shell32.SetProcessWorkingSetSize(Process.GetCurrentProcess().Handle, -1, -1); } this.IsCancelRequested = false; this.IsNavigationInProgress = false; if (this.RequestedCurrentLocation.NavigationStatus != HResult.S_OK) { this.Invoke((Action)(() => { if (this._SearchTimer.Enabled) this._SearchTimer.Stop(); })); this.BeginInvoke((Action)(() => { var navArgs = new NavigatedEventArgs(this.RequestedCurrentLocation, this.CurrentFolder, isInSameTab); this.CurrentFolder = this.RequestedCurrentLocation; if (!refresh) Navigated?.Invoke(this, navArgs); })); GC.Collect(); Shell32.SetProcessWorkingSetSize(Process.GetCurrentProcess().Handle, -1, -1); if (this._Threads.Count <= 1) return; _Mre.Set(); this._ResetEvent.Set(); this._Threads[0].Abort(); this._Threads.RemoveAt(0); return; } var headerhandle = User32.SendMessage(this.LVHandle, MSG.LVM_GETHEADER, 0, 0); for (var i = 0; i < this.Collumns.Count; i++) { this.Collumns[i].SetSplitButton(headerhandle, i); } if (this.View != ShellViewStyle.Details) AutosizeAllColumns(-2); var sortColIndex = 0; if (sortColIndex > -1) this.SetSortIcon(sortColIndex, SortOrder.Ascending); this.SetSortCollumn(false, this.Collumns.First(), SortOrder.Ascending, false); this.BeginInvoke((Action)(() => { var navArgs = new NavigatedEventArgs(this.RequestedCurrentLocation, this.CurrentFolder, isInSameTab); this.CurrentFolder = this.RequestedCurrentLocation; if (!refresh) Navigated?.Invoke(this, navArgs); })); GC.Collect(); Shell32.SetProcessWorkingSetSize(Process.GetCurrentProcess().Handle, -1, -1); this.Invoke((Action)(() => { if (this._SearchTimer.Enabled) this._SearchTimer.Stop(); })); _Mre.Reset(); _Mre.WaitOne(); }); navigationThread.SetApartmentState(ApartmentState.STA); this._Threads.Add(navigationThread); navigationThread.Start(); }
private void Navigate(IListItemEx destination, Boolean isInSameTab = false, Boolean refresh = false, Boolean isCancel = false) { this.SaveSettingsToDatabase(this.CurrentFolder); // TODO: Document isCancel Param better if (destination == null) { return; } destination = FileSystemListItem.ToFileSystemItem(destination.ParentHandle, destination.PIDL); if (this.RequestedCurrentLocation == destination && !refresh) { return; } //if (this.RequestedCurrentLocation != destination) { // this.IsCancelRequested = true; //} this.LargeImageList.ResetEvent.Set(); this.SmallImageList.ResetEvent.Set(); this._ResetEvent.Set(); if (this._Threads.Count > 0) { this._Mre.Set(); this._ResetEvent.Set(); this.LargeImageList.ResetEvent.Set(); this.SmallImageList.ResetEvent.Set(); foreach (var thread in this._Threads.ToArray()) { thread.Abort(); this._Threads.Remove(thread); } } this._UnvalidateTimer.Stop(); this._IsDisplayEmptyText = false; User32.SendMessage(this.LVHandle, MSG.LVM_SETITEMCOUNT, 0, 0); this.DisableGroups(); this.Focus(false, true); this._ItemForRename = -1; this._LastItemForRename = -1; this.Items.Clear(); this._AddedItems.Clear(); this.LargeImageList.ReInitQueues(); this.SmallImageList.ReInitQueues(); this._CuttedIndexes.Clear(); FolderSettings folderSettings; var isThereSettings = false; isThereSettings = LoadSettingsFromDatabase(destination, out folderSettings); this.RequestedCurrentLocation = destination; if (!refresh) Navigating?.Invoke(this, new NavigatingEventArgs(destination, isInSameTab)); var columns = new Collumns(); Int32 CurrentI = 0, LastI = 0, K = 0; this.IsNavigationInProgress = true; _ResetTimer.Stop(); if (isThereSettings) { if (folderSettings.Columns != null) { this.RemoveAllCollumns(); foreach (var collumn in folderSettings.Columns.Elements()) { var theColumn = this.AllAvailableColumns.FirstOrDefault(w => w.Value.ID == collumn.Attribute("ID").Value).Value;//.Single(); if (theColumn == null) continue; if (this.Collumns.Any(c => c.ID == theColumn?.ID)) continue; if (collumn.Attribute("Width").Value != "0") theColumn.Width = Convert.ToInt32(collumn.Attribute("Width").Value); this.Collumns.Add(theColumn); var column = theColumn.ToNativeColumn(folderSettings.View == ShellViewStyle.Details); User32.SendMessage(this.LVHandle, MSG.LVM_INSERTCOLUMN, this.Collumns.Count - 1, ref column); if (folderSettings.View != ShellViewStyle.Details) this.AutosizeColumn(this.Collumns.Count - 1, -2); } } } else { this.RemoveAllCollumns(); this.AddDefaultColumns(false, true); } if (!String.IsNullOrEmpty(folderSettings.GroupCollumn)) { var colData = this.AllAvailableColumns.FirstOrDefault(w => w.Value.ID == folderSettings.GroupCollumn).Value; if (colData != null) this.EnableGroups(); else this.DisableGroups(); } else { this.DisableGroups(); } columns = this.AllAvailableColumns.FirstOrDefault(w => w.Value.ID == folderSettings.SortColumn).Value; this.IsViewSelectionAllowed = false; if (!isThereSettings) { this.View = ShellViewStyle.Details; } if (folderSettings.View == ShellViewStyle.Details || folderSettings.View == ShellViewStyle.SmallIcon || folderSettings.View == ShellViewStyle.List) { this.ResizeIcons(16); this.View = folderSettings.View; } else if (folderSettings.IconSize >= 16) { this.ResizeIcons(folderSettings.IconSize); var view = (ShellViewStyle)folderSettings.IconSize; if (folderSettings.IconSize != 48 && folderSettings.IconSize != 96 && folderSettings.IconSize != 256) this.View = ShellViewStyle.Thumbnail; else this.View = folderSettings.View; } this.IsViewSelectionAllowed = true; this.Invoke((Action)(() => this._NavWaitTimer.Start())); var navigationThread = new Thread(() => { this.IsCancelRequested = false; destination = FileSystemListItem.ToFileSystemItem(destination.ParentHandle, destination.PIDL); if (destination.IsFileSystem) { if (this._FsWatcher != null) { this._FsWatcher.EnableRaisingEvents = false; this._FsWatcher.Dispose(); try { this._FsWatcher = new FileSystemWatcher(@destination.ParsingName); //this._FsWatcher.InternalBufferSize = 64 * 1024 * 1024; this._FsWatcher.Changed += (sender, args) => { try { var objUpdateItem = FileSystemListItem.ToFileSystemItem(this.LVHandle, args.FullPath); if (objUpdateItem.IsInCurrentFolder(this.CurrentFolder)) { var exisitingUItem = this.Items.ToArray().FirstOrDefault(w => w.Equals(objUpdateItem)); if (exisitingUItem != null) this.RefreshItem(exisitingUItem.ItemIndex, true); if (this.RequestedCurrentLocation != null && objUpdateItem.Equals(this.RequestedCurrentLocation)) this.UnvalidateDirectory(); } } catch (FileNotFoundException) { //Probably a temporary file this._TemporaryFiles.Add(args.FullPath); } catch { } }; this._FsWatcher.Error += (sender, args) => { var ex = args.GetException(); }; this._FsWatcher.Created += (sender, args) => { try { //var existing = this.Items.FirstOrDefault(s => s.ParsingName.Equals(args.FullPath)); //if (existing != null) return; if (Path.GetExtension(args.FullPath).ToLowerInvariant() == ".tmp" || Path.GetExtension(args.FullPath) == String.Empty) { if (!this._TemporaryFiles.Contains(args.FullPath)) this._TemporaryFiles.Add(args.FullPath); } var obj = FileSystemListItem.ToFileSystemItem(this.LVHandle, args.FullPath); if (obj.IsInCurrentFolder(this.CurrentFolder)) { if (this.IsRenameNeeded) { var existingItem = this.Items.ToArray().FirstOrDefault(s => s.Equals(obj)); if (existingItem == null) { var itemIndex = this.InsertNewItem(obj); this.SelectItemByIndex(itemIndex, true, true); this.RenameSelectedItem(itemIndex); this.IsRenameNeeded = false; } else { this.RenameSelectedItem(existingItem.ItemIndex); } } else { if (this._ItemsQueue.Enqueue(new Tuple<ItemUpdateType, IListItemEx>(ItemUpdateType.Created, obj))) this.UnvalidateDirectory(); } } } catch (FileNotFoundException) { this.QueueDeleteItem(args); } catch { } }; this._FsWatcher.Deleted += (sender, args) => this.QueueDeleteItem(args); this._FsWatcher.Renamed += (sender, args) => { }; this._FsWatcher.IncludeSubdirectories = false; this._FsWatcher.NotifyFilter = NotifyFilters.CreationTime | NotifyFilters.DirectoryName | NotifyFilters.Attributes | NotifyFilters.FileName | NotifyFilters.LastWrite | NotifyFilters.Security | NotifyFilters.Size; } catch (ArgumentException) { this._FsWatcher = new FileSystemWatcher(); } } try { if (this._FsWatcher != null && !String.IsNullOrEmpty(this._FsWatcher.Path)) { this._FsWatcher.EnableRaisingEvents = true; } } catch (FileNotFoundException) { } } this.RequestedCurrentLocation = destination; var column = columns ?? this.AllAvailableColumns.Single(s => s.Value.ID == "A0").Value; var order = folderSettings.SortOrder; var content = destination; foreach (var shellItem in destination.IsNetworkPath ? destination.TakeWhile(shellItem => !this.IsCancelRequested) : content.TakeWhile(shellItem => !this.IsCancelRequested)) { CurrentI++; if (!this.RequestedCurrentLocation.Equals(shellItem.Parent) && this.IsNavigationCancelRequested) { this.IsNavigationCancelRequested = false; return; } if (this.ShowHidden || !shellItem.IsHidden) { shellItem.ItemIndex = K++; this.Items.Add(shellItem); if (CurrentI == 1) { this.Invoke((Action)(() => { this._NavWaitTimer.Stop(); this._IsDisplayEmptyText = false; this._IIListView.ResetEmptyText(); })); } } var delta = CurrentI - LastI; if (delta >= 4750) { LastI = CurrentI; this.BeginInvoke((MethodInvoker)(() => this._IIListView.SetItemCount(this.Items.Count, 0x2))); } } this.IsCancelRequested = false; this.IsNavigationInProgress = false; if (this.RequestedCurrentLocation.NavigationStatus != HResult.S_OK) { GC.Collect(); Shell32.SetProcessWorkingSetSize(Process.GetCurrentProcess().Handle, -1, -1); if (this._Threads.Count <= 1) return; _Mre.Set(); this._ResetEvent.Set(); this._Threads[0].Abort(); this._Threads.RemoveAt(0); return; } var headerhandle = User32.SendMessage(this.LVHandle, MSG.LVM_GETHEADER, 0, 0); for (var i = 0; i < this.Collumns.Count; i++) { this.Collumns[i].SetSplitButton(headerhandle, i); } if (this.View != ShellViewStyle.Details) AutosizeAllColumns(-2); //User32.SendMessage(this.LVHandle, MSG.LVM_SETITEMCOUNT, this.Items.Count, 0x2); var sortColIndex = this.Collumns.SingleOrDefault(s => s.ID == columns?.ID)?.Index; if (sortColIndex != null) { this.SetSortIcon(sortColIndex.Value, folderSettings.SortOrder == SortOrder.None ? SortOrder.Ascending : folderSettings.SortOrder); } if (isThereSettings) { if (columns?.ID == "A0" && String.Equals(this.RequestedCurrentLocation.ParsingName, KnownFolders.Computer.ParsingName, StringComparison.InvariantCultureIgnoreCase)) this.SetSortCollumn(true, this.AvailableColumns().Single(s => s.Value.ID == "A180").Value, SortOrder.Ascending, false); else this.SetSortCollumn(true, columns, folderSettings.SortOrder, false); } else if (String.Equals(this.RequestedCurrentLocation.ParsingName, KnownFolders.Computer.ParsingName, StringComparison.InvariantCultureIgnoreCase)) { this.Items = this.Items.OrderBy(o => o.ParsingName).ToList(); var i = 0; this.Items.ForEach(e => e.ItemIndex = i++); User32.SendMessage(this.LVHandle, MSG.LVM_SETITEMCOUNT, this.Items.Count, 0x2); } else { this.Items = this.Items.OrderByDescending(o => o.IsFolder).ThenBy(o => o.DisplayName).ToList(); var i = 0; this.Items.ToList().ForEach(e => e.ItemIndex = i++); User32.SendMessage(this.LVHandle, MSG.LVM_SETITEMCOUNT, this.Items.Count, 0x2); } if (this.IsGroupsEnabled) { var colData = this.AllAvailableColumns.FirstOrDefault(w => w.Value.ID == folderSettings.GroupCollumn).Value; this.GenerateGroupsFromColumn(colData, folderSettings.GroupOrder == SortOrder.Descending); } if (!isThereSettings) { this.LastSortedColumnId = "A0"; this.LastSortOrder = SortOrder.Ascending; this.SetSortIcon(0, SortOrder.Ascending); User32.SendMessage(this.LVHandle, MSG.LVM_SETSELECTEDCOLUMN, 0, 0); } this._IsDisplayEmptyText = false; this.BeginInvoke((Action)(() => { var navArgs = new NavigatedEventArgs(this.RequestedCurrentLocation, this.CurrentFolder, isInSameTab); this.CurrentFolder = this.RequestedCurrentLocation; if (!refresh) Navigated?.Invoke(this, navArgs); })); this.Invoke((Action)(() => { this._NavWaitTimer.Stop(); this._IsDisplayEmptyText = false; this._IIListView.ResetEmptyText(); })); GC.Collect(); Shell32.SetProcessWorkingSetSize(Process.GetCurrentProcess().Handle, -1, -1); this.Invoke((Action)(() => { if (this._SearchTimer.Enabled) this._SearchTimer.Stop(); })); _Mre.Reset(); _Mre.WaitOne(); }); navigationThread.SetApartmentState(ApartmentState.STA); this._Threads.Add(navigationThread); navigationThread.Start(); }