/// <summary> /// Processes Windows messages. /// </summary> /// <param name="m">The Windows Message to process. </param> protected override void WndProc(ref Message m) { switch (m.Msg) { case PI.WM_NCLBUTTONDOWN: { // Perform a hit test to determine which area the mouse press is over at the moment uint result = PI.SendMessage(this.Handle, (int)PI.WM_NCHITTEST, 0, (uint)m.LParam); // Only want to override the behaviour of moving the window via the caption bar if (result == PI.HITTEST_CAPTION) { // Extract screen position of the mouse from the message LPARAM Point screenPos = new Point((short)((uint)m.LParam & 0x0000FFFFU), (short)(uint)(((uint)m.LParam & 0xFFFF0000U) >> 16)); // Find the mouse offset relative to the top left of the window Point offset = new Point(screenPos.X - Location.X, screenPos.Y - Location.Y); // Do not intercept message if inside the max/close buttons if (!HitTestMaxButton(offset) && !HitTestCloseButton(offset)) { // Capture the mouse until the mouse us is received and gain focus so we look active Capture = true; Activate(); // Use event to notify the request to drag the window OnWindowCaptionDragging(new ScreenAndOffsetEventArgs(screenPos, offset)); // Eat the message! return; } } } break; case PI.WM_KEYDOWN: base.WndProc(ref m); if (_floatingMessages != null) { _floatingMessages.OnKEYDOWN(ref m); } return; case PI.WM_MOUSEMOVE: base.WndProc(ref m); if (_floatingMessages != null) { _floatingMessages.OnMOUSEMOVE(); } return; case PI.WM_LBUTTONUP: base.WndProc(ref m); if (_floatingMessages != null) { _floatingMessages.OnLBUTTONUP(); } return; } base.WndProc(ref m); }
public bool PreFilterMessage(ref Message m) { switch (m.Msg) { case PI.WM_MOUSELEAVE: // Only interested in the mouse leave if it relates to the floating window and so ignore any // message that comes from the mouse leaving the source of a drag such as a docked window or // a workspace/navigator tab. if (m.HWnd == FloatingWindow.Handle) { // If mouse has left then we need to finish with docking. Most likely reason is the focus // has been shifted to another application with ALT+TAB. DragEnd(Control.MousePosition); Dispose(); } break; case PI.WM_KEYDOWN: { // Extract the keys being pressed Keys keys = ((Keys)((int)m.WParam.ToInt64())); // Pressing escape ends dragging if (keys == Keys.Escape) { DragQuit(); Dispose(); } return(true); } case PI.WM_SYSKEYDOWN: { // Extract the keys being pressed Keys keys = ((Keys)((int)m.WParam.ToInt64())); // Pressing ALT+TAB ends dragging because user is moving to another app if (PI.IsKeyDown(Keys.Tab) && ((Control.ModifierKeys & Keys.Alt) == Keys.Alt)) { DragQuit(); Dispose(); } break; } case PI.WM_MOUSEMOVE: if (_monitorMouse) { // Update feedback to reflect the current mouse position DragMove(Control.MousePosition); } break; case PI.WM_LBUTTONUP: if (_monitorMouse) { DragEnd(Control.MousePosition); Dispose(); } break; } return(false); }
public bool PreFilterMessage(ref Message msg) { Form parentForm = this.FindForm(); Form parentMdi = (parentForm != null ? parentForm.MdiParent : null); // Only interested in snooping messages if.... // The Form we are inside is the active form AND // If an MDI Child Form then we must be the active MDI Child Form AND // We are not in the hidden state AND // We have an associated auto hidden group control that is not disposed AND // We are not disposed if ((parentForm != null) && ((parentForm == Form.ActiveForm) || (parentMdi != null && parentMdi.ActiveMdiChild == parentForm)) && parentForm.ContainsFocus && (_state != DockingAutoHiddenShowState.Hidden) && (_group != null) && !_group.IsDisposed && !IsDisposed) { switch (msg.Msg) { case PI.WM_KEYDOWN: // Pressing escape removes the auto hidden window if ((int)msg.WParam == PI.VK_ESCAPE) { MakeHidden(); return(true); } break; case PI.WM_MOUSELEAVE: // If the mouse is leaving a control then we start the dismiss timer so that a mouse move is required // to cancel the mouse move and prevent the actual dismissal occuring. The exception to this is if the // slide out dockspace has the focus, in which case we do nothing. if (!_dismissRunning && !DockspaceControl.ContainsFocus) { _dismissTimer.Stop(); _dismissTimer.Start(); _dismissRunning = true; } break; case PI.WM_MOUSEMOVE: // Convert the mouse position into a screen location Point screenPt = CommonHelper.ClientMouseMessageToScreenPt(msg); // Is the mouse over ourself or over the associated auto hiiden group if (RectangleToScreen(ClientRectangle).Contains(screenPt) || _group.RectangleToScreen(_group.ClientRectangle).Contains(screenPt)) { // We do not dismiss while the mouse is over ourself if (_dismissRunning) { _dismissTimer.Stop(); _dismissRunning = false; } } else { // When mouse not over a relevant area we need to start the dismiss process // unless the slide out dockspace has the focus, in which case we do nothing. if (!_dismissRunning && !DockspaceControl.ContainsFocus) { _dismissTimer.Stop(); _dismissTimer.Start(); _dismissRunning = true; } } // If first message for this window then need to track to get the mouse leave if (_mouseTrackWindow != msg.HWnd) { _mouseTrackWindow = msg.HWnd; // This structure needs to know its own size in bytes PI.TRACKMOUSEEVENTS tme = new PI.TRACKMOUSEEVENTS(); tme.cbSize = (uint)Marshal.SizeOf(typeof(PI.TRACKMOUSEEVENTS)); tme.dwHoverTime = 100; tme.dwFlags = (int)(PI.TME_LEAVE); tme.hWnd = Handle; // Call Win32 API to start tracking PI.TrackMouseEvent(ref tme); } break; } } return(false); }