private void InstallDesktopHook() { const int WH_KEYBOARD = 2; const int WH_GETMESSAGE = 3; IntPtr hwndDesktop = GetDesktopHwnd(); if(timerHooks == null) { if(hwndDesktop == IntPtr.Zero) { // wait till desktop window is created timerHooks = new Timer(); timerHooks.Tick += (sender, args) => { if(++iHookTimeout > 5) { timerHooks.Stop(); MessageBox.Show( QTUtility.TextResourcesDic["ErrorDialogs"][8] ); return; } InstallDesktopHook(); }; timerHooks.Interval = 3000; timerHooks.Start(); return; } } else { if(hwndDesktop == IntPtr.Zero) { return; } else { timerHooks.Stop(); timerHooks.Dispose(); timerHooks = null; } } // Now we've got desktop window handle hwndShellTray = WindowUtils.GetShellTrayWnd(); hookProc_Msg_Desktop = CallbackGetMsgProc_Desktop; hookProc_Msg_ShellTrayWnd = CallbackGetMsgProc_ShellTrayWnd; hookProc_Keys_Desktop = CallbackKeyProc_Desktop; uint id1, id2; int threadID_Desktop = PInvoke.GetWindowThreadProcessId(hwndDesktop, out id1); int threadID_ShellTray = PInvoke.GetWindowThreadProcessId(hwndShellTray, out id2); hHook_MsgDesktop = PInvoke.SetWindowsHookEx(WH_GETMESSAGE, hookProc_Msg_Desktop, IntPtr.Zero, threadID_Desktop); hHook_MsgShell_TrayWnd = PInvoke.SetWindowsHookEx(WH_GETMESSAGE, hookProc_Msg_ShellTrayWnd, IntPtr.Zero, threadID_ShellTray); hHook_KeyDesktop = PInvoke.SetWindowsHookEx(WH_KEYBOARD, hookProc_Keys_Desktop, IntPtr.Zero, threadID_Desktop); // get IFolderView on the desktop thread... // todo: quizo claims this must be done on the desktop thread. I disagree. test. GetFolderView(); // subclassing ShellView // todo: hmm, is this allowed here? I would think you'd have to do this in the desktop's thread. const int GWL_HWNDPARENT = -8; // todo: constify IntPtr hwndShellView = PInvoke.GetWindowLongPtr(hwndDesktop, GWL_HWNDPARENT); slvDesktop = new ExtendedSysListView32(ShellBrowser, hwndShellView, hwndDesktop, hwndThis); slvDesktop.SelectionActivated += ListView_SelectionActivated; slvDesktop.MiddleClick += ListView_MiddleClick; slvDesktop.MouseActivate += ListView_MouseActivate; slvDesktop.SubDirTip_MenuItemClicked += subDirTip_MenuItemClicked; slvDesktop.SubDirTip_MenuItemRightClicked += subDirTip_MenuItemRightClicked; slvDesktop.SubDirTip_MultipleMenuItemsClicked += subDirTip_MultipleMenuItemsClicked; slvDesktop.SubDirTip_MultipleMenuItemsRightClicked += subDirTip_MultipleMenuItemsRightClicked; }
public override void CloseDW(uint dwReserved) { if(iContextMenu2 != null) { Marshal.ReleaseComObject(iContextMenu2); iContextMenu2 = null; } if(ShellBrowser != null) { ShellBrowser.Dispose(); ShellBrowser = null; } lock(this) { if(listView != null) { listView.RemoteDispose(); listView = null; } } DisposeInvoker method = disposable => disposable.Dispose(); if(hashForm != null) { hashForm.Invoke(method, new object[] { hashForm }); hashForm = null; } if(hHook_MsgDesktop != IntPtr.Zero) { PInvoke.UnhookWindowsHookEx(hHook_MsgDesktop); hHook_MsgDesktop = IntPtr.Zero; } if(hHook_MsgShell_TrayWnd != IntPtr.Zero) { PInvoke.UnhookWindowsHookEx(hHook_MsgShell_TrayWnd); hHook_MsgShell_TrayWnd = IntPtr.Zero; } if(hHook_KeyDesktop != IntPtr.Zero) { PInvoke.UnhookWindowsHookEx(hHook_KeyDesktop); hHook_KeyDesktop = IntPtr.Zero; } base.CloseDW(dwReserved); }
private void ListView_Destroyed(object sender, EventArgs e) { lock(this) { listView.Dispose(); listView = null; } }
private IntPtr CallbackGetMsgProc_Desktop(int nCode, IntPtr wParam, IntPtr lParam) { if(nCode >= 0) { MSG msg = (MSG)Marshal.PtrToStructure(lParam, typeof(MSG)); if(msg.hwnd == hwndListView && msg.message == WM.APP + 100) { IntPtr hwnd = PInvoke.FindWindowEx(IntPtr.Zero, IntPtr.Zero, "Progman", null); IntPtr pUnk = PInvoke.SendMessage(hwnd, WM.USER + 7, IntPtr.Zero, IntPtr.Zero); if(pUnk == IntPtr.Zero) { timerISV = new Timer(); timerISV.Tag = msg.hwnd; timerISV.Tick += (sender, args) => { PInvoke.PostMessage((IntPtr)timerISV.Tag, WM.APP + 100, IntPtr.Zero, IntPtr.Zero); timerISV.Enabled = false; }; timerISV.Interval = 2000; timerISV.Start(); } else { ShellBrowser = new ShellBrowserEx((IShellBrowser)Marshal.GetObjectForIUnknown(pUnk), true); listView = new ExtendedSysListView32(ShellBrowser, PInvoke.GetParent(hwndListView), hwndListView, ThisHandle); listView.MouseActivate += ListView_MouseActivate; listView.SelectionActivated += ListView_SelectionActivated; listView.MiddleClick += ListView_MiddleClick; listView.DoubleClick += ListView_DoubleClick; listView.ListViewDestroyed += ListView_Destroyed; listView.SubDirTip_MenuItemClicked += subDirTip_MenuItemClicked; listView.SubDirTip_MenuItemRightClicked += subDirTip_MenuItemRightClicked; listView.SubDirTip_MultipleMenuItemsClicked += subDirTip_MultipleMenuItemsClicked; listView.SubDirTip_MultipleMenuItemsRightClicked += subDirTip_MultipleMenuItemsRightClicked; } } } return PInvoke.CallNextHookEx(IntPtr.Zero, nCode, wParam, lParam); }
private void RecaptureHandles(IntPtr hwndShellView) { bool fIsSysListView = false; IntPtr hwndListView = WindowUtils.FindChildWindow(hwndShellView, hwnd => { string name = PInvoke.GetClassName(hwnd); if(name == "SysListView32") { fIsSysListView = true; return true; } else if(!QTUtility.IsXP && name == "DirectUIHWND") { fIsSysListView = false; return true; } return false; }); if(CurrentListView != null) { if(CurrentListView.Handle == hwndListView) { return; } PreviousListView = CurrentListView; } if(hwndListView == IntPtr.Zero) { CurrentListView = new AbstractListView(); } else if(fIsSysListView) { CurrentListView = new ExtendedSysListView32(ShellBrowser, hwndShellView, hwndListView, hwndSubDirTipMessageReflect); } else { CurrentListView = new ExtendedItemsView(ShellBrowser, hwndShellView, hwndListView, hwndSubDirTipMessageReflect); } CurrentListView.ListViewDestroyed += ListView_Destroyed; ListViewChanged(this, null); }