/// <summary> /// Used to intercept windows messages for our background form so that we can send events /// back to the main form. Because the background form is Disabled (so that it cannot receive focus) /// we only actually get one message WM_SETCURSOR, which actually gives us all the information on /// what the mouse is doing at the time, so we can use that to fire off events on the main form that /// we are missing out on because its background is transparent. /// </summary> /// <param name="hWnd"></param> /// <param name="Msg"></param> /// <param name="wParam"></param> /// <param name="lParam"></param> /// <returns></returns> private int LayeredWindowWndProc(IntPtr hWnd, int Msg, int wParam, int lParam) { Point mousePos = this.PointToClient(System.Windows.Forms.Cursor.Position); Win32.Message msgId = (Win32.Message)Msg; switch (msgId) { case Win32.Message.WM_LBUTTONDOWN: System.Diagnostics.Debugger.Break(); break; case Win32.Message.WM_SETCURSOR: { //Set the cursor, we need to do this ourselves because we are not letting this message through Win32.SetCursor(Win32.LoadCursor(IntPtr.Zero, Win32.SystemCursor.IDC_NORMAL)); MouseEventArgs e = null; delMouseEvent mouseEvent = null; delStdEvent stdEvent = null; //The low word of the lParam contains the hit test code, which we don't //need to know, we only need to know what the mouse is doing Win32.Message MouseEvent = (Win32.Message)(lParam >> 16); switch (MouseEvent) { case Win32.Message.WM_MOUSEMOVE: { if (m_isDown.Left && m_lockedPoint != mousePos) { //We are using the trick of sending the WM_NCLBUTTONDOWN message to make Windows drag our form //around, I'm not entirely certain how Windows works but our main form needs to have been the last //window with mouse capture for it to work, even thought it is necessary to ReleaseCapture prior //to sending the message System.Diagnostics.Debug.WriteLine("Setting Capture"); Win32.SetCapture(this.Handle); m_moving = true; } else { e = new MouseEventArgs(System.Windows.Forms.MouseButtons.None, 0, mousePos.X, mousePos.Y, 0); mouseEvent = new delMouseEvent(this.OnMouseMove); } } break; case Win32.Message.WM_LBUTTONDOWN: if (m_lastClickMsg == MouseEvent && !m_isDown.Left && dblClick(mousePos)) { e = new MouseEventArgs(System.Windows.Forms.MouseButtons.Left, 2, mousePos.X, mousePos.Y, 0); mouseEvent = new delMouseEvent(this.OnMouseDoubleClick); stdEvent = new delStdEvent(this.OnDoubleClick); m_lastClickMsg = 0; } else if (!m_isDown.Left) { e = new MouseEventArgs(System.Windows.Forms.MouseButtons.Left, 1, mousePos.X, mousePos.Y, 0); mouseEvent = new delMouseEvent(this.OnMouseDown); m_lastClickMsg = MouseEvent; } m_clickTime = DateTime.Now; m_lockedPoint = mousePos; m_isDown.Left = true; break; case Win32.Message.WM_LBUTTONUP: { e = new MouseEventArgs(System.Windows.Forms.MouseButtons.Left, 1, mousePos.X, mousePos.Y, 0); mouseEvent = new delMouseEvent(this.OnMouseClick); stdEvent = new delStdEvent(this.OnClick); m_isDown.Left = false; } break; case Win32.Message.WM_MBUTTONDOWN: if (m_lastClickMsg == MouseEvent && !m_isDown.Middle && dblClick(mousePos)) { e = new MouseEventArgs(System.Windows.Forms.MouseButtons.Middle, 2, mousePos.X, mousePos.Y, 0); mouseEvent = new delMouseEvent(this.OnMouseDoubleClick); stdEvent = new delStdEvent(this.OnDoubleClick); m_lastClickMsg = 0; } else if (!m_isDown.Middle) { e = new MouseEventArgs(System.Windows.Forms.MouseButtons.Middle, 1, mousePos.X, mousePos.Y, 0); mouseEvent = new delMouseEvent(this.OnMouseDown); m_lastClickMsg = MouseEvent; m_clickTime = DateTime.Now; m_lockedPoint = mousePos; } m_isDown.Middle = true; break; case Win32.Message.WM_MBUTTONUP: { e = new MouseEventArgs(System.Windows.Forms.MouseButtons.Middle, 1, mousePos.X, mousePos.Y, 0); mouseEvent = new delMouseEvent(this.OnMouseClick); stdEvent = new delStdEvent(this.OnClick); m_isDown.Middle = false; } break; case Win32.Message.WM_RBUTTONDOWN: if (m_lastClickMsg == MouseEvent && !m_isDown.Right && dblClick(mousePos)) { e = new MouseEventArgs(System.Windows.Forms.MouseButtons.Right, 2, mousePos.X, mousePos.Y, 0); mouseEvent = new delMouseEvent(this.OnMouseDoubleClick); stdEvent = new delStdEvent(this.OnDoubleClick); m_lastClickMsg = 0; } else if (!m_isDown.Right) { e = new MouseEventArgs(System.Windows.Forms.MouseButtons.Right, 1, mousePos.X, mousePos.Y, 0); mouseEvent = new delMouseEvent(this.OnMouseDown); m_lastClickMsg = MouseEvent; m_clickTime = DateTime.Now; m_lockedPoint = mousePos; } m_isDown.Right = true; break; case Win32.Message.WM_RBUTTONUP: { e = new MouseEventArgs(System.Windows.Forms.MouseButtons.Right, 1, mousePos.X, mousePos.Y, 0); mouseEvent = new delMouseEvent(this.OnMouseClick); stdEvent = new delStdEvent(this.OnClick); m_isDown.Right = false; } break; case Win32.Message.WM_XBUTTONDOWN: if (m_lastClickMsg == MouseEvent && !m_isDown.XBtn && dblClick(mousePos)) { e = new MouseEventArgs(System.Windows.Forms.MouseButtons.XButton1, 2, mousePos.X, mousePos.Y, 0); mouseEvent = new delMouseEvent(this.OnMouseDoubleClick); stdEvent = new delStdEvent(this.OnDoubleClick); m_lastClickMsg = 0; } else if (!m_isDown.XBtn) { e = new MouseEventArgs(System.Windows.Forms.MouseButtons.XButton1, 1, mousePos.X, mousePos.Y, 0); mouseEvent = new delMouseEvent(this.OnMouseDown); m_lastClickMsg = MouseEvent; m_clickTime = DateTime.Now; m_lockedPoint = mousePos; } m_isDown.XBtn = true; break; case Win32.Message.WM_XBUTTONUP: { e = new MouseEventArgs(System.Windows.Forms.MouseButtons.XButton1, 1, mousePos.X, mousePos.Y, 0); mouseEvent = new delMouseEvent(this.OnMouseClick); stdEvent = new delStdEvent(this.OnClick); m_isDown.XBtn = false; } break; } //Check if the form is being clicked, but is not active bool mouseDown = m_isDown.Left || m_isDown.Middle || m_isDown.Right || m_isDown.XBtn; if (mouseDown && Form.ActiveForm == null) { //We need to give our form focus this.Activate(); } if (e != null) { if (mouseEvent != null) this.BeginInvoke(mouseEvent, e); if (stdEvent != null) this.BeginInvoke(stdEvent, e); } return 0; } } return Win32.CallWindowProc(m_layeredWindowProc, hWnd, Msg, wParam, lParam); }
/// <summary> /// Used to intercept windows messages for our background form so that we can send events /// back to the main form. Because the background form is Disabled (so that it cannot receive focus) /// we only actually get one message WM_SETCURSOR, which actually gives us all the information on /// what the mouse is doing at the time, so we can use that to fire off events on the main form that /// we are missing out on because its background is transparent. /// </summary> /// <param name="hWnd"></param> /// <param name="Msg"></param> /// <param name="wParam"></param> /// <param name="lParam"></param> /// <returns></returns> private int LayeredWindowWndProc(IntPtr hWnd, int Msg, int wParam, int lParam) { Point mousePos = this.PointToClient(System.Windows.Forms.Cursor.Position); Win32.Message msgId = (Win32.Message)Msg; switch (msgId) { case Win32.Message.WM_LBUTTONDOWN: System.Diagnostics.Debugger.Break(); break; case Win32.Message.WM_SETCURSOR: { //Set the cursor, we need to do this ourselves because we are not letting this message through Win32.SetCursor(Win32.LoadCursor(IntPtr.Zero, Win32.SystemCursor.IDC_NORMAL)); MouseEventArgs e = null; delMouseEvent mouseEvent = null; delStdEvent stdEvent = null; //The low word of the lParam contains the hit test code, which we don't //need to know, we only need to know what the mouse is doing Win32.Message MouseEvent = (Win32.Message)(lParam >> 16); switch (MouseEvent) { case Win32.Message.WM_MOUSEMOVE: { if (m_isDown.Left && m_lockedPoint != mousePos) { //We are using the trick of sending the WM_NCLBUTTONDOWN message to make Windows drag our form //around, I'm not entirely certain how Windows works but our main form needs to have been the last //window with mouse capture for it to work, even thought it is necessary to ReleaseCapture prior //to sending the message System.Diagnostics.Debug.WriteLine("Setting Capture"); Win32.SetCapture(this.Handle); m_moving = true; } else { e = new MouseEventArgs(System.Windows.Forms.MouseButtons.None, 0, mousePos.X, mousePos.Y, 0); mouseEvent = new delMouseEvent(this.OnMouseMove); } } break; case Win32.Message.WM_LBUTTONDOWN: if (m_lastClickMsg == MouseEvent && !m_isDown.Left && dblClick(mousePos)) { e = new MouseEventArgs(System.Windows.Forms.MouseButtons.Left, 2, mousePos.X, mousePos.Y, 0); mouseEvent = new delMouseEvent(this.OnMouseDoubleClick); stdEvent = new delStdEvent(this.OnDoubleClick); m_lastClickMsg = 0; } else if (!m_isDown.Left) { e = new MouseEventArgs(System.Windows.Forms.MouseButtons.Left, 1, mousePos.X, mousePos.Y, 0); mouseEvent = new delMouseEvent(this.OnMouseDown); m_lastClickMsg = MouseEvent; } m_clickTime = DateTime.Now; m_lockedPoint = mousePos; m_isDown.Left = true; break; case Win32.Message.WM_LBUTTONUP: { e = new MouseEventArgs(System.Windows.Forms.MouseButtons.Left, 1, mousePos.X, mousePos.Y, 0); mouseEvent = new delMouseEvent(this.OnMouseClick); stdEvent = new delStdEvent(this.OnClick); m_isDown.Left = false; } break; case Win32.Message.WM_MBUTTONDOWN: if (m_lastClickMsg == MouseEvent && !m_isDown.Middle && dblClick(mousePos)) { e = new MouseEventArgs(System.Windows.Forms.MouseButtons.Middle, 2, mousePos.X, mousePos.Y, 0); mouseEvent = new delMouseEvent(this.OnMouseDoubleClick); stdEvent = new delStdEvent(this.OnDoubleClick); m_lastClickMsg = 0; } else if (!m_isDown.Middle) { e = new MouseEventArgs(System.Windows.Forms.MouseButtons.Middle, 1, mousePos.X, mousePos.Y, 0); mouseEvent = new delMouseEvent(this.OnMouseDown); m_lastClickMsg = MouseEvent; m_clickTime = DateTime.Now; m_lockedPoint = mousePos; } m_isDown.Middle = true; break; case Win32.Message.WM_MBUTTONUP: { e = new MouseEventArgs(System.Windows.Forms.MouseButtons.Middle, 1, mousePos.X, mousePos.Y, 0); mouseEvent = new delMouseEvent(this.OnMouseClick); stdEvent = new delStdEvent(this.OnClick); m_isDown.Middle = false; } break; case Win32.Message.WM_RBUTTONDOWN: if (m_lastClickMsg == MouseEvent && !m_isDown.Right && dblClick(mousePos)) { e = new MouseEventArgs(System.Windows.Forms.MouseButtons.Right, 2, mousePos.X, mousePos.Y, 0); mouseEvent = new delMouseEvent(this.OnMouseDoubleClick); stdEvent = new delStdEvent(this.OnDoubleClick); m_lastClickMsg = 0; } else if (!m_isDown.Right) { e = new MouseEventArgs(System.Windows.Forms.MouseButtons.Right, 1, mousePos.X, mousePos.Y, 0); mouseEvent = new delMouseEvent(this.OnMouseDown); m_lastClickMsg = MouseEvent; m_clickTime = DateTime.Now; m_lockedPoint = mousePos; } m_isDown.Right = true; break; case Win32.Message.WM_RBUTTONUP: { e = new MouseEventArgs(System.Windows.Forms.MouseButtons.Right, 1, mousePos.X, mousePos.Y, 0); mouseEvent = new delMouseEvent(this.OnMouseClick); stdEvent = new delStdEvent(this.OnClick); m_isDown.Right = false; } break; case Win32.Message.WM_XBUTTONDOWN: if (m_lastClickMsg == MouseEvent && !m_isDown.XBtn && dblClick(mousePos)) { e = new MouseEventArgs(System.Windows.Forms.MouseButtons.XButton1, 2, mousePos.X, mousePos.Y, 0); mouseEvent = new delMouseEvent(this.OnMouseDoubleClick); stdEvent = new delStdEvent(this.OnDoubleClick); m_lastClickMsg = 0; } else if (!m_isDown.XBtn) { e = new MouseEventArgs(System.Windows.Forms.MouseButtons.XButton1, 1, mousePos.X, mousePos.Y, 0); mouseEvent = new delMouseEvent(this.OnMouseDown); m_lastClickMsg = MouseEvent; m_clickTime = DateTime.Now; m_lockedPoint = mousePos; } m_isDown.XBtn = true; break; case Win32.Message.WM_XBUTTONUP: { e = new MouseEventArgs(System.Windows.Forms.MouseButtons.XButton1, 1, mousePos.X, mousePos.Y, 0); mouseEvent = new delMouseEvent(this.OnMouseClick); stdEvent = new delStdEvent(this.OnClick); m_isDown.XBtn = false; } break; } //Check if the form is being clicked, but is not active bool mouseDown = m_isDown.Left || m_isDown.Middle || m_isDown.Right || m_isDown.XBtn; if (mouseDown && Form.ActiveForm == null) { //We need to give our form focus this.Activate(); } if (e != null) { if (mouseEvent != null) { this.BeginInvoke(mouseEvent, e); } if (stdEvent != null) { this.BeginInvoke(stdEvent, e); } } return(0); } } return(Win32.CallWindowProc(m_layeredWindowProc, hWnd, Msg, wParam, lParam)); }
private int LayeredWindowWndProc(IntPtr hWnd, int Msg, int wParam, int lParam) { Point mousePos = this.PointToClient(System.Windows.Forms.Cursor.Position); Win32.Message msgId = (Win32.Message)Msg; switch (msgId) { case Win32.Message.WM_LBUTTONDOWN: System.Diagnostics.Debugger.Break(); break; case Win32.Message.WM_SETCURSOR: { Win32.SetCursor(Win32.LoadCursor(IntPtr.Zero, Win32.SystemCursor.IDC_NORMAL)); MouseEventArgs e = null; delMouseEvent mouseEvent = null; delStdEvent stdEvent = null; Win32.Message MouseEvent = (Win32.Message)(lParam >> 16); switch (MouseEvent) { case Win32.Message.WM_MOUSEMOVE: { if (m_isDown.Left && m_lockedPoint != mousePos) { System.Diagnostics.Debug.WriteLine("Setting Capture"); Win32.SetCapture(this.Handle); m_moving = true; } else { e = new MouseEventArgs(System.Windows.Forms.MouseButtons.None, 0, mousePos.X, mousePos.Y, 0); mouseEvent = new delMouseEvent(this.OnMouseMove); } } break; case Win32.Message.WM_LBUTTONDOWN: if (m_lastClickMsg == MouseEvent && !m_isDown.Left && dblClick(mousePos)) { e = new MouseEventArgs(System.Windows.Forms.MouseButtons.Left, 2, mousePos.X, mousePos.Y, 0); mouseEvent = new delMouseEvent(this.OnMouseDoubleClick); stdEvent = new delStdEvent(this.OnDoubleClick); m_lastClickMsg = 0; } else if (!m_isDown.Left) { e = new MouseEventArgs(System.Windows.Forms.MouseButtons.Left, 1, mousePos.X, mousePos.Y, 0); mouseEvent = new delMouseEvent(this.OnMouseDown); m_lastClickMsg = MouseEvent; } m_clickTime = DateTime.Now; m_lockedPoint = mousePos; m_isDown.Left = true; break; case Win32.Message.WM_LBUTTONUP: { e = new MouseEventArgs(System.Windows.Forms.MouseButtons.Left, 1, mousePos.X, mousePos.Y, 0); mouseEvent = new delMouseEvent(this.OnMouseClick); stdEvent = new delStdEvent(this.OnClick); m_isDown.Left = false; } break; case Win32.Message.WM_MBUTTONDOWN: if (m_lastClickMsg == MouseEvent && !m_isDown.Middle && dblClick(mousePos)) { e = new MouseEventArgs(System.Windows.Forms.MouseButtons.Middle, 2, mousePos.X, mousePos.Y, 0); mouseEvent = new delMouseEvent(this.OnMouseDoubleClick); stdEvent = new delStdEvent(this.OnDoubleClick); m_lastClickMsg = 0; } else if (!m_isDown.Middle) { e = new MouseEventArgs(System.Windows.Forms.MouseButtons.Middle, 1, mousePos.X, mousePos.Y, 0); mouseEvent = new delMouseEvent(this.OnMouseDown); m_lastClickMsg = MouseEvent; m_clickTime = DateTime.Now; m_lockedPoint = mousePos; } m_isDown.Middle = true; break; case Win32.Message.WM_MBUTTONUP: { e = new MouseEventArgs(System.Windows.Forms.MouseButtons.Middle, 1, mousePos.X, mousePos.Y, 0); mouseEvent = new delMouseEvent(this.OnMouseClick); stdEvent = new delStdEvent(this.OnClick); m_isDown.Middle = false; } break; case Win32.Message.WM_RBUTTONDOWN: if (m_lastClickMsg == MouseEvent && !m_isDown.Right && dblClick(mousePos)) { e = new MouseEventArgs(System.Windows.Forms.MouseButtons.Right, 2, mousePos.X, mousePos.Y, 0); mouseEvent = new delMouseEvent(this.OnMouseDoubleClick); stdEvent = new delStdEvent(this.OnDoubleClick); m_lastClickMsg = 0; } else if (!m_isDown.Right) { e = new MouseEventArgs(System.Windows.Forms.MouseButtons.Right, 1, mousePos.X, mousePos.Y, 0); mouseEvent = new delMouseEvent(this.OnMouseDown); m_lastClickMsg = MouseEvent; m_clickTime = DateTime.Now; m_lockedPoint = mousePos; } m_isDown.Right = true; break; case Win32.Message.WM_RBUTTONUP: { e = new MouseEventArgs(System.Windows.Forms.MouseButtons.Right, 1, mousePos.X, mousePos.Y, 0); mouseEvent = new delMouseEvent(this.OnMouseClick); stdEvent = new delStdEvent(this.OnClick); m_isDown.Right = false; } break; case Win32.Message.WM_XBUTTONDOWN: if (m_lastClickMsg == MouseEvent && !m_isDown.XBtn && dblClick(mousePos)) { e = new MouseEventArgs(System.Windows.Forms.MouseButtons.XButton1, 2, mousePos.X, mousePos.Y, 0); mouseEvent = new delMouseEvent(this.OnMouseDoubleClick); stdEvent = new delStdEvent(this.OnDoubleClick); m_lastClickMsg = 0; } else if (!m_isDown.XBtn) { e = new MouseEventArgs(System.Windows.Forms.MouseButtons.XButton1, 1, mousePos.X, mousePos.Y, 0); mouseEvent = new delMouseEvent(this.OnMouseDown); m_lastClickMsg = MouseEvent; m_clickTime = DateTime.Now; m_lockedPoint = mousePos; } m_isDown.XBtn = true; break; case Win32.Message.WM_XBUTTONUP: { e = new MouseEventArgs(System.Windows.Forms.MouseButtons.XButton1, 1, mousePos.X, mousePos.Y, 0); mouseEvent = new delMouseEvent(this.OnMouseClick); stdEvent = new delStdEvent(this.OnClick); m_isDown.XBtn = false; } break; } bool mouseDown = m_isDown.Left || m_isDown.Middle || m_isDown.Right || m_isDown.XBtn; if (mouseDown && Form.ActiveForm == null) { this.Activate(); } if (e != null) { if (mouseEvent != null) { this.BeginInvoke(mouseEvent, e); } if (stdEvent != null) { this.BeginInvoke(stdEvent, e); } } return(0); } } return(Win32.CallWindowProc(m_layeredWindowProc, hWnd, Msg, wParam, lParam)); }