예제 #1
0
        protected override void WndProc(ref Message m)
        {
            if (DesignMode)
            {
                base.WndProc(ref m);
                return;
            }

            switch ((Window.Msg)m.Msg)
            {
            case Window.Msg.WM_NCCALCSIZE:

                // Check WPARAM
                if (m.WParam != IntPtr.Zero)
                {
                    // When TRUE, LPARAM Points to a NCCALCSIZE_PARAMS structure
                    var nccsp = (WinApi.NCCALCSIZE_PARAMS)Marshal.PtrToStructure(m.LParam, typeof(WinApi.NCCALCSIZE_PARAMS));
                    ApplyPreferedSize(_preferedSize, nccsp.rectProposed.Size);
                    AdjustClientArea(ref nccsp.rectProposed);
                    Marshal.StructureToPtr(nccsp, m.LParam, true);
                }
                else
                {
                    // When FALSE, LPARAM Points to a RECT structure
                    var clnRect = (WinApi.RECT)Marshal.PtrToStructure(m.LParam, typeof(WinApi.RECT));
                    ApplyPreferedSize(_preferedSize, clnRect.Size);
                    AdjustClientArea(ref clnRect);
                    Marshal.StructureToPtr(clnRect, m.LParam, true);
                }

                //Return Zero
                m.Result = IntPtr.Zero;
                break;

            case Window.Msg.WM_NCPAINT:
                PaintScrollBars(null);
                // we handled everything
                m.Result = IntPtr.Zero;
                break;

            case Window.Msg.WM_NCHITTEST:
                // we need to correctly handle this if we want the non client area events (WM_NC*) to fire properly!
                var point = PointToClient(new Point(m.LParam.ToInt32()));
                if (!ClientRectangle.Contains(point))
                {
                    m.Result = (IntPtr)WinApi.HitTest.HTBORDER;
                }
                else
                {
                    base.WndProc(ref m);
                }

                break;

            case Window.Msg.WM_MOUSEWHEEL:
                if (HasScroll)
                {
                    // delta negative when scrolling up
                    var delta       = (short)(m.WParam.ToInt64() >> 16);
                    var mouseEvent1 = new MouseEventArgs(MouseButtons.None, 0, 0, 0, delta);
                    if (HorizontalScroll.IsHovered)
                    {
                        HorizontalScroll.HandleScroll(null, mouseEvent1);
                    }
                    else
                    {
                        VerticalScroll.HandleScroll(null, mouseEvent1);
                    }
                }
                else
                {
                    // propagate the event
                    base.WndProc(ref m);
                }

                break;

            case Window.Msg.WM_MOUSEMOVE:
                if (VerticalScroll.IsThumbPressed)
                {
                    VerticalScroll.HandleMouseMove(null, null);
                }
                if (HorizontalScroll.IsThumbPressed)
                {
                    HorizontalScroll.HandleMouseMove(null, null);
                }
                base.WndProc(ref m);
                break;

            case Window.Msg.WM_NCMOUSEMOVE:
                // track mouse leaving (otherwise the WM_NCMOUSELEAVE message would not fire)
                WinApi.TRACKMOUSEEVENT tme = new WinApi.TRACKMOUSEEVENT();
                tme.cbSize    = (uint)Marshal.SizeOf(tme);
                tme.dwFlags   = (uint)(WinApi.TMEFlags.TME_LEAVE | WinApi.TMEFlags.TME_NONCLIENT);
                tme.hwndTrack = Handle;
                WinApi.TrackMouseEvent(tme);

                // PointToClient(new Point(m.LParam.ToInt32()));
                VerticalScroll.HandleMouseMove(null, null);
                HorizontalScroll.HandleMouseMove(null, null);
                base.WndProc(ref m);
                break;

            case Window.Msg.WM_NCLBUTTONDOWN:
                VerticalScroll.HandleMouseDown(null, null);
                HorizontalScroll.HandleMouseDown(null, null);
                Focus();
                // here we forward to base button down because it has a internal focus mecanism that we want to exploit
                // if we don't do that, the mouse MOVE events are not fired outside the bounds of this control!
                m.Msg = (int)Window.Msg.WM_LBUTTONDOWN;
                base.WndProc(ref m);
                break;

            case Window.Msg.WM_NCLBUTTONUP:
            case Window.Msg.WM_LBUTTONUP:
                VerticalScroll.HandleMouseUp(null, null);
                HorizontalScroll.HandleMouseUp(null, null);
                // here we forward this message to base WM_LBUTTONUP to release the internal focus on this control
                m.Msg = (int)Window.Msg.WM_LBUTTONUP;
                base.WndProc(ref m);
                break;

            case Window.Msg.WM_NCMOUSELEAVE:
                VerticalScroll.HandleMouseLeave(null, null);
                HorizontalScroll.HandleMouseLeave(null, null);
                base.WndProc(ref m);
                break;

            default:
                base.WndProc(ref m);
                break;
            }
        }
        protected override void WndProc(ref Message m)
        {
            if (DesignMode)
            {
                base.WndProc(ref m);
                return;
            }

            switch ((Window.Msg)m.Msg)
            {
            case Window.Msg.WM_NCCALCSIZE:

                // Check WPARAM
                if (m.WParam != IntPtr.Zero)
                {
                    // When TRUE, LPARAM Points to a NCCALCSIZE_PARAMS structure
                    var nccsp = (WinApi.NCCALCSIZE_PARAMS)Marshal.PtrToStructure(m.LParam, typeof(WinApi.NCCALCSIZE_PARAMS));
                    if (!nccsp.rectProposed.Size.IsEmpty)
                    {
                        // we are not in this case when the form is minimized
                        //OnSizeChanged(nccsp.rectProposed.Size);
                    }

                    AdjustClientArea(ref nccsp.rectProposed);
                    Marshal.StructureToPtr(nccsp, m.LParam, true);
                }
                else
                {
                    // When FALSE, LPARAM Points to a RECT structure
                    var clnRect = (WinApi.RECT)Marshal.PtrToStructure(m.LParam, typeof(WinApi.RECT));
                    if (!clnRect.Size.IsEmpty)
                    {
                        // we are not in this case when the form is minimized
                        //OnSizeChanged(clnRect.Size);
                    }

                    AdjustClientArea(ref clnRect);
                    Marshal.StructureToPtr(clnRect, m.LParam, true);
                }

                //Return Zero
                m.Result = IntPtr.Zero;
                break;

            case Window.Msg.WM_MOUSEWHEEL:
                if (HasScroll)
                {
                    // delta negative when scrolling up
                    var delta       = (short)(m.WParam.ToInt64() >> 16);
                    var mouseEvent1 = new MouseEventArgs(MouseButtons.None, 0, 0, 0, delta);
                    if (HorizontalScroll.IsHovered)
                    {
                        HorizontalScroll.HandleScroll(null, mouseEvent1);
                    }
                    else
                    {
                        VerticalScroll.HandleScroll(null, mouseEvent1);
                    }
                }
                else
                {
                    // propagate the event
                    base.WndProc(ref m);
                }

                break;

            /*
             * case Window.Msg.WM_KEYDOWN:
             *  // needto override OnPreviewKeyDown or IsInputKey to receive this
             *  var key = (Keys) (m.WParam.ToInt64());
             *  long context = m.LParam.ToInt64();
             *
             *  // on key down
             *  if (!context.IsBitSet(31)) {
             *      var e = new KeyEventArgs(key);
             *      e.Handled = PerformKeyDown(e);
             *      if (!e.Handled)
             *          base.WndProc(ref m);
             *  }
             *
             *  break;
             */
            case Window.Msg.WM_NCPAINT:
                m.Result = IntPtr.Zero;
                break;

            case Window.Msg.WM_ERASEBKGND:
                m.Result = IntPtr.Zero;
                return;

            default:
                base.WndProc(ref m);
                break;
            }
        }