示例#1
0
    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();
    }
示例#2
0
    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();
    }