Exemple #1
0
        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);
        }