private void HookMouse() { Debug.Assert(s_adornerWindowList.Count > 0, "No AdornerWindow available to create the mouse hook"); lock (this) { if (_mouseHookHandle != IntPtr.Zero || s_adornerWindowList.Count == 0) { return; } if (_thisProcessID == 0) { AdornerWindow adornerWindow = s_adornerWindowList[0]; User32.GetWindowThreadProcessId(adornerWindow, out _thisProcessID); } var hook = new User32.HOOKPROC(MouseHookProc); _mouseHookRoot = GCHandle.Alloc(hook); _mouseHookHandle = User32.SetWindowsHookExW( User32.WH.MOUSE, hook, IntPtr.Zero, Kernel32.GetCurrentThreadId()); if (_mouseHookHandle != IntPtr.Zero) { _isHooked = true; } Debug.Assert(_mouseHookHandle != IntPtr.Zero, "Failed to install mouse hook"); } }
internal BehaviorService(IServiceProvider serviceProvider, Control windowFrame) { this.serviceProvider = serviceProvider; this.adornerWindow = new AdornerWindow(this, windowFrame); IOverlayService service = (IOverlayService) serviceProvider.GetService(typeof(IOverlayService)); if (service != null) { this.adornerWindowIndex = service.PushOverlay(this.adornerWindow); } this.dragEnterReplies = new Hashtable(); this.adorners = new BehaviorServiceAdornerCollection(this); this.behaviorStack = new ArrayList(); this.hitTestedGlyph = null; this.validDragArgs = null; this.actionPointer = null; this.trackMouseEvent = null; this.trackingMouseEvent = false; IMenuCommandService menuService = serviceProvider.GetService(typeof(IMenuCommandService)) as IMenuCommandService; IDesignerHost host = serviceProvider.GetService(typeof(IDesignerHost)) as IDesignerHost; if ((menuService != null) && (host != null)) { this.menuCommandHandler = new MenuCommandHandler(this, menuService); host.RemoveService(typeof(IMenuCommandService)); host.AddService(typeof(IMenuCommandService), this.menuCommandHandler); } this.useSnapLines = false; this.queriedSnapLines = false; WM_GETALLSNAPLINES = System.Design.SafeNativeMethods.RegisterWindowMessage("WM_GETALLSNAPLINES"); WM_GETRECENTSNAPLINES = System.Design.SafeNativeMethods.RegisterWindowMessage("WM_GETRECENTSNAPLINES"); SystemEvents.DisplaySettingsChanged += new EventHandler(this.OnSystemSettingChanged); SystemEvents.InstalledFontsChanged += new EventHandler(this.OnSystemSettingChanged); SystemEvents.UserPreferenceChanged += new UserPreferenceChangedEventHandler(this.OnUserPreferenceChanged); }
private const string ToolboxFormat = ".NET Toolbox Item"; // used to detect if a drag is coming from the toolbox. internal BehaviorService(IServiceProvider serviceProvider, Control windowFrame) { _serviceProvider = serviceProvider; _adornerWindow = new AdornerWindow(this, windowFrame); // Use the adornerWindow as an overlay IOverlayService os = (IOverlayService)serviceProvider.GetService(typeof(IOverlayService)); if (os != null) { AdornerWindowIndex = os.PushOverlay(_adornerWindow); } _dragEnterReplies = new Hashtable(); // Start with an empty adorner collection & no behavior on the stack Adorners = new BehaviorServiceAdornerCollection(this); _behaviorStack = new ArrayList(); _hitTestedGlyph = null; _validDragArgs = null; DesignerActionUI = null; _trackMouseEvent = default; _trackingMouseEvent = false; // Create out object that will handle all menucommands if (serviceProvider.GetService(typeof(IMenuCommandService)) is IMenuCommandService menuCommandService && serviceProvider.GetService(typeof(IDesignerHost)) is IDesignerHost host) { _menuCommandHandler = new MenuCommandHandler(this, menuCommandService); host.RemoveService(typeof(IMenuCommandService)); host.AddService(typeof(IMenuCommandService), _menuCommandHandler); } // Default layoutmode is SnapToGrid. _useSnapLines = false; _queriedSnapLines = false; // Test hooks WM_GETALLSNAPLINES = User32.RegisterWindowMessageW("WM_GETALLSNAPLINES"); WM_GETRECENTSNAPLINES = User32.RegisterWindowMessageW("WM_GETRECENTSNAPLINES"); // Listen to the SystemEvents so that we can resync selection based on display settings etc. SystemEvents.UserPreferenceChanged += new UserPreferenceChangedEventHandler(OnUserPreferenceChanged); }
private unsafe IntPtr MouseHookProc(User32.HC nCode, IntPtr wparam, IntPtr lparam) { if (_isHooked && nCode == User32.HC.ACTION && lparam != IntPtr.Zero) { User32.MOUSEHOOKSTRUCT *mhs = (User32.MOUSEHOOKSTRUCT *)lparam; try { if (ProcessMouseMessage(mhs->hWnd, unchecked ((int)(long)wparam), mhs->pt.X, mhs->pt.Y)) { return((IntPtr)1); } } catch (Exception ex) { _currentAdornerWindow.Capture = false; if (ex != CheckoutException.Canceled) { _currentAdornerWindow._behaviorService.ShowError(ex); } if (ClientUtils.IsCriticalException(ex)) { throw; } } finally { _currentAdornerWindow = null; } } Debug.Assert(_isHooked, "How did we get here when we are disposed?"); return(User32.CallNextHookEx(new HandleRef(this, _mouseHookHandle), nCode, wparam, lparam)); }
private bool ProcessMouseMessage(IntPtr hWnd, int msg, int x, int y) { if (_processingMessage) { return(false); } foreach (AdornerWindow adornerWindow in s_adornerWindowList) { if (!adornerWindow.DesignerFrameValid) { continue; } _currentAdornerWindow = adornerWindow; IntPtr handle = adornerWindow.DesignerFrame.Handle; // If it's us or one of our children, just process as normal if (adornerWindow.ProcessingDrag || (hWnd != handle && User32.IsChild(new HandleRef(this, handle), hWnd).IsTrue())) { Debug.Assert(_thisProcessID != 0, "Didn't get our process id!"); // Make sure the window is in our process User32.GetWindowThreadProcessId(hWnd, out uint pid); // If this isn't our process, bail if (pid != _thisProcessID) { return(false); } try { _processingMessage = true; var pt = new Point(x, y); User32.MapWindowPoints(IntPtr.Zero, adornerWindow.Handle, ref pt, 1); Message m = Message.Create(hWnd, msg, (IntPtr)0, PARAM.FromLowHigh(pt.Y, pt.X)); // No one knows why we get an extra click here from VS. As a workaround, we check the TimeStamp and discard it. if (m.Msg == (int)User32.WM.LBUTTONDOWN) { _lastLButtonDownTimeStamp = User32.GetMessageTime(); } else if (m.Msg == (int)User32.WM.LBUTTONDBLCLK) { int lButtonDoubleClickTimeStamp = User32.GetMessageTime(); if (lButtonDoubleClickTimeStamp == _lastLButtonDownTimeStamp) { return(true); } } if (!adornerWindow.WndProcProxy(ref m, pt.X, pt.Y)) { // We did the work, stop the message propagation return(true); } } finally { _processingMessage = false; } // No need to enumerate the other adorner windows since only one can be focused at a time. break; } } return(false); }