context: //    This file is part of QTTabBar, a shell extension for Microsoft
  //    Windows Explorer.
  //    Copyright (C) 2007-2010  Quizo, Paul Accisano
  //
  //    QTTabBar is free software: you can redistribute it and/or modify
  //    it under the terms of the GNU General Public License as published by
  //    the Free Software Foundation, either version 3 of the License, or
  //    (at your option) any later version.
  //
  //    QTTabBar is distributed in the hope that it will be useful,
  //    but WITHOUT ANY WARRANTY; without even the implied warranty of
  //    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  //    GNU General Public License for more details.
  //
  //    You should have received a copy of the GNU General Public License
  //    along with QTTabBar.  If not, see <http://www.gnu.org/licenses/>.
  
  using System;
  using System.Collections.Generic;
  using System.ComponentModel;
  using System.Diagnostics;
  using System.Drawing;
  using System.Drawing.Imaging;
  using System.IO;
  using System.Linq;
  using System.Media;
  using System.Reflection;
  using System.Runtime.InteropServices;
  using System.Runtime.Remoting.Messaging;
  using System.Text;
  using System.Threading;
  using System.Windows.Forms;
  using System.Windows.Forms.VisualStyles;
  using BandObjectLib;
  using Microsoft.Win32;
  using QTPlugin;
  using QTTabBarLib.Interop;
  using SHDocVw;
  using Timer = System.Windows.Forms.Timer;
  
  namespace QTTabBarLib {
      [ComVisible(true), Guid("d2bf470e-ed1c-487f-a333-2bd8835eb6ce")]
      public sealed partial class QTTabBarClass : BandObject {
          private int BandHeight;
          private VisualStyleRenderer bgRenderer;
          private BreadcrumbBar breadcrumbBar;
          private ToolStripButton buttonBack;
          private ToolStripButton buttonForward;
          private ToolStripDropDownButton buttonNavHistoryMenu;
          private IContainer components;
          private ContextMenuStripEx contextMenuDropped;
          private QTabItem ContextMenuedTab;
          private ContextMenuStripEx contextMenuSys;
          private ContextMenuStripEx contextMenuTab;
          private string CurrentAddress;
          private QTabItem CurrentTab;
          private int CurrentTravelLogIndex;
          private Cursor curTabCloning;
          private Cursor curTabDrag;
          private Rectangle DraggingDestRect;
          private QTabItem DraggingTab;
          private DropTargetWrapper dropTargetWrapper;
          private NativeWindowController explorerController;
          private IntPtr ExplorerHandle;
          private bool fDrivesContainedDD;
          private static bool fInitialized;
          private readonly bool fIsFirstLoad;
          private volatile bool FirstNavigationCompleted;
          private bool fAutoNavigating;
          private bool fNavigatedByTabSelection;
          private bool fNeedsNewWindowPulse;
          private bool fNowQuitting;
          private bool fNowRestoring;
          private bool fNowTravelByTree;
          private bool fToggleTabMenu;
          private IntPtr hHook_Key;
          private IntPtr hHook_Mouse;
          private IntPtr hHook_Msg;
          private HookProc hookProc_GetMsg;
          private HookProc hookProc_Key;
          private HookProc hookProc_Mouse;
          private ShellContextMenu shellContextMenu = new ShellContextMenu();
          private int iModKeyStateDD;
          private const int INTERVAL_SELCTTAB = 700;
          private const int INTERVAL_SHOWMENU = 0x4b0;
          private int iSequential_WM_CLOSE;
          private bool IsShown;
          private byte[] lastAttemptedBrowseObjectIDL;
          private byte[] lastCompletedBrowseObjectIDL;
          private Dictionary<int, ITravelLogEntry> LogEntryDic = new Dictionary<int, ITravelLogEntry>();
          private AbstractListView listView = new AbstractListView();
          private ListViewMonitor listViewManager;
          private List<QTabItem> lstActivatedTabs = new List<QTabItem>(0x10);
          private List<ToolStripItem> lstPluginMenuItems_Sys;
          private List<ToolStripItem> lstPluginMenuItems_Tab;
          private static FileHashComputerForm md5Form;
          private ToolStripTextBox menuTextBoxTabAlias;
          private int navBtnsFlag;
          private bool NavigatedByCode;
          private bool NowInTravelLog;
          private bool NowModalDialogShown;
          private bool NowOpenedByGroupOpener;
          private bool NowTabCloned;
          private bool NowTabCreated;
          private bool NowTabDragging;
          private bool NowTabsAddingRemoving;
          private bool NowTopMost;
          internal RebarController rebarController;
          private ShellBrowserEx ShellBrowser;
          private string strDraggingDrive;
          private string strDraggingStartPath;
          private SubDirTipForm subDirTip_Tab;
          private QTabControl tabControl1;
          private QTabItem tabForDD;
          private TabSwitchForm tabSwitcher;
          private Timer timerOnTab;
          private Timer timerSelectionChanged;
          private ToolStripClasses toolStrip;
          private ToolTip toolTipForDD;
          private NativeWindowController travelBtnController;
          private ITravelLogStg TravelLog;
          private IntPtr TravelToolBarHandle;
          private TreeViewWrapper treeViewWrapper;
          private ToolStripMenuItem tsmiAddToGroup;
          private ToolStripMenuItem tsmiBrowseFolder;
          private ToolStripMenuItem tsmiCloneThis;
          private ToolStripMenuItem tsmiClose;
          private ToolStripMenuItem tsmiCloseAllButCurrent;
          private ToolStripMenuItem tsmiCloseAllButThis;
          private ToolStripMenuItem tsmiCloseLeft;
          private ToolStripMenuItem tsmiCloseRight;
          private ToolStripMenuItem tsmiCloseWindow;
          private ToolStripMenuItem tsmiCopy;
          private ToolStripMenuItem tsmiCreateGroup;
          private ToolStripMenuItem tsmiCreateWindow;
          private ToolStripMenuItem tsmiExecuted;
          private ToolStripMenuItem tsmiGroups;
          private ToolStripMenuItem tsmiHistory;
          private ToolStripMenuItem tsmiLastActiv;
          private ToolStripMenuItem tsmiLockThis;
          private ToolStripMenuItem tsmiLockToolbar;
          private ToolStripMenuItem tsmiMergeWindows;
          private ToolStripMenuItem tsmiOption;
          private ToolStripMenuItem tsmiProp;
          private ToolStripMenuItem tsmiTabOrder;
          private ToolStripMenuItem tsmiUndoClose;
          private ToolStripSeparator tssep_Sys1;
          private ToolStripSeparator tssep_Sys2;
          private ToolStripSeparator tssep_Tab1;
          private ToolStripSeparator tssep_Tab2;
          private ToolStripSeparator tssep_Tab3;
          private readonly uint WM_NEWTREECONTROL = PInvoke.RegisterWindowMessage("QTTabBar_NewTreeControl");
          private readonly uint WM_BROWSEOBJECT = PInvoke.RegisterWindowMessage("QTTabBar_BrowseObject");
          private readonly uint WM_HEADERINALLVIEWS = PInvoke.RegisterWindowMessage("QTTabBar_HeaderInAllViews");
          private readonly uint WM_LISTREFRESHED = PInvoke.RegisterWindowMessage("QTTabBar_ListRefreshed");
          private readonly uint WM_SHOWHIDEBARS = PInvoke.RegisterWindowMessage("QTTabBar_ShowHideBars");
          private readonly uint WM_CHECKPULSE = PInvoke.RegisterWindowMessage("QTTabBar_CheckPulse");
  
          internal PluginServer pluginServer { get; private set; }
          internal bool CanNavigateBackward { get { return ((navBtnsFlag & 1) != 0); } }
          internal bool CanNavigateForward { get { return ((navBtnsFlag & 2) != 0); } }
          internal int TabCount { get { return tabControl1.TabCount; } }
          internal int SelectedTabIndex {
              get {
                  return tabControl1.TabPages.IndexOf(CurrentTab);
              }
              set {
                  if(0 <= value && value < tabControl1.TabPages.Count) {
                      tabControl1.SelectTab(value);
                  }
              }
          }
              
          public QTTabBarClass() {
              QTUtility.Initialize();
              try {
                  string installDateString;
                  DateTime installDate;
                  string minDate = DateTime.MinValue.ToString();
                  using(RegistryKey key = Registry.LocalMachine.OpenSubKey(RegConst.Root)) {
                      installDateString = key == null ? minDate : (string)key.GetValue("InstallDate", minDate);
                      installDate = DateTime.Parse(installDateString);
                  }
                  using(RegistryKey key = Registry.CurrentUser.CreateSubKey(RegConst.Root)) {
                      DateTime lastActivation = DateTime.Parse((string)key.GetValue("ActivationDate", minDate));
                      fIsFirstLoad = installDate.CompareTo(lastActivation) > 0;
                      if(fIsFirstLoad) key.SetValue("ActivationDate", installDateString);
                  }
              }
              catch {
              }
              if(!fInitialized) {
                  InitializeStaticFields();
              }
              BandHeight = Config.Skin.TabHeight + 2;
              InitializeComponent();
              lstActivatedTabs.Add(CurrentTab);
          }
  
          private void AddInsertTab(QTabItem tab) {
              switch(Config.Tabs.NewTabPosition) {
                  case TabPos.Leftmost:
                      tabControl1.TabPages.Insert(0, tab);
                      break;
  
                  case TabPos.Right:
                  case TabPos.Left: {
                      int index = tabControl1.TabPages.IndexOf(CurrentTab);
                      if(index == -1) {
                          tabControl1.TabPages.Add(tab);
                      }
                      else {
                          tabControl1.TabPages.Insert(Config.Tabs.NewTabPosition == TabPos.Right ? (index + 1) : index, tab);    
                      }
                      break;
                  }
  
                  default: // TabPos.Rightmost
                      tabControl1.TabPages.Add(tab);
                      break;
              }
          }
  
          private void AddStartUpTabs(string openingGRP, string openingPath) {
              if(ModifierKeys == Keys.Shift || InstanceManager.GetTotalInstanceCount() != 0) return;
              foreach(string path in GroupsManager.Groups.Where(g => g.Startup && openingGRP != g.Name).SelectMany(g => g.Paths)) {
                  if(Config.Tabs.NeverOpenSame) {
                      if(path.PathEquals(openingPath)) {
                          tabControl1.TabPages.Relocate(0, tabControl1.TabCount - 1);
                          continue;
                      }
                      if(tabControl1.TabPages.Any(item => path.PathEquals(item.CurrentPath))) {
                          continue;
                      }
                  }
                  using(IDLWrapper wrapper = new IDLWrapper(path)) {
                      if(!wrapper.Available) continue;
                      QTabItem tabPage = new QTabItem(QTUtility2.MakePathDisplayText(path, false), path, tabControl1);
                      tabPage.NavigatedTo(path, wrapper.IDL, -1, false);
                      tabPage.ToolTipText = QTUtility2.MakePathDisplayText(path, true);
                      tabPage.Underline = true;
                      tabControl1.TabPages.Add(tabPage);
                  }
              }
              if(Config.Window.RestoreOnlyLocked) {
                  RestoreTabsOnInitialize(1, openingPath);
              }
              else if(Config.Window.RestoreSession || fIsFirstLoad) {
                  RestoreTabsOnInitialize(0, openingPath);
              }
          }
  
          private static void AddToHistory(QTabItem closingTab) {
              string currentPath = closingTab.CurrentPath;
              if((Config.Misc.KeepHistory && !string.IsNullOrEmpty(currentPath)) && !IsSearchResultFolder(currentPath)) {
                  if(QTUtility2.IsShellPathButNotFileSystem(currentPath) && (currentPath.IndexOf("???") == -1)) {
                      currentPath = currentPath + "???" + closingTab.GetLogHash(true, 0);
                  }
                  StaticReg.ClosedTabHistoryList.Add(currentPath);
                  InstanceManager.ButtonBarBroadcast(bbar => bbar.RefreshButtons(), true);
              }
          }
  
          private void AppendUserApps(IList<string> listDroppedPaths) {
              WindowUtils.BringExplorerToFront(ExplorerHandle);
              if(contextMenuDropped == null) {
                  ToolStripMenuItem tsmiDropped = new ToolStripMenuItem { Tag = 1 };
                  contextMenuDropped = new ContextMenuStripEx(components, false);
                  contextMenuDropped.SuspendLayout();
                  contextMenuDropped.Items.Add(tsmiDropped);
                  contextMenuDropped.Items.Add(new ToolStripMenuItem());
                  contextMenuDropped.ItemClicked += (sender, e) => {
                      if(e.ClickedItem.Tag != null)
                          AppsManager.CreateNewApp((List<string>)contextMenuDropped.Tag);
                  };
                  contextMenuDropped.ResumeLayout(false);
              }
  
              string strMenu = QTUtility.ResMain[21];
              strMenu += listDroppedPaths.Count > 1
                      ? listDroppedPaths.Count + QTUtility.ResMain[22] // "items"
                      : Path.GetFileName(listDroppedPaths[0]).Enquote();
  
              contextMenuDropped.SuspendLayout();
              contextMenuDropped.Items[0].Text = strMenu;
              contextMenuDropped.Items[1].Text = QTUtility.ResMain[23];			// Cancel
              contextMenuDropped.Tag = listDroppedPaths;
              contextMenuDropped.ResumeLayout();
              contextMenuDropped.Show(MousePosition);
          }
  
          // TODO: Kill this.
          private void AsyncComplete_FolderTree(IAsyncResult ar) {
              AsyncResult result = (AsyncResult)ar;
              ((WaitTimeoutCallback)result.AsyncDelegate).EndInvoke(ar);
              if(IsHandleCreated) {
                  Invoke(new FormMethodInvoker(CallbackFolderTree), new object[] { result.AsyncState });
              }
          }
  
          // This function is used as a more available version of BeforeNavigate2.
          // Return true to suppress the navigation.  Target IDL should not be relied
          // upon; it's not guaranteed to be accurate.
          private bool BeforeNavigate(IDLWrapper target, bool autonav) {
              if(!IsShown) return false;
              HideSubDirTip_Tab_Menu();
              NowTabDragging = false;
              fAutoNavigating = autonav;
              if(!NavigatedByCode) {
                  SaveSelectedItems(CurrentTab);
              }
              if(NowInTravelLog) {
                  if(CurrentTravelLogIndex > 0) {
                      CurrentTravelLogIndex--;
                      if(!IsSpecialFolderNeedsToTravel(target.Path)) {
                          NavigateBackToTheFuture();
                      }
                  }
                  else {
                      NowInTravelLog = false;
                  }
              }
              lastAttemptedBrowseObjectIDL = target.IDL;
              return false;
          }
  
          private void CallbackFolderTree(object obj) {
              bool fShow = (bool)obj;
              ShowFolderTree(fShow);
              if(fShow) {
                  PInvoke.SetRedraw(ExplorerHandle, true);
                  PInvoke.RedrawWindow(ExplorerHandle, IntPtr.Zero, IntPtr.Zero, 0x289);
              }
          }
  
          private IntPtr CallbackGetMsgProc(int nCode, IntPtr wParam, IntPtr lParam) {
              if(nCode >= 0) {
                  MSG msg = (MSG)Marshal.PtrToStructure(lParam, typeof(MSG));
                  try {
                      if(QTUtility.IsXP) {
                          if(msg.message == WM.CLOSE) {
                              if(iSequential_WM_CLOSE > 0) {
                                  Marshal.StructureToPtr(new MSG(), lParam, false);
                                  return PInvoke.CallNextHookEx(hHook_Msg, nCode, wParam, lParam);
                              }
                              iSequential_WM_CLOSE++;
                          }
                          else {
                              iSequential_WM_CLOSE = 0;
                          }
                      }
  
                      if(msg.message == WM_NEWTREECONTROL) {
                          object obj = Marshal.GetObjectForIUnknown(msg.wParam);
                          try {
                              if(obj != null) {
                                  IOleWindow window = obj as IOleWindow;
                                  if(window != null) {
                                      IntPtr hwnd;
                                      window.GetWindow(out hwnd);
                                      if(hwnd != IntPtr.Zero && PInvoke.IsChild(ExplorerHandle, hwnd)) {
                                          hwnd = WindowUtils.FindChildWindow(hwnd,
                                                  child => PInvoke.GetClassName(child) == "SysTreeView32");
                                          if(hwnd != IntPtr.Zero) {
                                              INameSpaceTreeControl control = obj as INameSpaceTreeControl;
                                              if(control != null) {
                                                  if(treeViewWrapper != null) {
                                                      treeViewWrapper.Dispose();
                                                  }
                                                  treeViewWrapper = new TreeViewWrapper(hwnd, control);
                                                  treeViewWrapper.TreeViewClicked += FolderLinkClicked;
                                                  obj = null; // Release the object only if we didn't get this far.
                                              }
                                          }
                                      }
                                  }
                              }
                          }
                          finally {
                              if(obj != null) {
                                  Marshal.ReleaseComObject(obj);
                              }
                          }
                          return PInvoke.CallNextHookEx(hHook_Msg, nCode, wParam, lParam);   
                      }
                      else if(msg.message == WM_LISTREFRESHED) {
                          HandleF5();
                          return PInvoke.CallNextHookEx(hHook_Msg, nCode, wParam, lParam);   
                      }
  
                      switch(msg.message) {
                          /* TODO: Handle FolderView clicks on XP.
                          case WM.LBUTTONDOWN:
                          case WM.LBUTTONUP:
                              if((QTUtility.IsXP && !Config.NoMidClickTree) && ((((int)((long)msg.wParam)) & 4) != 0)) {
                                  HandleLBUTTON_Tree(msg, msg.message == 0x201);
                              }
                              break;
  
                          case WM.MBUTTONUP:
                              if(QTUtility.IsXP && !Explorer.Busy && !Config.NoMidClickTree) {
                                  Handle_MButtonUp_Tree(msg);
                              }
                              break;
                          */
  
                          case WM.CLOSE:
                              if(QTUtility.IsXP) {
                                  if((msg.hwnd == ExplorerHandle) && HandleCLOSE(msg.lParam)) {
                                      Marshal.StructureToPtr(new MSG(), lParam, false);
                                  }
                                  break;
                              }
                              if(msg.hwnd == WindowUtils.GetShellTabWindowClass(ExplorerHandle)) {
                                  try {
                                      bool flag = tabControl1.TabCount == 1;
                                      string currentPath = tabControl1.SelectedTab.CurrentPath;
                                      if(!Directory.Exists(currentPath) && currentPath.Length > 3 /* && currentPath.Substring(1, 2) == @":\" */ ) {
                                          if(flag) {
                                              WindowUtils.CloseExplorer(ExplorerHandle, 2);
                                          }
                                          else {
                                              CloseTab(tabControl1.SelectedTab, true);
                                          }
                                      }
                                  }
                                  catch {
                                  }
                                  Marshal.StructureToPtr(new MSG(), lParam, false);
                              }
                              break;
  
                          case WM.COMMAND:
                              if(QTUtility.IsXP) {
                                  int num = ((int)((long)msg.wParam)) & 0xffff;
                                  if(num == 0xa021) {
                                      WindowUtils.CloseExplorer(ExplorerHandle, 3);
                                      Marshal.StructureToPtr(new MSG(), lParam, false);
                                  }
                              }
                              break;
                      }
                  }
                  catch(Exception ex) {
                      QTUtility2.MakeErrorLog(ex, String.Format("Message: {0:x4}", msg.message));
                  }
              }
              return PInvoke.CallNextHookEx(hHook_Msg, nCode, wParam, lParam);
          }
  
          private IntPtr CallbackKeyboardProc(int nCode, IntPtr wParam, IntPtr lParam) {
              const uint KB_TRANSITION_FLAG = 0x80000000;
              const uint KB_PREVIOUS_STATE_FLAG = 0x40000000;
              if(nCode < 0 || NowModalDialogShown) {
                  return PInvoke.CallNextHookEx(hHook_Key, nCode, wParam, lParam);
              }
  
              try {
                  uint flags = (uint)((long)lParam);
                  bool isKeyPress = (flags & KB_TRANSITION_FLAG) == 0;
                  bool isRepeat = (flags & KB_PREVIOUS_STATE_FLAG) != 0;
                  Keys key = (Keys)((int)wParam);
  
                  if(key == Keys.ShiftKey) {
                      if(isKeyPress || !isRepeat) {
                          listView.HandleShiftKey();
                      }
                  }
  
                  if(isKeyPress) {
                      if(HandleKEYDOWN(key, isRepeat)) {
                          return new IntPtr(1);
                      }
                  }
                  else {
                      listView.HideThumbnailTooltip(3);
                      if(NowTabDragging && DraggingTab != null) {
                          Cursor = Cursors.Default;
                      }
  
                      switch(key) {
                          case Keys.ControlKey:
                              if(Config.Keys.UseTabSwitcher) {
                                  HideTabSwitcher(true);
                              }
                              break;
  
                          case Keys.Menu: // Alt key
                              if(Config.Tabs.ShowCloseButtons && Config.Tabs.CloseBtnsWithAlt) {
                                  tabControl1.ShowCloseButton(false);
                              }
                              break;
  
                          case Keys.Tab:
                              if(Config.Keys.UseTabSwitcher && tabSwitcher != null && tabSwitcher.IsShown) {
                                  tabControl1.SetPseudoHotIndex(tabSwitcher.SelectedIndex);
                              }
                              break;
                      }
                  }
              }
              catch(Exception ex) {
                  QTUtility2.MakeErrorLog(ex,
                          String.Format("LParam: {0:x4}, WParam: {1:x4}", (long)lParam, (long)wParam));
              }
              return PInvoke.CallNextHookEx(hHook_Key, nCode, wParam, lParam);
          }
  
          private IntPtr CallbackMouseProc(int nCode, IntPtr wParam, IntPtr lParam) {
              try {
                  if(nCode >= 0 && !NowModalDialogShown) {
                      IntPtr ptr = (IntPtr)1;
                      switch(((int)wParam)) {
                          case WM.MOUSEWHEEL:
                              if(!HandleMOUSEWHEEL(lParam)) {
                                  break;
                              }
                              return ptr;
  
                          case WM.XBUTTONDOWN:
                          case WM.XBUTTONUP:
                              MouseButtons mouseButtons = MouseButtons;
                              Keys modifierKeys = ModifierKeys;
                              MouseChord chord = mouseButtons == MouseButtons.XButton1
                                      ? MouseChord.X1
                                      : mouseButtons == MouseButtons.XButton2 ? MouseChord.X2 : MouseChord.None;
                              if(chord == MouseChord.None) break;
                              chord = QTUtility.MakeMouseChord(chord, modifierKeys);
                              BindAction action;
                              if(!Config.Mouse.GlobalMouseActions.TryGetValue(chord, out action)) {
                                  break;
                              }
                              if(((int)wParam) == WM.XBUTTONUP && !Explorer.Busy) {
                                  DoBindAction(action);
                              }
                              return ptr;
                      }
                  }
              }
              catch(Exception ex) {
                  QTUtility2.MakeErrorLog(ex, String.Format("LParam: {0:x4}, WParam: {1:x4}", (long)lParam, (long)wParam));
              }
              return PInvoke.CallNextHookEx(hHook_Mouse, nCode, wParam, lParam);
          }
  
          private void CallbackMultiPath(object obj) {
              object[] objArray = (object[])obj;
              string[] collection = (string[])objArray[0];
              int num = (int)objArray[1];
              switch(num) {
                  case 0:
                      foreach(string str in collection) {
                          OpenNewTab(str, true);
                      }
                      break;
  
                  case 1: {
                          bool flag = true;
                          foreach(string str2 in collection) {
                              OpenNewTab(str2, !flag);
                              flag = false;
                          }
                          break;
                      }
                  default:
                      StaticReg.CreateWindowPaths.Assign(collection);
                      using(IDLWrapper wrapper = new IDLWrapper(collection[0])) {
                          OpenNewWindow(wrapper);
                      }
                      break;
              }
              if(num == 1) {
                  InstanceManager.RemoveFromTrayIcon(Handle);
                  WindowUtils.BringExplorerToFront(ExplorerHandle);
              }
          }
  
          private void CancelFailedNavigation(string failedPath, bool fRollBackForward, int countRollback) {
              ShowMessageNavCanceled(failedPath, false);
              if(fRollBackForward) {
                  for(int i = 0; i < countRollback; i++) {
                      CurrentTab.GoForward();
                  }
              }
              else {
                  for(int j = 0; j < countRollback; j++) {
                      CurrentTab.GoBackward();
                  }
              }
              NavigatedByCode = false;
          }
  
          private void CancelFailedTabChanging(string newPath) {
              if(!CloseTab(tabControl1.SelectedTab, true)) {
                  if(tabControl1.TabCount == 1) {
                      WindowUtils.CloseExplorer(ExplorerHandle, 2);
                  }
                  else {
                      ShowMessageNavCanceled(newPath, false);
                      if(CurrentTab == null) {
                          tabControl1.SelectedIndex = 0;
                      }
                  }
              }
              else {
                  StaticReg.ClosedTabHistoryList.Remove(newPath);
                  if(tabControl1.TabCount == 0) {
                      ShowMessageNavCanceled(newPath, true);
                      WindowUtils.CloseExplorer(ExplorerHandle, 2);
                  }
                  else {
                      if(CurrentTab == null) {
                          tabControl1.SelectedIndex = 0;
                      }
                      else {
                          tabControl1.SelectTab(CurrentTab);
                      }
                      ShowMessageNavCanceled(newPath, false);
                  }
              }
          }
  
          private void ChangeViewMode(bool fUp) {
              FVM orig = ShellBrowser.ViewMode;
              FVM mode = orig;
              switch(mode) {
                  case FVM.ICON:
                      mode = fUp ? FVM.TILE : FVM.LIST;
                      break;
  
                  case FVM.LIST:
                      mode = fUp ? FVM.ICON : FVM.DETAILS;
                      break;
  
                  case FVM.DETAILS:
                      if(fUp) {
                          mode = FVM.LIST;
                      }
                      break;
  
                  case FVM.THUMBNAIL:
                      mode = fUp ? FVM.THUMBSTRIP : FVM.TILE;
                      break;
  
                  case FVM.TILE:
                      mode = fUp ? FVM.THUMBNAIL : FVM.ICON;
                      break;
  
                  case FVM.THUMBSTRIP:
                      if(!fUp) {
                          mode = FVM.THUMBNAIL;
                      }
                      break;
              }
              if(mode != orig) {
                  ShellBrowser.ViewMode = mode;
              }
          }
  
          private static bool CheckProcessID(IntPtr hwnd1, IntPtr hwnd2) {
              uint num;
              uint num2;
              PInvoke.GetWindowThreadProcessId(hwnd1, out num);
              PInvoke.GetWindowThreadProcessId(hwnd2, out num2);
              return ((num == num2) && (num != 0));
          }
  
          private void ChooseNewDirectory() {
              NowModalDialogShown = true;
              bool nowTopMost = NowTopMost;
              if(nowTopMost) {
                  ToggleTopMost();
              }
              using(FolderBrowserDialog dialog = new FolderBrowserDialog()) {
                  dialog.SelectedPath = CurrentAddress;
                  if(DialogResult.OK == dialog.ShowDialog()) {
                      OpenNewTab(dialog.SelectedPath);
                  }
              }
              NowModalDialogShown = false;
              if(nowTopMost) {
                  ToggleTopMost();
              }
          }
  
          private void ClearTravelLogs() {
              IEnumTravelLogEntry ppenum = null;
              try {
                  if((TravelLog.EnumEntries(0x30, out ppenum) != 0) || (ppenum == null)) {
                      return;
                  }
                  int num = 0;
              Label_0018:
                  ITravelLogEntry entry2 = null;
                  try {
                      if(ppenum.Next(1, out entry2, 0) == 0) {
                          IntPtr ptr;
                          if((num++ != 0) && (entry2.GetURL(out ptr) == 0)) {
                              string path = Marshal.PtrToStringUni(ptr);
                              PInvoke.CoTaskMemFree(ptr);
                              if(!IsSpecialFolderNeedsToTravel(path)) {
                                  TravelLog.RemoveEntry(entry2);
                              }
                          }
                          goto Label_0018;
                      }
                  }
                  finally {
                      if(entry2 != null) {
                          Marshal.ReleaseComObject(entry2);
                      }
                  }
              }
              catch(Exception exception) {
                  QTUtility2.MakeErrorLog(exception);
              }
              finally {
                  if(ppenum != null) {
                      Marshal.ReleaseComObject(ppenum);
                  }
              }
          }
  
          internal void CloneCurrentTab(bool fSelect = true) {
              CloneTabButton(CurrentTab, null, fSelect, -1);
          }
  
          private void CloneTabButton(QTabItem tab, LogData log) {
              NowTabCloned = true;
              QTabItem item = tab.Clone();
              AddInsertTab(item);
              using(IDLWrapper wrapper = new IDLWrapper(log.IDL)) {
                  if(wrapper.Available) {
                      item.NavigatedTo(wrapper.Path, wrapper.IDL, log.Hash, false);
                  }
              }
              tabControl1.SelectTab(item);
          }
  
          private QTabItem CloneTabButton(QTabItem tab, string optionURL, bool fSelect, int index) {
              NowTabCloned = fSelect;
              QTabItem item = tab.Clone();
              if(index < 0) {
                  AddInsertTab(item);
              }
              else if((-1 < index) && (index < (tabControl1.TabCount + 1))) {
                  tabControl1.TabPages.Insert(index, item);
              }
              else {
                  AddInsertTab(item);
              }
              if(optionURL != null) {
                  using(IDLWrapper wrapper = new IDLWrapper(optionURL)) {
                      item.NavigatedTo(optionURL, wrapper.IDL, -1, false);
                  }
              }
              if(fSelect) {
                  tabControl1.SelectTab(item);
              }
              else {
                  item.RefreshRectangle();
                  tabControl1.Refresh();
              }
              return item;
          }
  
          private List<string> CloseAllTabsExcept(QTabItem leaveThisOne, bool leaveLocked = true) {
              List<QTabItem> tabs = tabControl1.TabPages.Where(item => 
                  !(leaveLocked && item.TabLocked) && item != leaveThisOne).ToList();
              List<string> paths = tabs.Select(tab => tab.CurrentPath).ToList();
              CloseTabs(tabs, !leaveLocked);
              return paths;
          }
  
          public override void CloseDW(uint dwReserved) {
              try {
                  if(treeViewWrapper != null) {
                      treeViewWrapper.Dispose();
                      treeViewWrapper = null;
                  }
                  if(listViewManager != null) {
                      listViewManager.Dispose();
                      listViewManager = null;
                  }
                  if(subDirTip_Tab != null) {
                      subDirTip_Tab.Dispose();
                      subDirTip_Tab = null;
                  }
                  if(IsShown) {
                      if(pluginServer != null) {
                          pluginServer.Dispose();
                          pluginServer = null;
                      }
                      if(hHook_Key != IntPtr.Zero) {
                          PInvoke.UnhookWindowsHookEx(hHook_Key);
                          hHook_Key = IntPtr.Zero;
                      }
                      if(hHook_Mouse != IntPtr.Zero) {
                          PInvoke.UnhookWindowsHookEx(hHook_Mouse);
                          hHook_Mouse = IntPtr.Zero;
                      }
                      if(hHook_Msg != IntPtr.Zero) {
                          PInvoke.UnhookWindowsHookEx(hHook_Msg);
                          hHook_Msg = IntPtr.Zero;
                      }
                      if(explorerController != null) {
                          explorerController.ReleaseHandle();
                          explorerController = null;
                      }
                      if(rebarController != null) {
                          rebarController.Dispose();
                          rebarController = null;
                      }
                      if(!QTUtility.IsXP && (travelBtnController != null)) {
                          travelBtnController.ReleaseHandle();
                          travelBtnController = null;
                      }
                      InstanceManager.RemoveFromTrayIcon(Handle);
                      
                      // TODO: check this
                      using(RegistryKey key = Registry.CurrentUser.CreateSubKey(RegConst.Root)) {
                          if(Config.Misc.KeepHistory) {
                              foreach(QTabItem item in tabControl1.TabPages) {
                                  AddToHistory(item);
                              }
                              QTUtility.SaveRecentlyClosed(key);
                          }
                          if(Config.Misc.KeepRecentFiles) {
                              QTUtility.SaveRecentFiles(key);
                          }
                          string[] list = (from QTabItem item2 in tabControl1.TabPages
                                  where item2.TabLocked
                                  select item2.CurrentPath).ToArray();
                          QTUtility2.WriteRegBinary(list, "TabsLocked", key);
                          InstanceManager.UnregisterTabBar();
                          if(0x80000 != ((int)PInvoke.Ptr_OP_AND(PInvoke.GetWindowLongPtr(ExplorerHandle, -20), 0x80000))) {
                              QTUtility.WindowAlpha = 0xff;
                          }
                          else {
                              byte num;
                              int num2;
                              int num3;
                              if(PInvoke.GetLayeredWindowAttributes(ExplorerHandle, out num2, out num, out num3)) {
                                  QTUtility.WindowAlpha = num;
                              }
                              else {
                                  QTUtility.WindowAlpha = 0xff;
                              }
                          }
                          key.SetValue("WindowAlpha", QTUtility.WindowAlpha);
                          IDLWrapper.SaveCache(key);
                      }
                      if((md5Form != null) && !md5Form.InvokeRequired) {
                          md5Form.SaveMD5FormStat();
                          md5Form.Dispose();
                          md5Form = null;
                      }
                      Cursor = Cursors.Default;
                      if((curTabDrag != null) && (curTabDrag != Cursors.Default)) {
                          PInvoke.DestroyIcon(curTabDrag.Handle);
                          GC.SuppressFinalize(curTabDrag);
                          curTabDrag = null;
                      }
                      if((curTabCloning != null) && (curTabCloning != Cursors.Default)) {
                          PInvoke.DestroyIcon(curTabCloning.Handle);
                          GC.SuppressFinalize(curTabCloning);
                          curTabCloning = null;
                      }
                      if(dropTargetWrapper != null) {
                          dropTargetWrapper.Dispose();
                          dropTargetWrapper = null;
                      }
                      OptionsDialog.ForceClose();
                      if(tabSwitcher != null) {
                          tabSwitcher.Dispose();
                          tabSwitcher = null;
                      }
                  }
                  if(TravelLog != null) {
                      Marshal.FinalReleaseComObject(TravelLog);
                      TravelLog = null;
                  }
                  if(shellContextMenu != null) {
                      shellContextMenu.Dispose();
                      shellContextMenu = null;
                  }
                  if(ShellBrowser != null) {
                      ShellBrowser.Dispose();
                      ShellBrowser = null;
                  }
                  foreach(ITravelLogEntry entry in LogEntryDic.Values) {
                      if(entry != null) {
                          Marshal.FinalReleaseComObject(entry);
                      }
                  }
                  LogEntryDic.Clear();
                  fFinalRelease = true;
                  base.CloseDW(dwReserved);
              }
              catch(Exception exception2) {
                  QTUtility2.MakeErrorLog(exception2, "tabbar closing");
              }
          }
  
          private void CloseLeftRight(bool fLeft, int index) {
              if(index == -1) {
                  index = tabControl1.SelectedIndex;
              }
              if(fLeft ? (index <= 0) : (index >= (tabControl1.TabCount - 1))) return;
              CloseTabs(fLeft
                      ? tabControl1.TabPages.Take(index).ToList()
                      : tabControl1.TabPages.Skip(index + 1).ToList());
          }
          
          // TODO: Optional params
          private bool CloseTab(QTabItem closingTab) {
              return ((tabControl1.TabCount > 1) && CloseTab(closingTab, false));
          }
  
          private bool CloseTab(QTabItem closingTab, bool fCritical, bool fSkipSync = false) {
              if(closingTab == null) {
                  return false;
              }
              if((!fCritical && closingTab.TabLocked) && QTUtility2.PathExists(closingTab.CurrentPath)) {
                  return false;
              }
              int index = tabControl1.TabPages.IndexOf(closingTab);
              if(index == -1) {
                  return false;
              }
              lstActivatedTabs.Remove(closingTab);
              AddToHistory(closingTab);
              tabControl1.TabPages.Remove(closingTab);
              closingTab.OnClose();
              if(closingTab != CurrentTab) {
                  if(!fSkipSync) {
                      TryCallButtonBar(bbar => bbar.RefreshButtons());
                      QTabItem.CheckSubTexts(tabControl1);
                  }
                  return true;
              }
              CurrentTab = null;
              int tabCount = tabControl1.TabCount;
              if(tabCount == 0) return true;
              QTabItem tabPage = null;
              switch(Config.Tabs.NextAfterClosed) {
                  case TabPos.Right:
                      tabPage = tabControl1.TabPages[index == tabCount ? index - 1: index];
                      break;
  
                  case TabPos.Left:
                      tabPage = tabControl1.TabPages[index == 0 ? 0 : index - 1];
                      break;
  
                  case TabPos.Rightmost:
                      tabPage = tabControl1.TabPages[tabCount - 1];
                      break;
  
                  case TabPos.Leftmost:
                      tabPage = tabControl1.TabPages[0];
                      break;
  
                  case TabPos.LastActive:
                      if(lstActivatedTabs.Count > 0) {
                          QTabItem lastTab = lstActivatedTabs[lstActivatedTabs.Count - 1];
                          lstActivatedTabs.RemoveAt(lstActivatedTabs.Count - 1);
                          tabPage = tabControl1.TabPages.Contains(lastTab)
                                  ? lastTab
                                  : tabControl1.TabPages[0];
                      }
                      else {
                          tabPage = tabControl1.TabPages[0];
                      }
                      break;
              }
              if(tabPage != null) {
                  tabControl1.SelectTab(tabPage);
              }
              else {
                  tabControl1.SelectTab(0);
              }
              if(!fSkipSync) {
                  TryCallButtonBar(bbar => bbar.RefreshButtons());
              }
              return true;
          }
  
          private void CloseTabs(IEnumerable<QTabItem> tabs, bool fCritical = false) {
              tabControl1.SetRedraw(false);
              bool closeCurrent = false;
              foreach(QTabItem tab in tabs) {
                  if(tab == CurrentTab)
                      closeCurrent = true;
                  else
                      CloseTab(tab, fCritical, true);
              }
              if(closeCurrent) {
                  CloseTab(CurrentTab, fCritical);
              }
              else {
                  TryCallButtonBar(bbar => bbar.RefreshButtons());
                  QTabItem.CheckSubTexts(tabControl1);
              }
              if(tabControl1.TabCount > 0) {
                  tabControl1.SetRedraw(true);
              }
          }
  
          private void contextMenuSys_ItemClicked(object sender, ToolStripItemClickedEventArgs e) {
              if(e.ClickedItem == tsmiOption) {
                  OptionsDialog.Open();
              }
              else if(e.ClickedItem == tsmiCloseAllButCurrent) {
                  if(tabControl1.TabCount != 1) {
                      CloseAllTabsExcept(CurrentTab);
                  }
              }
              else if(e.ClickedItem == tsmiBrowseFolder) {
                  ChooseNewDirectory();
              }
              else if(e.ClickedItem == tsmiCloseWindow) {
                  WindowUtils.CloseExplorer(ExplorerHandle, 1);
              }
              else {
                  if(e.ClickedItem == tsmiLastActiv) {
                      try {
                          tabControl1.SelectTab(lstActivatedTabs[lstActivatedTabs.Count - 2]);
                          return;
                      }
                      catch {
                          return;
                      }
                  }
                  if(e.ClickedItem == tsmiLockToolbar) {
                      rebarController.Locked = !tsmiLockToolbar.Checked;
                  }
                  else if(e.ClickedItem == tsmiMergeWindows) {
                      MergeAllWindows();
                  }
              }
          }
  
          private void contextMenuSys_Opening(object sender, CancelEventArgs e) {
              InitializeSysMenu(false);
              contextMenuSys.SuspendLayout();
              tsmiGroups.DropDown.SuspendLayout();
              tsmiUndoClose.DropDown.SuspendLayout();
              MenuUtility.CreateGroupItems(tsmiGroups);
              MenuUtility.CreateUndoClosedItems(tsmiUndoClose);
              if((lstActivatedTabs.Count > 1) && tabControl1.TabPages.Contains(lstActivatedTabs[lstActivatedTabs.Count - 2])) {
                  tsmiLastActiv.ToolTipText = lstActivatedTabs[lstActivatedTabs.Count - 2].CurrentPath;
                  tsmiLastActiv.Enabled = true;
              }
              else {
                  tsmiLastActiv.ToolTipText = string.Empty;
                  tsmiLastActiv.Enabled = false;
              }
              while(tsmiExecuted.DropDownItems.Count > 0) {
                  tsmiExecuted.DropDownItems[0].Dispose();
              }
              List<ToolStripItem> list = MenuUtility.CreateRecentFilesItems();
              if(list.Count > 0) {
                  tsmiExecuted.DropDown.SuspendLayout();
                  tsmiExecuted.DropDownItems.AddRange(list.ToArray());
                  tsmiExecuted.DropDown.ResumeLayout();
              }
              tsmiExecuted.Enabled = tsmiExecuted.DropDownItems.Count > 0;
              tsmiMergeWindows.Enabled = InstanceManager.GetTotalInstanceCount() > 1;
              tsmiLockToolbar.Checked = rebarController.Locked;
              if((lstPluginMenuItems_Sys != null) && (lstPluginMenuItems_Sys.Count > 0)) {
                  foreach(ToolStripItem item in lstPluginMenuItems_Sys) {
                      item.Dispose();
                  }
                  lstPluginMenuItems_Sys = null;
              }
              if((pluginServer != null) && (pluginServer.dicFullNamesMenuRegistered_Sys.Count > 0)) {
                  lstPluginMenuItems_Sys = new List<ToolStripItem>();
                  int index = contextMenuSys.Items.IndexOf(tsmiOption);
                  ToolStripSeparator separator = new ToolStripSeparator();
                  contextMenuSys.Items.Insert(index, separator);
                  foreach(string str in pluginServer.dicFullNamesMenuRegistered_Sys.Keys) {
                      ToolStripMenuItem item2 = new ToolStripMenuItem(pluginServer.dicFullNamesMenuRegistered_Sys[str]);
                      item2.Name = str;
                      item2.Tag = MenuType.Bar;
                      item2.Click += pluginitems_Click;
                      contextMenuSys.Items.Insert(index, item2);
                      lstPluginMenuItems_Sys.Add(item2);
                  }
                  lstPluginMenuItems_Sys.Add(separator);
              }
              tsmiUndoClose.DropDown.ResumeLayout();
              tsmiGroups.DropDown.ResumeLayout();
              contextMenuSys.ResumeLayout();
          }
  
          private void contextMenuTab_Closed(object sender, ToolStripDropDownClosedEventArgs e) {
              tabControl1.SetContextMenuState(false);
              if(ContextMenuedTab != CurrentTab) {
                  tabControl1.Refresh();
              }
          }
  
          private void contextMenuTab_ItemClicked(object sender, ToolStripItemClickedEventArgs e) {
              if(ContextMenuedTab != null) {
                  if(e.ClickedItem == tsmiClose) {
                      if(tabControl1.TabCount == 1) {
                          WindowUtils.CloseExplorer(ExplorerHandle, 1);
                      }
                      else {
                          CloseTab(ContextMenuedTab);
                      }
                  }
                  else if(e.ClickedItem == tsmiCloseAllButThis) {
                      CloseAllTabsExcept(ContextMenuedTab);
                  }
                  else if(e.ClickedItem == tsmiCloseLeft) {
                      int index = tabControl1.TabPages.IndexOf(ContextMenuedTab);
                      if(index > 0) {
                          CloseLeftRight(true, index);
                      }
                  }
                  else if(e.ClickedItem == tsmiCloseRight) {
                      int num2 = tabControl1.TabPages.IndexOf(ContextMenuedTab);
                      if(num2 >= 0) {
                          CloseLeftRight(false, num2);
                      }
                  }
                  else if(e.ClickedItem == tsmiCreateGroup) {
                      CreateGroup(ContextMenuedTab);
                  }
                  else if(e.ClickedItem == tsmiLockThis) {
                      ContextMenuedTab.TabLocked = !ContextMenuedTab.TabLocked;
                  }
                  else if(e.ClickedItem == tsmiCloneThis) {
                      CloneTabButton(ContextMenuedTab, null, true, -1);
                  }
                  else if(e.ClickedItem == tsmiCreateWindow) {
                      using(IDLWrapper wrapper = new IDLWrapper(ContextMenuedTab.CurrentIDL)) {
                          OpenNewWindow(wrapper);
                      }
                      if(/*!Config.KeepOnSeparate != */ ((ModifierKeys & Keys.Shift) != Keys.None)) {
                          CloseTab(ContextMenuedTab);
                      }
                  }
                  else if(e.ClickedItem == tsmiCopy) {
                      string currentPath = ContextMenuedTab.CurrentPath;
                      if(currentPath.IndexOf("???") != -1) {
                          currentPath = currentPath.Substring(0, currentPath.IndexOf("???"));
                      }
                      else if(currentPath.IndexOf("*?*?*") != -1) {
                          currentPath = currentPath.Substring(0, currentPath.IndexOf("*?*?*"));
                      }
                      QTUtility2.SetStringClipboard(currentPath);
                  }
                  else if(e.ClickedItem == tsmiProp) {
                      ShellMethods.ShowProperties(ContextMenuedTab.CurrentIDL);
                  }
              }
          }
  
          private void contextMenuTab_Opening(object sender, CancelEventArgs e) {
              InitializeTabMenu(false);
              int index = tabControl1.TabPages.IndexOf(ContextMenuedTab);
              if((index == -1) || (ContextMenuedTab == null)) {
                  e.Cancel = true;
              }
              else {
                  tabControl1.SetContextMenuState(true);
                  contextMenuTab.SuspendLayout();
                  if(tabControl1.TabCount == 1) {
                      tsmiTabOrder.Enabled = tsmiCloseAllButThis.Enabled = tsmiCloseLeft.Enabled = tsmiCloseRight.Enabled = false;
                  }
                  else {
                      if(index == 0) {
                          tsmiCloseLeft.Enabled = false;
                          tsmiCloseRight.Enabled = true;
                      }
                      else if(index == (tabControl1.TabCount - 1)) {
                          tsmiCloseLeft.Enabled = true;
                          tsmiCloseRight.Enabled = false;
                      }
                      else {
                          tsmiCloseLeft.Enabled = tsmiCloseRight.Enabled = true;
                      }
                      tsmiTabOrder.Enabled = tsmiCloseAllButThis.Enabled = true;
                  }
                  tsmiClose.Enabled = !ContextMenuedTab.TabLocked;
                  tsmiLockThis.Text = ContextMenuedTab.TabLocked ? QTUtility.ResMain[20] : QTUtility.ResMain[6];
                  if(GroupsManager.GroupCount > 0) {
                      tsmiAddToGroup.DropDown.SuspendLayout();
                      tsmiAddToGroup.Enabled = true;
                      while(tsmiAddToGroup.DropDownItems.Count > 0) {
                          tsmiAddToGroup.DropDownItems[0].Dispose();
                      }
                      foreach(Group g in GroupsManager.Groups.Where(g => g.Paths.Count > 0)) {
                          tsmiAddToGroup.DropDownItems.Add(new ToolStripMenuItem(g.Name) {
                              ImageKey = QTUtility.GetImageKey(g.Paths[0], null)
                          });
                      }
                      tsmiAddToGroup.DropDown.ResumeLayout();
                  }
                  else {
                      tsmiAddToGroup.Enabled = false;
                  }
                  tsmiHistory.DropDown.SuspendLayout();
                  while(tsmiHistory.DropDownItems.Count > 0) {
                      tsmiHistory.DropDownItems[0].Dispose();
                  }
                  if((ContextMenuedTab.HistoryCount_Back + ContextMenuedTab.HistoryCount_Forward) > 1) {
                      tsmiHistory.DropDownItems.AddRange(CreateNavBtnMenuItems(false).ToArray());
                      tsmiHistory.DropDownItems.AddRange(CreateBranchMenu(false, components, tsmiBranchRoot_DropDownItemClicked).ToArray());
                      tsmiHistory.Enabled = true;
                  }
                  else {
                      tsmiHistory.Enabled = false;
                  }
                  tsmiHistory.DropDown.ResumeLayout();
                  contextMenuTab.Items.Remove(menuTextBoxTabAlias);
                  if(!Config.Tabs.RenameAmbTabs) {
                      contextMenuTab.Items.Insert(12, menuTextBoxTabAlias);
                      if(ContextMenuedTab.Comment.Length > 0) {
                          menuTextBoxTabAlias.Text = ContextMenuedTab.Comment;
                          menuTextBoxTabAlias.ForeColor = SystemColors.WindowText;
                      }
                      else {
                          menuTextBoxTabAlias.Text = QTUtility.ResMain[0x1b];
                          menuTextBoxTabAlias.ForeColor = SystemColors.GrayText;
                      }
                      menuTextBoxTabAlias.Enabled = !tabControl1.AutoSubText;
                  }
                  if(tsmiTabOrder.DropDownItems.Count == 0) {
                      ((ToolStripDropDownMenu)tsmiTabOrder.DropDown).ShowImageMargin = false;
                      ToolStripMenuItem item2 = new ToolStripMenuItem(QTUtility.ResMain[0x1d]);
                      ToolStripMenuItem item3 = new ToolStripMenuItem(QTUtility.ResMain[30]);
                      ToolStripMenuItem item4 = new ToolStripMenuItem(QTUtility.ResMain[0x1f]);
                      ToolStripSeparator separator = new ToolStripSeparator();
                      ToolStripMenuItem item5 = new ToolStripMenuItem(QTUtility.ResMain[0x22]);
                      item2.Name = "Name";
                      item3.Name = "Drive";
                      item4.Name = "Active";
                      separator.Enabled = false;
                      item5.Name = "Rev";
                      tsmiTabOrder.DropDownItems.Add(item2);
                      tsmiTabOrder.DropDownItems.Add(item3);
                      tsmiTabOrder.DropDownItems.Add(item4);
                      tsmiTabOrder.DropDownItems.Add(separator);
                      tsmiTabOrder.DropDownItems.Add(item5);
                      tsmiTabOrder.DropDownItemClicked += menuitemTabOrder_DropDownItemClicked;
                  }
                  if((lstPluginMenuItems_Tab != null) && (lstPluginMenuItems_Tab.Count > 0)) {
                      foreach(ToolStripItem item6 in lstPluginMenuItems_Tab) {
                          item6.Dispose();
                      }
                      lstPluginMenuItems_Tab = null;
                  }
                  if((pluginServer != null) && (pluginServer.dicFullNamesMenuRegistered_Tab.Count > 0)) {
                      lstPluginMenuItems_Tab = new List<ToolStripItem>();
                      int num2 = contextMenuTab.Items.IndexOf(tsmiProp);
                      ToolStripSeparator separator2 = new ToolStripSeparator();
                      contextMenuTab.Items.Insert(num2, separator2);
                      foreach(string str3 in pluginServer.dicFullNamesMenuRegistered_Tab.Keys) {
                          ToolStripMenuItem item7 = new ToolStripMenuItem(pluginServer.dicFullNamesMenuRegistered_Tab[str3]);
                          item7.Name = str3;
                          item7.Tag = MenuType.Tab;
                          item7.Click += pluginitems_Click;
                          contextMenuTab.Items.Insert(num2, item7);
                          lstPluginMenuItems_Tab.Add(item7);
                      }
                      lstPluginMenuItems_Tab.Add(separator2);
                  }
                  contextMenuTab.ResumeLayout();
              }
          }
  
          private void Controls_GotFocus(object sender, EventArgs e) {
              OnGotFocus(e);
          }
  
          internal List<ToolStripItem> CreateBranchMenu(bool fCurrent, IContainer container, ToolStripItemClickedEventHandler itemClickedEvent) {
              QTabItem item = fCurrent ? CurrentTab : ContextMenuedTab;
              List<ToolStripItem> list = new List<ToolStripItem>();
              List<LogData> branches = item.Branches;
              if(branches.Count > 0) {
                  ToolStripMenuItem item2 = new ToolStripMenuItem(QTUtility.ResMain[0x18]);
                  item2.Tag = item;
                  item2.DropDown = new DropDownMenuBase(container, true, true);
                  item2.DropDown.ImageList = QTUtility.ImageListGlobal;
                  item2.DropDownItemClicked += itemClickedEvent;
                  int index = -1;
                  foreach(LogData data in branches) {
                      index++;
                      if(IsSpecialFolderNeedsToTravel(data.Path)) {
                          if(LogEntryDic.ContainsKey(data.Hash)) {
                              goto Label_00B3;
                          }
                          continue;
                      }
                      if(!QTUtility2.PathExists(data.Path)) {
                          continue;
                      }
                  Label_00B3:
                      item2.DropDownItems.Add(MenuUtility.CreateMenuItem(new MenuItemArguments(data.Path, false, index, MenuGenre.Branch)));
                  }
                  if(item2.DropDownItems.Count > 0) {
                      list.Add(new ToolStripSeparator());
                      list.Add(item2);
                  }
              }
              return list;
          }
  
          private static Cursor CreateCursor(Bitmap bmpColor) {
              Cursor cursor;
              using(bmpColor) {
                  using(Bitmap bitmap = new Bitmap(0x20, 0x20)) {
                      ICONINFO piconinfo = new ICONINFO();
                      piconinfo.fIcon = false;
                      piconinfo.hbmColor = bmpColor.GetHbitmap();
                      piconinfo.hbmMask = bitmap.GetHbitmap();
                      try {
                          cursor = new Cursor(PInvoke.CreateIconIndirect(ref piconinfo));
                      }
                      catch {
                          cursor = Cursors.Default;
                      }
                  }
              }
              return cursor;
          }
  
          private void CreateGroup(QTabItem contextMenuedTab) {
              NowModalDialogShown = true;
              using(CreateNewGroupForm form = new CreateNewGroupForm(contextMenuedTab.CurrentPath, tabControl1.TabPages)) {
                  form.TopMost = true;
                  form.ShowDialog();
              }
              NowModalDialogShown = false;
          }
  
          internal List<QMenuItem> CreateNavBtnMenuItems(bool fCurrent) {
              QTabItem item = fCurrent ? CurrentTab : ContextMenuedTab;
              List<QMenuItem> list = new List<QMenuItem>();
              string[] historyBack = item.GetHistoryBack();
              string[] historyForward = item.GetHistoryForward();
              if((historyBack.Length + historyForward.Length) > 1) {
                  for(int i = historyBack.Length - 1; i >= 0; i--) {
                      QMenuItem item2 = MenuUtility.CreateMenuItem(new MenuItemArguments(historyBack[i], true, i, MenuGenre.Navigation));
                      if(IsSpecialFolderNeedsToTravel(historyBack[i])) {
                          item2.Enabled = LogEntryDic.ContainsKey(item.GetLogHash(true, i));
                      }
                      else if(!QTUtility2.PathExists(historyBack[i])) {
                          item2.Enabled = false;
                      }
                      if(item2.Enabled && (i == 0)) {
                          item2.BackColor = QTUtility2.MakeModColor(SystemColors.Highlight);
                      }
                      list.Add(item2);
                  }
                  for(int j = 0; j < historyForward.Length; j++) {
                      QMenuItem item3 = MenuUtility.CreateMenuItem(new MenuItemArguments(historyForward[j], false, j, MenuGenre.Navigation));
                      if(IsSpecialFolderNeedsToTravel(historyForward[j])) {
                          item3.Enabled = LogEntryDic.ContainsKey(item.GetLogHash(false, j));
                      }
                      else if(!QTUtility2.PathExists(historyForward[j])) {
                          item3.Enabled = false;
                      }
                      list.Add(item3);
                  }
              }
              return list;
          }
  
          private QTabItem CreateNewTab(IDLWrapper idlw) {
              string path = idlw.Path;
              QTabItem tab = new QTabItem(QTUtility2.MakePathDisplayText(path, false), path, tabControl1);
              tab.NavigatedTo(path, idlw.IDL, -1, false);
              tab.ToolTipText = QTUtility2.MakePathDisplayText(path, true);
              AddInsertTab(tab);
              return tab;
          }
  
          internal static Bitmap[] CreateTabImage() {
              if(File.Exists(Config.Skin.TabImageFile)) {
                  try {
                      Bitmap[] bitmapArray = new Bitmap[3];
                      using(Bitmap bitmap = new Bitmap(Config.Skin.TabImageFile)) {
                          int height = bitmap.Height / 3;
                          bitmapArray[0] = bitmap.Clone(new Rectangle(0, 0, bitmap.Width, height), PixelFormat.Format32bppArgb);
                          bitmapArray[1] = bitmap.Clone(new Rectangle(0, height, bitmap.Width, height), PixelFormat.Format32bppArgb);
                          bitmapArray[2] = bitmap.Clone(new Rectangle(0, height * 2, bitmap.Width, height), PixelFormat.Format32bppArgb);
                      }
                      if(Path.GetExtension(Config.Skin.TabImageFile).PathEquals(".bmp")) {
                          bitmapArray[0].MakeTransparent(Color.Magenta);
                          bitmapArray[1].MakeTransparent(Color.Magenta);
                          bitmapArray[2].MakeTransparent(Color.Magenta);
                      }
                      return bitmapArray;
                  }
                  catch {
                  }
              }
              return null;
          }
  
          // todo: handle links
          private static IEnumerable<string> CreateTMPPathsToOpenNew(Address[] addresses, string pathExclude) {
              List<string> list = new List<string>();
              QTUtility2.InitializeTemporaryPaths();
              for(int i = 0; i < addresses.Length; i++) {
                  try {
                      using(IDLWrapper wrapper = new IDLWrapper(addresses[i].ITEMIDLIST)) {
                          if(wrapper.Available && wrapper.HasPath) {
                              string path = wrapper.Path;
                              if(path.Length > 0 && !path.PathEquals(pathExclude) && 
                                      !QTUtility2.IsShellPathButNotFileSystem(path) && 
                                      wrapper.IsFolder && !wrapper.IsLinkToDeadFolder) {
                                  list.Add(path);
                              }
                          }
                      }
                  }
                  catch {
                  }
              }
              return list;
          }
  
          private void ddmrUndoClose_ItemRightClicked(object sender, ItemRightClickedEventArgs e) {
              QMenuItem clickedItem = e.ClickedItem as QMenuItem;
              if(clickedItem != null) {
                  using(IDLWrapper wrapper = new IDLWrapper(clickedItem.Path)) {
                      e.HRESULT = shellContextMenu.Open(wrapper, e.IsKey ? e.Point : MousePosition, ((DropDownMenuReorderable)sender).Handle, true);
                  }
                  if(e.HRESULT == 0xffff) {
                      StaticReg.ClosedTabHistoryList.Remove(clickedItem.Path);
                      e.ClickedItem.Dispose();
                  }
              }
          }
  
          private void ddrmrGroups_ItemMiddleClicked(object sender, ItemRightClickedEventArgs e) {
              ReplaceByGroup(e.ClickedItem.Text);
          }
  
          protected override void Dispose(bool disposing) {
              if(disposing && (components != null)) {
                  components.Dispose();
              }
              base.Dispose(disposing);
          }
  
          private bool DoBindAction(BindAction action, bool fRepeat = false, QTabItem tab = null, IDLWrapper item = null) {
              if(fRepeat && !(
                      action == BindAction.GoBack ||
                      action == BindAction.GoForward ||
                      action == BindAction.TransparencyPlus ||
                      action == BindAction.TransparencyMinus)) {
                  return false;
              }
  
              if(tab == null) tab = CurrentTab;
  
              IntPtr ptr;
              switch(action) {
                  case BindAction.GoBack:
                      NavigateCurrentTab(true);
                      break;
  
                  case BindAction.GoForward:
                      NavigateCurrentTab(false);
                      break;
  
                  case BindAction.GoFirst:
                      NavigateToFirstOrLast(true);
                      break;
  
                  case BindAction.GoLast:
                      NavigateToFirstOrLast(false);
                      break;
  
                  case BindAction.NextTab:
                      if(tabControl1.SelectedIndex == tabControl1.TabCount - 1) {
                          tabControl1.SelectedIndex = 0;
                      }
                      else {
                          tabControl1.SelectedIndex++;
                      }
                      break;
  
                  case BindAction.PreviousTab:
                      if(tabControl1.SelectedIndex == 0) {
                          tabControl1.SelectedIndex = tabControl1.TabCount - 1;
                      }
                      else {
                          tabControl1.SelectedIndex--;
                      }
                      break;
  
                  case BindAction.FirstTab:
                      tabControl1.SelectedIndex = 0;
                      break;
  
                  case BindAction.LastTab:
                      tabControl1.SelectedIndex = tabControl1.TabCount - 1;
                      break;
  
                  case BindAction.CloseCurrent:
                  case BindAction.CloseTab:
                      NowTabDragging = false;
                      if(!tab.TabLocked) {
                          if(tabControl1.TabCount > 1) {
                              CloseTab(tab);
                          }
                          else {
                              WindowUtils.CloseExplorer(ExplorerHandle, 1);
                          }
                      }
                      break;
  
                  case BindAction.CloseAllButCurrent:
                  case BindAction.CloseAllButThis:
                      CloseAllTabsExcept(tab);
                      break;
  
                  case BindAction.CloseLeft:
                  case BindAction.CloseLeftTab:
                      CloseLeftRight(true, tab.Index);
                      break;
  
                  case BindAction.CloseRight:
                  case BindAction.CloseRightTab:
                      CloseLeftRight(false, tab.Index);
                      break;
  
                  case BindAction.CloseWindow:
                      WindowUtils.CloseExplorer(ExplorerHandle, 1);
                      break;
  
                  case BindAction.RestoreLastClosed:
                      RestoreLastClosed();
                      break;
  
                  case BindAction.CloneCurrent:
                  case BindAction.CloneTab:
                      CloneTabButton(tab, null, true, -1);
                      break;
  
                  case BindAction.TearOffCurrent:
                  case BindAction.TearOffTab:
                      if(tabControl1.TabCount > 1) {
                          using(IDLWrapper wrapper = new IDLWrapper(tab.CurrentIDL)) {
                              OpenNewWindow(wrapper);
                          }
                          CloseTab(tab);
                      }
                      break;
  
                  case BindAction.LockCurrent:
                  case BindAction.LockTab:
                      tab.TabLocked = !tab.TabLocked;
                      break;
  
                  case BindAction.LockAll:
                      bool lockState = tabControl1.TabPages.Any(t => t.TabLocked);
                      tabControl1.TabPages.ForEach(t => t.TabLocked = !lockState);
                      break;
  
                  case BindAction.BrowseFolder:
                      ChooseNewDirectory();
                      break;
  
                  case BindAction.CreateNewGroup:
                      CreateGroup(tab);
                      break;
  
                  case BindAction.ShowOptions:
                      OptionsDialog.Open();
                      break;
  
                  case BindAction.ShowToolbarMenu: // hmm.
                      Rectangle tabRect = tabControl1.GetTabRect(tabControl1.TabCount - 1, true);
                      contextMenuSys.Show(PointToScreen(new Point(tabRect.Right + 10, tabRect.Bottom - 10)));
                      break;
  
                  case BindAction.ShowTabMenuCurrent:
                      if(tab.Index != -1) {
                          ContextMenuedTab = tab;
                          Rectangle rect = tabControl1.GetTabRect(tab.Index, true);
                          contextMenuTab.Show(PointToScreen(new Point(rect.Right + 10, rect.Bottom - 10)));
                      }
                      break;
  
                  case BindAction.ShowTabMenu:
                      ContextMenuedTab = tab;
                      contextMenuTab.Show(MousePosition);
                      break;
  
                  case BindAction.ShowGroupMenu:
                      TryCallButtonBar(bbar => bbar.ClickItem(QTButtonBar.BII_GROUP));
                      break;
  
                  case BindAction.ShowRecentTabsMenu:
                      TryCallButtonBar(bbar => bbar.ClickItem(QTButtonBar.BII_RECENTTAB));
                      break;
  
                  case BindAction.ShowUserAppsMenu:
                      TryCallButtonBar(bbar => bbar.ClickItem(QTButtonBar.BII_APPLICATIONLAUNCHER));
                      break;
  
                  case BindAction.CopySelectedPaths:
                      if(listView.SubDirTipMenuIsShowing() || (subDirTip_Tab != null && subDirTip_Tab.MenuIsShowing)) {
                          return false;
                      }
                      DoFileTools(0);
                      break;
  
                  case BindAction.CopySelectedNames:
                      if(listView.SubDirTipMenuIsShowing() || (subDirTip_Tab != null && subDirTip_Tab.MenuIsShowing)) {
                          return false;
                      }
                      DoFileTools(1);
                      break;
  
                  case BindAction.CopyCurrentFolderPath:
                      DoFileTools(2);
                      break;
  
                  case BindAction.CopyCurrentFolderName:
                      DoFileTools(3);
                      break;
  
                  case BindAction.ChecksumSelected:
                      DoFileTools(4);
                      break;
  
                  case BindAction.ToggleTopMost:
                      ToggleTopMost(); // todo: move v to < ?
                      TryCallButtonBar(bbar => bbar.RefreshButtons());
                      break;
  
                  case BindAction.TransparencyPlus:
                  case BindAction.TransparencyMinus: {
                          // TODO!!!
                          int num9;
                          int num10;
                          byte num11;
                          if(0x80000 != ((int)PInvoke.Ptr_OP_AND(PInvoke.GetWindowLongPtr(ExplorerHandle, -20), 0x80000))) {
                              if(action == BindAction.TransparencyPlus) {
                                  return true;
                              }
                              PInvoke.SetWindowLongPtr(ExplorerHandle, -20, PInvoke.Ptr_OP_OR(PInvoke.GetWindowLongPtr(ExplorerHandle, -20), 0x80000));
                              PInvoke.SetLayeredWindowAttributes(ExplorerHandle, 0, 0xff, 2);
                          }
                          if(PInvoke.GetLayeredWindowAttributes(ExplorerHandle, out num9, out num11, out num10)) {
                              IntPtr ptr3;
                              if(action == BindAction.TransparencyPlus) {
                                  if(num11 > 0xf3) {
                                      num11 = 0xff;
                                  }
                                  else {
                                      num11 = (byte)(num11 + 12);
                                  }
                              }
                              else if(num11 < 0x20) {
                                  num11 = 20;
                              }
                              else {
                                  num11 = (byte)(num11 - 12);
                              }
                              PInvoke.SetLayeredWindowAttributes(ExplorerHandle, 0, num11, 2);
                              // IM!
                              //if(InstanceManager.TryGetButtonBarHandle(ExplorerHandle, out ptr3)) {
                              //    QTUtility2.SendCOPYDATASTRUCT(ptr3, (IntPtr)7, "track", (IntPtr)num11);
                              //}
                              if(num11 == 0xff) {
                                  PInvoke.SetWindowLongPtr(ExplorerHandle, -20, PInvoke.Ptr_OP_AND(PInvoke.GetWindowLongPtr(ExplorerHandle, -20), 0xfff7ffff));
                              }
                          }
                      }
                      break;
  
                  case BindAction.FocusFileList:
                      listView.SetFocus();
                      break;
  
                  case BindAction.FocusSearchBarReal:
                      if(QTUtility.IsXP) return false;
                      // todo, I don't think this works
                      PInvoke.SetFocus(GetSearchBand_Edit());
                      break;
  
                  case BindAction.FocusSearchBarBBar:
                      TryCallButtonBar(bbar => bbar.FocusSearchBox());
                      break;
  
                  case BindAction.ShowSDTSelected:
                      if(!Config.Tips.ShowSubDirTips) return false;
                      listView.ShowAndClickSubDirTip();
                      break;
  
                  case BindAction.SendToTray:
                      MinimizeToTray();
                      break;
  
                  case BindAction.FocusTabBar:
                      tabControl1.Focus();
                      tabControl1.FocusNextTab(false, true, false);
                      break;
  
                  case BindAction.NewTab:
                      using(IDLWrapper wrapper = new IDLWrapper(Config.Window.DefaultLocation)) {
                          OpenNewTab(wrapper, false, true);    
                      }
                      break;
  
                  case BindAction.NewWindow:
                      using(IDLWrapper wrapper = new IDLWrapper(Config.Window.DefaultLocation)) {
                          OpenNewWindow(wrapper);
                      }
                      break;
  
                  // TODO all the blank ones
                  case BindAction.NewFolder:
                      break;
                  case BindAction.NewFile:
                      break;
  
                  case BindAction.SwitchToLastActivated:
                      if(lstActivatedTabs.Count > 1 && tabControl1.TabPages.Contains(lstActivatedTabs[lstActivatedTabs.Count - 2])) {
                          try {
                              tabControl1.SelectTab(lstActivatedTabs[lstActivatedTabs.Count - 2]);
                          }
                          catch(ArgumentException) {
                          }
                      }
                      break;
  
                  case BindAction.MergeWindows:
                      MergeAllWindows();
                      break;
  
                  case BindAction.ShowRecentFilesMenu:
                      break;
                  case BindAction.SortTabsByName:
                      break;
                  case BindAction.SortTabsByPath:
                      break;
                  case BindAction.SortTabsByActive:
                      break;
  
                  case BindAction.UpOneLevelTab:
                  case BindAction.UpOneLevel:
                      UpOneLevel(); // Hmm...
                      break;
  
                  case BindAction.Refresh:
                      break;
                  case BindAction.Paste:
                      break;
                  case BindAction.Maximize:
                      break;
                  case BindAction.Minimize:
                      break;
  
                  case BindAction.CopyTabPath:
                      string currentPath = tab.CurrentPath;
                      if(currentPath.IndexOf("???") != -1) {
                          currentPath = currentPath.Substring(0, currentPath.IndexOf("???"));
                      }
                      QTUtility2.SetStringClipboard(currentPath);
                      break;
  
                  case BindAction.TabProperties:
                      ShellMethods.ShowProperties(tab.CurrentIDL);
                      break;
  
                  case BindAction.ShowTabSubfolderMenu:
                      break;
  
                  case BindAction.ItemOpenInNewTab:
                  case BindAction.ItemOpenInNewTabNoSel:
                  case BindAction.ItemOpenInNewWindow:
                      if(item.Available && item.HasPath && item.IsReadyIfDrive && !item.IsLinkToDeadFolder) {
                          using(IDLWrapper linkWrapper = item.ResolveTargetIfLink()) {
                              IDLWrapper actualItem = linkWrapper ?? item;
                              if(actualItem.IsFolder) {
                                  if(action == BindAction.ItemOpenInNewWindow) {
                                      OpenNewWindow(actualItem);
                                  }
                                  else {
                                      OpenNewTab(actualItem, action == BindAction.ItemOpenInNewTabNoSel);
                                  }
                              }
                          }
                      }
                      break;
  
                  case BindAction.ItemCut:
                  case BindAction.ItemCopy:      
                  case BindAction.ItemDelete:
                      break;
  
                  case BindAction.ItemProperties:
                      ShellMethods.ShowProperties(item.IDL);
                      break;
  
                  case BindAction.CopyItemPath:
                  case BindAction.CopyItemName:
                  case BindAction.ChecksumItem:
                      break;
              }
              return true;
          }
  
          // todo: clean, enum.
          internal bool DoFileTools(int index) {
              try {
                  Address[] addressArray;
                  List<string> list;
                  int num;
                  string displayName = string.Empty;
                  switch(index) {
                      case 0:
                      case 1:
                      case 4:
                          string str2;
                          if(!ShellBrowser.TryGetSelection(out addressArray, out str2, index == 1)) {
                              goto Label_019C;
                          }
                          list = new List<string>();
                          num = 0;
                          goto Label_00A1;
  
                      case 2:
                      case 3: {
                              using(IDLWrapper wrapper = ShellBrowser.GetShellPath()) {
                                  if(wrapper.Available) {
                                      displayName = ShellMethods.GetDisplayName(wrapper.PIDL, index == 3);
                                  }
                                  goto Label_019C;
                              }
                          }
                      case 5:
                          foreach(QTabItem item in tabControl1.TabPages) {
                              string currentPath = item.CurrentPath;
                              int length = currentPath.IndexOf("???");
                              if(length != -1) {
                                  currentPath = currentPath.Substring(0, length);
                              }
                              int num3 = currentPath.IndexOf("*?*?*");
                              if(num3 != -1) {
                                  currentPath = currentPath.Substring(0, num3);
                              }
                              displayName = displayName + ((displayName.Length == 0) ? string.Empty : "\r\n") + currentPath;
                          }
                          goto Label_019C;
  
                      default:
                          goto Label_019C;
                  }
              Label_004B:
                  if(addressArray[num].Path != null) {
                      if(index != 4) {
                          displayName = displayName + ((displayName.Length == 0) ? string.Empty : "\r\n") + addressArray[num].Path;
                      }
                      else {
                          list.Add(addressArray[num].Path);
                      }
                  }
                  num++;
              Label_00A1:
                  if(num < addressArray.Length) {
                      goto Label_004B;
                  }
                  if(index == 4) {
                      ShowMD5(list.ToArray());
                      return true;
                  }
              Label_019C:
                  if(displayName.Length > 0) {
                      QTUtility2.SetStringClipboard(displayName);
                      return true;
                  }
              }
              catch {
              }
              if(index == 4) {
                  ShowMD5(null);
                  return true;
              }
              return false;
          }
  
          // This function is either called by BeforeNavigate2 (on XP and Vista)
          // or NavigateComplete2 (on 7)
          private void DoFirstNavigation(bool before, string path) {
              // TODO: sort out this mess
              if(StaticReg.CreateWindowPaths.Count > 0 || StaticReg.CreateWindowIDLs.Count > 0) {
                  foreach(string tpath in StaticReg.CreateWindowPaths.Where(str2 => !str2.PathEquals(path))) {
                      using(IDLWrapper wrapper = new IDLWrapper(tpath)) {
                          if(wrapper.Available) {
                              CreateNewTab(wrapper);
                          }
                      }
                  }
                  foreach(byte[] idl in StaticReg.CreateWindowIDLs) {
                      using(IDLWrapper wrapper2 = new IDLWrapper(idl)) {
                          OpenNewTab(wrapper2, true);
                      }
                  }
                  QTUtility2.InitializeTemporaryPaths();
                  AddStartUpTabs(string.Empty, path);
                  InitializeOpenedWindow();
              }
              else if(StaticReg.CreateWindowGroup.Length != 0) {
                  string createWindowTMPGroup = StaticReg.CreateWindowGroup;
                  StaticReg.CreateWindowGroup = string.Empty;
                  CurrentTab.CurrentPath = path;
                  NowOpenedByGroupOpener = true;
                  OpenGroup(createWindowTMPGroup, false);
                  AddStartUpTabs(createWindowTMPGroup, path);
                  InitializeOpenedWindow();
              }
              else if(!Config.Window.CaptureNewWindows || StaticReg.SkipNextCapture) {
                  StaticReg.SkipNextCapture = false;
                  AddStartUpTabs(string.Empty, path);
                  InitializeOpenedWindow();
              }
              else if(path.StartsWith(QTUtility.ResMisc[0]) ||
                      (path.EndsWith(QTUtility.ResMisc[0]) && QTUtility2.IsShellPathButNotFileSystem(path)) ||
                      path.PathEquals(QTUtility.PATH_SEARCHFOLDER)) {
                  InitializeOpenedWindow();
              }
              else {
                  if(QTUtility.NoCapturePathsList.Any(ncPath => ncPath.PathEquals(path))) {
                      InitializeOpenedWindow();
                      return;
                  }
                  if(Config.Window.CaptureNewWindows && ModifierKeys != Keys.Control && InstanceManager.GetTotalInstanceCount() > 0) {
                      string selectMe = GetNameToSelectFromCommandLineArg();
                      InstanceManager.BeginInvokeMain(tabbar => {
                          tabbar.OpenNewTab(path);
                          if(selectMe != "") {
                              tabbar.ShellBrowser.TrySetSelection(
                                      new Address[] { new Address(selectMe) }, null, true);    
                          }
                          tabbar.RestoreWindow();
                      });
                      fNowQuitting = true;
                      if(QTUtility.IsXP) {
                          WindowUtils.CloseExplorer(ExplorerHandle, 0);
                      }
                      else {
                          Explorer.Quit();
                      }
                      return;
                  }
                  AddStartUpTabs(string.Empty, path);
                  InitializeOpenedWindow();
              }
          }
  
          private int dropTargetWrapper_DragFileDrop(out IntPtr hwnd, out byte[] idlReal) {
              HideToolTipForDD();
              hwnd = tabControl1.Handle;
              idlReal = null;
              QTabItem tabMouseOn = tabControl1.GetTabMouseOn();
              if((tabMouseOn == null) || !Config.Tabs.DragOverTabOpensSDT) {
                  return 1;
              }
              if((tabMouseOn.CurrentIDL != null) && (tabMouseOn.CurrentIDL.Length > 0)) {
                  idlReal = tabMouseOn.CurrentIDL;
                  return 0;
              }
              return -1;
          }
  
          private DragDropEffects dropTargetWrapper_DragFileEnter(IntPtr hDrop, Point pnt, int grfKeyState) {
              if(Config.Tabs.DragOverTabOpensSDT) {
                  int num = HandleDragEnter(hDrop, out strDraggingDrive, out strDraggingStartPath);
                  fDrivesContainedDD = num == 2;
                  if(num == -1) {
                      return DragDropEffects.None;
                  }
                  if(tabControl1.GetTabMouseOn() == null) {
                      return DragDropEffects.Copy;
                  }
                  switch(num) {
                      case 0:
                          return DropTargetWrapper.MakeEffect(grfKeyState, 0);
  
                      case 1:
                          return DropTargetWrapper.MakeEffect(grfKeyState, 1);
  
                      case 2:
                          return DragDropEffects.None;
                  }
              }
              return DragDropEffects.Copy;
          }
  
          private void dropTargetWrapper_DragFileLeave(object sender, EventArgs e) {
              HideToolTipForDD();
              strDraggingDrive = null;
              strDraggingStartPath = null;
              tabControl1.Refresh();
          }
  
          private void dropTargetWrapper_DragFileOver(object sender, DragEventArgs e) {
              e.Effect = DragDropEffects.None;
              QTabItem tabMouseOn = tabControl1.GetTabMouseOn();
              bool flag = true;
              if(tabMouseOn != tabForDD) {
                  tabControl1.Refresh();
                  HideSubDirTip_Tab_Menu();
                  fToggleTabMenu = false;
                  flag = false;
              }
              if(tabMouseOn == null) {
                  e.Effect = DragDropEffects.Copy;
              }
              else if(tabMouseOn.CurrentPath.Length > 2) {
                  if(fDrivesContainedDD || strDraggingStartPath.PathEquals(tabMouseOn.CurrentPath)) {
                      if(toolTipForDD != null) {
                          toolTipForDD.Hide(tabControl1);
                      }
                      ShowToolTipForDD(tabMouseOn, -1, e.KeyState);
                  }
                  else {
                      using(IDLWrapper wrapper = new IDLWrapper(tabMouseOn.CurrentIDL, !flag)) {
                          if(wrapper.Available && wrapper.IsDropTarget) {
                              string b = tabMouseOn.CurrentPath.Substring(0, 3);
                              int num = strDraggingDrive != null && strDraggingDrive.Equals(b, StringComparison.OrdinalIgnoreCase)
                                      ? 0 : 1;
                              ShowToolTipForDD(tabMouseOn, num, e.KeyState);
                              e.Effect = Config.Tabs.DragOverTabOpensSDT
                                      ? DropTargetWrapper.MakeEffect(e.KeyState, num)
                                      : DragDropEffects.Copy;
                          }
                          else {
                              HideToolTipForDD();
                          }
                      }
                  }
              }
              else {
                  HideToolTipForDD();
              }
          }
  
          private void Explorer_BeforeNavigate2(object pDisp, ref object URL, ref object Flags, ref object TargetFrameName, ref object PostData, ref object Headers, ref bool Cancel) {
              if(!IsShown) {
                  DoFirstNavigation(true, (string)URL);
              }
          }
  
          private void Explorer_NavigateComplete2(object pDisp, ref object URL) {
              string path = (string)URL;
              lastCompletedBrowseObjectIDL = lastAttemptedBrowseObjectIDL;
              ShellBrowser.OnNavigateComplete();
              if(!IsShown) {
                  DoFirstNavigation(false, path);
              }            
  
              if(fNowQuitting) {
                  Explorer.Quit();
              }
              else {
                  int hash = -1;
                  bool flag = IsSpecialFolderNeedsToTravel(path);
                  bool flag2 = QTUtility2.IsShellPathButNotFileSystem(path);
                  bool flag3 = QTUtility2.IsShellPathButNotFileSystem(CurrentTab.CurrentPath);
  
                  // If we're navigating on a locked tab, we simulate opening the target folder
                  // in a new tab.  First we clone the tab at the old address and lock it.  Then
                  // we move the current tab to the "new tab" position and unlock it.
                  if(!flag2 && !flag3 && !NavigatedByCode && CurrentTab.TabLocked) {
                      int pos = tabControl1.SelectedIndex;
                      tabControl1.SetRedraw(false);
                      QTabItem item = CloneTabButton(CurrentTab, null, false, pos);
                      item.TabLocked = true;
                      CurrentTab.TabLocked = false;
                      pos++;
                      int max = tabControl1.TabPages.Count - 1;
  
                      switch(Config.Tabs.NewTabPosition) {
                          case TabPos.Rightmost:
                              if(pos != max) {
                                  tabControl1.TabPages.Relocate(pos, max);
                              }
                              break;
                          case TabPos.Leftmost:
                              tabControl1.TabPages.Relocate(pos, 0);
                              break;
                          case TabPos.Left:
                              tabControl1.TabPages.Relocate(pos, pos - 1);
                              break;
                      }
                      tabControl1.SetRedraw(true);
  
                      lstActivatedTabs.Remove(CurrentTab);
                      lstActivatedTabs.Add(item);
                      lstActivatedTabs.Add(CurrentTab);
                      if(lstActivatedTabs.Count > 15) {
                          lstActivatedTabs.RemoveAt(0);
                      }
                  }
  
                  if(!NavigatedByCode && flag) {
                      hash = DateTime.Now.GetHashCode();
                      LogEntryDic[hash] = GetCurrentLogEntry();
                  }
                  ClearTravelLogs();
                  try {
                      tabControl1.SetRedraw(false);
                      if(fNowTravelByTree) {
                          using(IDLWrapper wrapper = GetCurrentPIDL()) {
                              QTabItem tabPage = CreateNewTab(wrapper);
                              tabControl1.SelectTabDirectly(tabPage);
                              CurrentTab = tabPage;
                          }
                      }
                      if(tabControl1.AutoSubText && !fNavigatedByTabSelection) {
                          CurrentTab.Comment = string.Empty;
                      }
                      CurrentAddress = path;
                      CurrentTab.Text = Explorer.LocationName;
                      CurrentTab.CurrentIDL = null;
                      CurrentTab.ShellToolTip = null;
                      byte[] idl;
                      using(IDLWrapper wrapper2 = GetCurrentPIDL()) {
                          CurrentTab.CurrentIDL = idl = wrapper2.IDL;
                          if(flag) {
                              if((!NavigatedByCode && (idl != null)) && (idl.Length > 0)) {
                                  path = path + "*?*?*" + hash;
                                  QTUtility.ITEMIDLIST_Dic_Session[path] = idl;
                                  CurrentTab.CurrentPath = CurrentAddress = path;
                              }
                          }
                          else if((flag2 && wrapper2.Available) && !CurrentTab.CurrentPath.Contains("???")) {
                              string str2;
                              int num2;
                              if(IDLWrapper.GetIDLHash(wrapper2.PIDL, out num2, out str2)) {
                                  hash = num2;
                                  CurrentTab.CurrentPath = CurrentAddress = path = str2;
                              }
                              else if((idl != null) && (idl.Length > 0)) {
                                  hash = num2;
                                  path = path + "???" + hash;
                                  IDLWrapper.AddCache(path, idl);
                                  CurrentTab.CurrentPath = CurrentAddress = path;
                              }
                          }
                          if(!NavigatedByCode) {
                              CurrentTab.NavigatedTo(CurrentAddress, idl, hash, fAutoNavigating);
                          }
                      }
                      SyncTravelState();
                      if(QTUtility.IsXP) {
                          if(CurrentAddress.StartsWith(QTUtility.PATH_SEARCHFOLDER)) {
                              ShowSearchBar(true);
                          }
                          else if(QTUtility.fExplorerPrevented) {
                              ShowFolderTree(true);
                              QTUtility.fExplorerPrevented = false;
                          }
                      }
                      if(CurrentAddress.StartsWith("::")) {
                          CurrentTab.ToolTipText = CurrentTab.Text;
                          QTUtility.DisplayNameCacheDic[CurrentAddress] = CurrentTab.Text;
                      }
                      else if(flag2) {
                          CurrentTab.ToolTipText = (string)URL;
                      }
                      else if(((CurrentAddress.Length == 3) || CurrentAddress.StartsWith(@"\\")) || (CurrentAddress.StartsWith("http://", StringComparison.OrdinalIgnoreCase) || CurrentAddress.StartsWith("ftp://", StringComparison.OrdinalIgnoreCase))) {
                          CurrentTab.ToolTipText = CurrentTab.CurrentPath;
                          QTUtility.DisplayNameCacheDic[CurrentAddress] = CurrentTab.Text;
                      }
                      else {
                          CurrentTab.ToolTipText = CurrentTab.CurrentPath;
                      }
                      if(NavigatedByCode && !NowTabCreated) {
                          string str3;
                          Address[] selectedItemsAt = CurrentTab.GetSelectedItemsAt(CurrentAddress, out str3);
                          if(selectedItemsAt != null) {
                              ShellBrowser.TrySetSelection(selectedItemsAt, str3, true);
                          }
                      }
                      if(QTUtility.RestoreFolderTree_Hide) {
                          new WaitTimeoutCallback(WaitTimeout).BeginInvoke(150, AsyncComplete_FolderTree, false);
                      }
                      if(fNowRestoring) {
                          fNowRestoring = false;
                          if(StaticReg.LockedTabsToRestoreList.Contains(path)) {
                              CurrentTab.TabLocked = true;
                          }
                      }
                      if((!QTUtility.IsXP || FirstNavigationCompleted) && (!PInvoke.IsWindowVisible(ExplorerHandle) || PInvoke.IsIconic(ExplorerHandle))) {
                          WindowUtils.BringExplorerToFront(ExplorerHandle);
                      }
                      if(pluginServer != null) {
                          pluginServer.OnNavigationComplete(tabControl1.SelectedIndex, idl, (string)URL);
                      }
                      if(buttonNavHistoryMenu.DropDown.Visible) {
                          buttonNavHistoryMenu.DropDown.Close(ToolStripDropDownCloseReason.AppFocusChange);
                      }
                      if(Config.Misc.AutoUpdate) {
                          UpdateChecker.Check(false);
                      }
                  }
                  catch(Exception exception) {
                      QTUtility2.MakeErrorLog(exception);
                  }
                  finally {
                      QTUtility.RestoreFolderTree_Hide = NavigatedByCode = fNavigatedByTabSelection = NowTabCreated = fNowTravelByTree = false;
                      tabControl1.SetRedraw(true);
                      FirstNavigationCompleted = true;
                  }
              }
          }
  
          private bool explorerController_MessageCaptured(ref Message msg) {
              if(msg.Msg != WM.CLOSE) {
                  iSequential_WM_CLOSE = 0;
              }
              
              if(msg.Msg == WM_BROWSEOBJECT) {
                  SBSP flags = (SBSP)Marshal.ReadInt32(msg.WParam);
                  if((flags & SBSP.NAVIGATEBACK) != 0) {
                      msg.Result = (IntPtr)1;
                      if(!NavigateCurrentTab(true) && CloseTab(CurrentTab, true) && tabControl1.TabCount == 0) {
                          WindowUtils.CloseExplorer(ExplorerHandle, 2);
                      }
                  }
                  else if((flags & SBSP.NAVIGATEFORWARD) != 0) {
                      msg.Result = (IntPtr)1;
                      NavigateCurrentTab(false);
                  }
                  else {
                      IntPtr pidl = IntPtr.Zero;
                      if(msg.LParam != IntPtr.Zero) {
                          pidl = PInvoke.ILClone(msg.LParam);
                      }
                      bool autonav = (flags & SBSP.AUTONAVIGATE) != 0;
                      using(IDLWrapper wrapper = new IDLWrapper(pidl)) {
                          msg.Result = (IntPtr)(BeforeNavigate(wrapper, autonav) ? 1 : 0);
                      }
                  }
                  return true;
              }
              else if(msg.Msg == WM_HEADERINALLVIEWS) {
                  msg.Result = (IntPtr)(Config.Tweaks.AlwaysShowHeaders ? 1 : 0);
                  return true;
              }
              else if(msg.Msg == WM_SHOWHIDEBARS) {
                  // Todo: hardcoding = bad
                  object pvaTabBar = new Guid("{d2bf470e-ed1c-487f-a333-2bd8835eb6ce}").ToString("B");
                  object pvaButtonBar = new Guid("{d2bf470e-ed1c-487f-a666-2bd8835eb6ce}").ToString("B");
                  object pvarShow = (msg.WParam != IntPtr.Zero);
                  object pvarSize = null;
                  try {
                      Explorer.ShowBrowserBar(pvaTabBar, pvarShow, pvarSize);
                      Explorer.ShowBrowserBar(pvaButtonBar, pvarShow, pvarSize);
                      msg.Result = (IntPtr)1;
                  }
                  catch(COMException) {
                  }
                  return true;
              }
              else if(msg.Msg == WM_CHECKPULSE) {
                  if(fNeedsNewWindowPulse && msg.LParam != IntPtr.Zero) {
                      Marshal.WriteIntPtr(msg.LParam, Marshal.GetIDispatchForObject(Explorer));
                      msg.Result = (IntPtr)1;
                      fNeedsNewWindowPulse = false;
                  }
                  return true;
              }
  
              switch(msg.Msg) {
                  case WM.SETTINGCHANGE:
                      if(QTUtility.IsXP) {
                          QTUtility.GetShellClickMode();
                      }
                      if(Marshal.PtrToStringUni(msg.LParam) == "Environment") {
                          // todo: hmmmm....
                          //QTUtility.fRequiredRefresh_App = true;
                          SyncTaskBarMenu();
                      }
                      return false;
  
                  case WM.NCLBUTTONDOWN:
                  case WM.NCRBUTTONDOWN:
                      HideTabSwitcher(false);
                      return false;
  
                  case WM.MOVE:
                  case WM.SIZE:
                      listView.HideThumbnailTooltip(0);
                      listView.HideSubDirTip(0);
                      return false;
  
                  case WM.ACTIVATE: {
                      int num3 = ((int) msg.WParam) & 0xffff;
                      if(num3 > 0) {
                          // I can't figure out why, but calling these methods synchronously
                          // prevents the window from being restored when minimized.
                          // I guess neither has to synchronous anyway, so...
                          BeginInvoke(new Action(() => {
                              InstanceManager.PushTabBarInstance(this);
                              InstanceManager.RemoveFromTrayIcon(Handle);
                          }));
                      }
                      else {
                          listView.HideThumbnailTooltip(1);
                          listView.HideSubDirTip_ExplorerInactivated();
                          HideTabSwitcher(false);
                          if(tabControl1.Focused) {
                              listView.SetFocus();
                          }
                          if((Config.Tabs.ShowCloseButtons &&
                                  Config.Tabs.CloseBtnsWithAlt) &&
                                          tabControl1.EnableCloseButton) {
                              tabControl1.EnableCloseButton = false;
                              tabControl1.Refresh();
                          }
                      }
                      return false;
                  }
                  case WM.CLOSE:
                      if(iSequential_WM_CLOSE > 0) {
                          return true;
                      }
                      iSequential_WM_CLOSE++;
                      return HandleCLOSE(msg.LParam);
  
                  case WM.NCMBUTTONDOWN:
                  case WM.NCXBUTTONDOWN:
                      HideTabSwitcher(false);
                      return false;
  
                  case WM.SYSCOMMAND:
                      if((((int) msg.WParam) & 0xfff0) == 0xf020) {
                          if(pluginServer != null) {
                              pluginServer.OnExplorerStateChanged(ExplorerWindowActions.Minimized);
                          }
                          if(Config.Window.TrayOnMinimize) {
                              MinimizeToTray();
                              return true;
                          }
                          return false;
                      }
                      if((((int) msg.WParam) & 0xfff0) == 0xf030) {
                          if(pluginServer != null) {
                              pluginServer.OnExplorerStateChanged(ExplorerWindowActions.Maximized);
                          }
                          return false;
                      }
                      if((((int) msg.WParam) & 0xfff0) == 0xf120) {
                          if(pluginServer != null) {
                              pluginServer.OnExplorerStateChanged(ExplorerWindowActions.Restored);
                          }
                          return false;
                      }
                      if((Config.Window.TrayOnClose &&
                              ((((int) msg.WParam) == 0xf060) || (((int) msg.WParam) == 0xf063))) &&
                                      (ModifierKeys != Keys.Shift)) {
                          MinimizeToTray();
                          return true;
                      }
                      if(!QTUtility.IsXP || ((((int) msg.WParam) != 0xf060) && (((int) msg.WParam) != 0xf063))) {
                          return false;
                      }
                      WindowUtils.CloseExplorer(ExplorerHandle, 3);
                      return true;
  
                  case WM.POWERBROADCAST:
                      if(((int) msg.WParam) == 7) {
                          OnAwake();
                      }
                      return false;
  
                  case WM.DEVICECHANGE:
                      if(((int) msg.WParam) == 0x8004) {
                          DEV_BROADCAST_HDR dev_broadcast_hdr = (DEV_BROADCAST_HDR)Marshal.PtrToStructure(msg.LParam, typeof(DEV_BROADCAST_HDR));
                          if(dev_broadcast_hdr.dbch_devicetype == 2) {
                              DEV_BROADCAST_VOLUME dev_broadcast_volume = (DEV_BROADCAST_VOLUME)Marshal.PtrToStructure(msg.LParam, typeof(DEV_BROADCAST_VOLUME));
                              uint num4 = dev_broadcast_volume.dbcv_unitmask;
                              ushort num5 = 0;
                              while(num5 < 0x1a) {
                                  if((num4 & 1) != 0) {
                                      break;
                                  }
                                  num4 = num4 >> 1;
                                  num5 = (ushort) (num5 + 1);
                              }
                              num5 = (ushort) (num5 + 0x41);
                              string str = ((char) num5) + @":\";
                              CloseTabs(tabControl1.TabPages.Where(item =>
                                      item.CurrentPath.PathStartsWith(str)).ToList(), true);
                              if(tabControl1.TabCount == 0) {
                                  WindowUtils.CloseExplorer(ExplorerHandle, 2);
                              }
                          }
                      }
                      return false;
  
                  case WM.PARENTNOTIFY:
                      switch((((int)msg.WParam) & 0xffff)) {
                          case WM.LBUTTONDOWN:
                          case WM.RBUTTONDOWN:
                          case WM.MBUTTONDOWN:
                          case WM.XBUTTONDOWN:
                              HideTabSwitcher(false);
                              break;
                      }
                      return false;
  
  
                  case WM.APPCOMMAND:
                      // some mouse drivers and utilities have the extra buttons send WM_APPCOMMAND.
                      const int APPCOMMAND_BROWSER_BACKWARD = 1;
                      const int APPCOMMAND_BROWSER_FORWARD = 2;
                      const int APPCOMMAND_CLOSE = 31;
                      const int FAPPCOMMAND_MOUSE = 0x8000;
                      const int FAPPCOMMAND_MASK = 0xF000;
  
                      //GET_APPCOMMAND_LPARAM(lParam) ((short)(HIWORD(lParam) & ~FAPPCOMMAND_MASK))
                      //GET_DEVICE_LPARAM(lParam)     ((WORD)(HIWORD(lParam) & FAPPCOMMAND_MASK))
                      int command = ((((int)(long)msg.LParam) >> 16) & 0xFFFF) & ~FAPPCOMMAND_MASK;
                      int device = ((((int)(long)msg.LParam) >> 16) & 0xFFFF) & FAPPCOMMAND_MASK;
                      bool fProcess = device != FAPPCOMMAND_MOUSE;
                      BindAction action;
  
                      switch(command) {
                          case APPCOMMAND_BROWSER_BACKWARD:
                              if(fProcess) {
                                  MouseChord chord = QTUtility.MakeMouseChord(MouseChord.X1, ModifierKeys);
                                  if(Config.Mouse.GlobalMouseActions.TryGetValue(chord, out action)) {
                                      DoBindAction(action);
                                  }
                              }
                              return true;
  
                          case APPCOMMAND_BROWSER_FORWARD:
                              if(fProcess) {
                                  MouseChord chord = QTUtility.MakeMouseChord(MouseChord.X2, ModifierKeys);
                                  if(Config.Mouse.GlobalMouseActions.TryGetValue(chord, out action)) {
                                      DoBindAction(action);
                                  }
                              }
                              return true;
  
                          case APPCOMMAND_CLOSE:
                              WindowUtils.CloseExplorer(ExplorerHandle, 0);
                              return true;
                      }
                      break;
              }
              return false;
          }
  
          public override void GetBandInfo(uint dwBandID, uint dwViewMode, ref DESKBANDINFO dbi) {
              if((dbi.dwMask & DBIM.ACTUAL) != (0)) {
                  dbi.ptActual.X = Size.Width;
                  dbi.ptActual.Y = BandHeight;
              }
              if((dbi.dwMask & DBIM.INTEGRAL) != (0)) {
                  dbi.ptIntegral.X = -1;
                  dbi.ptIntegral.Y = 10;
              }
              if((dbi.dwMask & DBIM.MAXSIZE) != (0)) {
                  dbi.ptMaxSize.X = -1;
                  dbi.ptMaxSize.Y = BandHeight;
              }
              if((dbi.dwMask & DBIM.MINSIZE) != (0)) {
                  dbi.ptMinSize.X = MinSize.Width;
                  dbi.ptMinSize.Y = BandHeight;
              }
              if((dbi.dwMask & DBIM.MODEFLAGS) != (0)) {
                  dbi.dwModeFlags = DBIMF.NORMAL;
              }
              if((dbi.dwMask & DBIM.BKCOLOR) != (0)) {
                  dbi.dwMask &= ~DBIM.BKCOLOR;
              }
              if((dbi.dwMask & DBIM.TITLE) != (0)) {
                  dbi.wszTitle = null;
              }
          }
  
          private ITravelLogEntry GetCurrentLogEntry() {
              IEnumTravelLogEntry ppenum = null;
              ITravelLogEntry rgElt = null;
              ITravelLogEntry entry3;
              try {
                  if(TravelLog.EnumEntries(1, out ppenum) == 0) {
                      ppenum.Next(1, out rgElt, 0);
                  }
                  entry3 = rgElt;
              }
              catch(Exception exception) {
                  QTUtility2.MakeErrorLog(exception);
                  entry3 = null;
              }
              finally {
                  if(ppenum != null) {
                      Marshal.ReleaseComObject(ppenum);
                  }
              }
              return entry3;
          }
  
          internal IDLWrapper GetCurrentPIDL() {
              IDLWrapper wrapper = ShellBrowser.GetShellPath();
              if(!wrapper.Available) {
                  wrapper.Dispose();
                  wrapper = new IDLWrapper(ShellMethods.ShellGetPath2(ExplorerHandle));
                  if(!wrapper.Available) {
                      wrapper.Dispose();
                      wrapper = new IDLWrapper(lastCompletedBrowseObjectIDL);
                  }
              }
              return wrapper;
          }
  
          private Cursor GetCursor(bool fDragging) {
              return fDragging ?
                      curTabDrag ?? (curTabDrag = CreateCursor(Resources_Image.imgCurTabDrag)) :
                      curTabCloning ?? (curTabCloning = CreateCursor(Resources_Image.imgCurTabCloning));
          }
  
          private static string GetNameToSelectFromCommandLineArg() {
              string str = Marshal.PtrToStringUni(PInvoke.GetCommandLine());
              if(!string.IsNullOrEmpty(str)) {
                  int index = str.IndexOf("/select,", StringComparison.CurrentCultureIgnoreCase);
                  if(index == -1) {
                      index = str.IndexOf(",select,", StringComparison.CurrentCultureIgnoreCase);
                  }
                  if(index != -1) {
                      index += 8;
                      if(str.Length < index) {
                          return string.Empty;
                      }
                      string path = str.Substring(index).Split(new char[] { ',' })[0].Trim().Trim(new char[] { ' ', '"' });
                      try {
                          if(File.Exists(path) || Directory.Exists(path)) {
                              return Path.GetFileName(path);
                          }
                      }
                      catch {
                      }
                  }
              }
              return string.Empty;
          }
  
          private IntPtr GetSearchBand_Edit() {
              IntPtr hwndSearchBand = WindowUtils.FindChildWindow(ExplorerHandle, hwnd => PInvoke.GetClassName(hwnd) == "UniversalSearchBand");
              if(hwndSearchBand != IntPtr.Zero) {
                  hwndSearchBand = WindowUtils.FindChildWindow(hwndSearchBand, hwnd =>
                          PInvoke.GetClassName(hwnd) == "Edit" && ((int)PInvoke.GetWindowLongPtr(hwnd, -16) & 0x10000000) != 0);
              }
              return hwndSearchBand;
          }
  
          public ShellBrowserEx GetShellBrowser() {
              return ShellBrowser;
          }
  
          private IntPtr GetTravelToolBarWindow32() {
              IntPtr hwndTravelBand = WindowUtils.FindChildWindow(ExplorerHandle, hwnd => PInvoke.GetClassName(hwnd) == "TravelBand");
              return hwndTravelBand != IntPtr.Zero 
                      ? PInvoke.FindWindowEx(hwndTravelBand, IntPtr.Zero, "ToolbarWindow32", null) 
                      : IntPtr.Zero;
          }
          
          // TODO
          private void Handle_MButtonUp_Tree(MSG msg) {
              IntPtr ptr;
              if(ShellBrowser.IsFolderTreeVisible(out ptr) && msg.hwnd == ptr) {
                  TVHITTESTINFO structure = new TVHITTESTINFO {pt = QTUtility2.PointFromLPARAM(msg.lParam)};
                  IntPtr wParam = PInvoke.SendMessage(ptr, 0x1111, IntPtr.Zero, ref structure);
                  if(wParam != IntPtr.Zero) {
                      int num = (int)PInvoke.SendMessage(ptr, 0x1127, wParam, (IntPtr)2);
                      if((num & 2) == 0) {
                          NavigatedByCode = fNowTravelByTree = true;
                          PInvoke.SendMessage(ptr, 0x110b, (IntPtr)9, wParam);
                      }
                  }
              }
          }
  
          private bool HandleCLOSE(IntPtr lParam) {
              bool flag = Config.Window.CloseBtnClosesSingleTab;
              bool flag2 = Config.Window.CloseBtnClosesUnlocked;
              List<string> closingPaths = new List<string>();
              int num = (int)lParam;
              switch(num) {
                  case 1:
                      closingPaths = CloseAllTabsExcept(null, flag2);
                      if(tabControl1.TabCount > 0) {
                          return true;
                      }
                      break;
                      
                  case 2:
                      return false;
  
                  default: {
                          bool flag3 = QTUtility2.PathExists(CurrentTab.CurrentPath);
                          if((QTUtility.IsXP && flag3) && (num == 0)) {
                              return true;
                          }
                          if(!flag3) {
                              CloseTab(CurrentTab, true);
                              return (tabControl1.TabCount > 0);
                          }
                          if(flag2 && !flag) {
                              closingPaths = CloseAllTabsExcept(null);
                              if(tabControl1.TabCount > 0) {
                                  return true;
                              }
                              QTUtility.SaveClosing(closingPaths);
                              return false;
                          }
                          Keys modifierKeys = ModifierKeys;
                          if((modifierKeys == (Keys.Control | Keys.Shift)) || !flag) {
                              foreach(QTabItem item2 in tabControl1.TabPages) {
                                  closingPaths.Add(item2.CurrentPath);
                                  AddToHistory(item2);
                              }
                              QTUtility.SaveClosing(closingPaths);
                              return false;
                          }
                          if(modifierKeys == Keys.Control) {
                              closingPaths = CloseAllTabsExcept(null);
                          }
                          else {
                              closingPaths.Add(CurrentTab.CurrentPath);
                              CloseTab(CurrentTab, false);
                          }
                          if(tabControl1.TabCount > 0) {
                              return true;
                          }
                          QTUtility.SaveClosing(closingPaths);
                          return false;
                      }
              }
              QTUtility.SaveClosing(closingPaths);
              return false;
          }
  
          internal static int HandleDragEnter(IntPtr hDrop, out string strDraggingDrive, out string strDraggingStartPath) {
              strDraggingDrive = (strDraggingStartPath = null);
              int capacity = (int)PInvoke.DragQueryFile(hDrop, uint.MaxValue, null, 0);
              if(capacity < 1) {
                  return -1;
              }
              List<string> list = new List<string>(capacity);
              for(int i = 0; i < capacity; i++) {
                  StringBuilder lpszFile = new StringBuilder(260);
                  PInvoke.DragQueryFile(hDrop, (uint)i, lpszFile, lpszFile.Capacity);
                  if(lpszFile.Length > 0) {
                      list.Add(lpszFile.ToString());
                  }
              }
              if(list.Count <= 0) {
                  return -1;
              }
              if(list[0].Length < 4) {
                  return 2;
              }
              bool flag = true;
              string b = QTUtility2.MakeRootName(list[0]);
              foreach(string str2 in list) {
                  if(File.Exists(str2) || Directory.Exists(str2)) {
                      if(str2.Length <= 3) {
                          return 2;
                      }
                      if(!QTUtility2.MakeRootName(str2).PathEquals(b)) {
                          flag = false;
                      }
                      continue;
                  }
                  return -1;
              }
              if(flag) {
                  strDraggingDrive = b;
                  strDraggingStartPath = Path.GetDirectoryName(list[0]);
                  return 0;
              }
              return 1;
          }
  
          private static void HandleF5() {
              TryCallButtonBar(bbar => bbar.RefreshSearchBox(false));
          }
  
          private void HandleFileDrop(IntPtr hDrop) {
              HideToolTipForDD();
              int capacity = (int)PInvoke.DragQueryFile(hDrop, uint.MaxValue, null, 0);
              if(capacity >= 1) {
                  List<string> listDroppedPaths = new List<string>(capacity);
                  for(int i = 0; i < capacity; i++) {
                      StringBuilder lpszFile = new StringBuilder(260);
                      PInvoke.DragQueryFile(hDrop, (uint)i, lpszFile, lpszFile.Capacity);
                      listDroppedPaths.Add(lpszFile.ToString());
                  }
                  OpenDroppedFolder(listDroppedPaths);
              }
          }
  
          private bool HandleKEYDOWN(Keys key, bool fRepeat) {
              Keys mkey = key | ModifierKeys;
  
              switch(key) {
                  case Keys.Enter:
                      return false;
  
                  case Keys.Menu:
                      if(!fRepeat && Config.Tabs.ShowCloseButtons && Config.Tabs.CloseBtnsWithAlt) {
                          tabControl1.ShowCloseButton(true);
                      }
                      return false;
  
                  case Keys.ControlKey:
                      if(!fRepeat && NowTabDragging && DraggingTab != null && tabControl1.GetTabMouseOn() == null) {
                          Cursor = GetCursor(false);
                      }
                      break;
  
                  case Keys.Tab:
                      if(Config.Keys.UseTabSwitcher && (mkey & Keys.Control) != Keys.None) {
                          return ShowTabSwitcher((mkey & Keys.Shift) != Keys.None, fRepeat);
                      }
                      break;
              }
  
              switch(mkey) {
                  case Keys.Back:
                      if(!QTUtility.IsXP) {
                          if(listView.HasFocus()) {
                              if(!fRepeat) {
                                  if(Config.Tweaks.BackspaceUpLevel) {
                                      UpOneLevel();
                                  }
                                  else {
                                      NavigateCurrentTab(true);
                                  }
                              }
                              return true;
                          }
                      }
                      return false;
  
                  case Keys.Alt | Keys.Left:
                      NavigateCurrentTab(true);
                      return true;
  
                  case Keys.Alt | Keys.Right:
                      NavigateCurrentTab(false);
                      return true;
  
                  case Keys.Alt | Keys.F4:
                      if(!fRepeat) {
                          WindowUtils.CloseExplorer(ExplorerHandle, 1);
                      }
                      return true;
  
                  case Keys.F2:
                      if(!Config.Tweaks.F2Selection) {
                          listView.HandleF2();
                      }
                      return false;
  
              }
  
              // Ctrl+number = switch to tab #n
              if(((Keys.Control | Keys.NumPad0) <= mkey && mkey <= (Keys.Control | Keys.NumPad9)) ||
                      ((Keys.Control | Keys.D0) <= mkey && mkey <= (Keys.Control | Keys.D9))) {
                  int digit;
                  if(mkey >= (Keys.Control | Keys.NumPad0)) {
  
gt:                     digit = (mkey - (Keys.Control | Keys.NumPad0));