Beispiel #1
0
                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);
 }
Beispiel #3
0
        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);
        }
Beispiel #4
0
                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));
                }
Beispiel #5
0
                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);
                }