private void NCCalcSize(ref Message m) { if (m.WParam == IntPtr.Zero) { WinApi.RECT ncRect = (WinApi.RECT)m.GetLParam(typeof(WinApi.RECT)); Rectangle proposed = ncRect.Rect; CalcSizeNCRectangle(ref proposed); ncRect.Rect = proposed; Marshal.StructureToPtr(ncRect, m.LParam, false); m.Result = IntPtr.Zero; } else if (m.WParam != IntPtr.Zero) { WinApi.NCCALCSIZE_PARAMS ncParams = (WinApi.NCCALCSIZE_PARAMS)m.GetLParam(typeof(WinApi.NCCALCSIZE_PARAMS)); Rectangle proposed = ncParams.rect0.Rect; CalcSizeNCRectangle(ref proposed); ncParams.rect0.Rect = proposed; Marshal.StructureToPtr(ncParams, m.LParam, false); } }
/// <summary> /// Processes the WndProc for a form with a Ribbbon. Returns true if message has been handled /// </summary> /// <param name="m">Message to process</param> /// <returns><c>true</c> if message has been handled. <c>false</c> otherwise</returns> public virtual bool WndProc(ref Message m) { if (DesignMode) { return(false); } bool handled = false; if (WinApi.IsVista) { #region Checks if DWM processes the message IntPtr result; int dwmHandled = WinApi.DwmDefWindowProc(m.HWnd, m.Msg, m.WParam, m.LParam, out result); if (dwmHandled == 1) { m.Result = result; handled = true; } #endregion } //if (m.Msg == WinApi.WM_NCLBUTTONUP) //{ // UpdateRibbonConditions(); //} if (!handled) { if (m.Msg == WinApi.WM_NCCALCSIZE && (int)m.WParam == 1) { #region Catch the margins of what the client area would be WinApi.NCCALCSIZE_PARAMS nccsp = (WinApi.NCCALCSIZE_PARAMS)Marshal.PtrToStructure(m.LParam, typeof(WinApi.NCCALCSIZE_PARAMS)); if (!MarginsChecked) { //Set what client area would be for passing to DwmExtendIntoClientArea SetMargins(new Padding( nccsp.rect2.Left - nccsp.rect1.Left, nccsp.rect2.Top - nccsp.rect1.Top, nccsp.rect1.Right - nccsp.rect2.Right, nccsp.rect1.Bottom - nccsp.rect2.Bottom)); MarginsChecked = true; } Marshal.StructureToPtr(nccsp, m.LParam, false); m.Result = IntPtr.Zero; handled = true; #endregion } else if (m.Msg == WinApi.WM_NCHITTEST && (int)m.Result == 0) { #region Check the Non-client area hit test m.Result = new IntPtr(Convert.ToInt32(NonClientHitTest(new Point(WinApi.LoWord((int)m.LParam), WinApi.HiWord((int)m.LParam))))); handled = true; if (Ribbon != null && Ribbon.ActualBorderMode == RibbonWindowMode.NonClientAreaCustomDrawn) { Form.Refresh(); } #endregion } //else if ((m.Msg == WinApi.WM_SIZE) && Ribbon != null && Ribbon.ActualBorderMode == RibbonWindowMode.NonClientAreaGlass) //{ // //UpdateRibbonConditions(); //} else if ( (Ribbon != null && Ribbon.ActualBorderMode != RibbonWindowMode.NonClientAreaCustomDrawn) && (m.Msg == 0x112 || m.Msg == 0x47 || m.Msg == 0x46 || m.Msg == 0x2a2)) //WM_SYSCOMMAND { //InvalidateCaption(); //using (Graphics g = Form.CreateGraphics()) //{ // g.DrawRectangle(Pens.Red, new Rectangle(Form.Width - 200, 0, 200, 50)); //} }/* * else if ( * (Ribbon != null && Ribbon.ActualBorderMode == RibbonWindowMode.NonClientAreaCustomDrawn) && * (m.Msg == 0x86 || m.Msg == 0x85 || m.Msg == 0xc3c2 || m.Msg == 0xc358) * ) * { * m.Result = new IntPtr(-1); * handled = true; * }*/ } return(handled); }
/// <summary> /// Processes the WndProc for a form with a Ribbbon. Returns true if message has been handled /// </summary> /// <param name="m">Message to process</param> /// <returns><c>true</c> if message has been handled. <c>false</c> otherwise</returns> public virtual bool WndProc(ref Message m) { if (DesignMode) { return(false); } bool handled = false; if (WinApi.IsVista) { #region Checks if DWM processes the message IntPtr result; int dwmHandled = WinApi.DwmDefWindowProc(m.HWnd, m.Msg, m.WParam, m.LParam, out result); if (dwmHandled == 1) { m.Result = result; handled = true; } #endregion } //if (m.Msg == WinApi.WM_NCLBUTTONUP) //{ // UpdateRibbonConditions(); //} if (!handled) { if (m.Msg == WinApi.WM_NCCALCSIZE && (int)m.WParam == 1) //0x83 { #region Catch the margins of what the client area would be WinApi.NCCALCSIZE_PARAMS nccsp = (WinApi.NCCALCSIZE_PARAMS)Marshal.PtrToStructure(m.LParam, typeof(WinApi.NCCALCSIZE_PARAMS)); if (!MarginsChecked) { //Set what client area would be for passing to DwmExtendIntoClientArea SetMargins(new Padding( nccsp.rect2.Left - nccsp.rect1.Left, nccsp.rect2.Top - nccsp.rect1.Top, nccsp.rect1.Right - nccsp.rect2.Right, nccsp.rect1.Bottom - nccsp.rect2.Bottom)); MarginsChecked = true; } Marshal.StructureToPtr(nccsp, m.LParam, false); m.Result = IntPtr.Zero; handled = true; #endregion } else if (m.Msg == WinApi.WM_NCACTIVATE && Ribbon != null && Ribbon.ActualBorderMode == RibbonWindowMode.NonClientAreaCustomDrawn) { Ribbon.Invalidate(); handled = true; if (m.WParam == IntPtr.Zero) // if could be removed because result is ignored if WParam is TRUE { m.Result = (IntPtr)1; } } else if ((m.Msg == WinApi.WM_ACTIVATE || m.Msg == WinApi.WM_PAINT) && WinApi.IsVista) //0x06 - 0x000F { m.Result = (IntPtr)1; handled = false; } else if (m.Msg == WinApi.WM_NCHITTEST && (int)m.Result == 0) //0x84 { #region Check the Non-client area hit test m.Result = new IntPtr(Convert.ToInt32(NonClientHitTest(new Point(WinApi.LoWord((int)m.LParam), WinApi.HiWord((int)m.LParam))))); handled = true; if (Ribbon != null && Ribbon.ActualBorderMode == RibbonWindowMode.NonClientAreaCustomDrawn) { //Kevin Carbis - this refresh call caused severe cpu usage while moving the mouse over the //caption bar. I have been trying to find a way to make a less demanding call to paint. //Form.Refresh(); //WinApi.InvalidateWindow(Form.Handle); //Form.Invalidate(); //Ribbon.Invalidate(); Ribbon.RedrawArea(Ribbon.ClientRectangle); } //Console.WriteLine("Msg " + m.Msg.ToString() + " " + m.Msg.ToString("X")); #endregion } else if ( (Ribbon != null && Ribbon.ActualBorderMode != RibbonWindowMode.NonClientAreaCustomDrawn) && (m.Msg == WinApi.WM_SYSCOMMAND || m.Msg == WinApi.WM_WINDOWPOSCHANGING || m.Msg == WinApi.WM_WINDOWPOSCHANGED)) { Ribbon.Invalidate(); } else if (m.Msg == WinApi.WM_NCMOUSELEAVE) { } } return(handled); }
/// <summary> /// Processes the WndProc for a form with a Ribbbon. Returns true if message has been handled /// </summary> /// <param name="m">Message to process</param> /// <returns><c>true</c> if message has been handled. <c>false</c> otherwise</returns> public virtual bool WndProc(ref Message m) { if (DesignMode) { return(false); } bool handled = false; if (WinApi.IsVista) { #region Checks if DWM processes the message IntPtr result; int dwmHandled = WinApi.DwmDefWindowProc(m.HWnd, m.Msg, m.WParam, m.LParam, out result); if (dwmHandled == 1) { m.Result = result; handled = true; } #endregion } //if (m.Msg == WinApi.WM_NCLBUTTONUP) //{ // UpdateRibbonConditions(); //} if (!handled) { if (m.Msg == WinApi.WM_NCCALCSIZE && (int)m.WParam == 1) //0x83 { #region Catch the margins of what the client area would be WinApi.NCCALCSIZE_PARAMS nccsp = (WinApi.NCCALCSIZE_PARAMS)Marshal.PtrToStructure(m.LParam, typeof(WinApi.NCCALCSIZE_PARAMS)); if (!MarginsChecked) { //Set what client area would be for passing to DwmExtendIntoClientArea SetMargins(new Padding( nccsp.rect2.Left - nccsp.rect1.Left, nccsp.rect2.Top - nccsp.rect1.Top, nccsp.rect1.Right - nccsp.rect2.Right, nccsp.rect1.Bottom - nccsp.rect2.Bottom)); MarginsChecked = true; } #region Hack to get rid of the black caption bar when form is maximized on multi-monitor setups with DWM enabled // toATwork: on multi-monitor setups the caption bar when the form is maximized the caption bar is black instead of glass // * set handled to false and let the base implementation handle it, will work but then the default caption bar // is also visible - not desired // * setting the client area to some other value, e.g. descrease the size of the client area by one pixel will // cause windows to render the caption bar a glass - not correct but the lesser of the two evils if (Screen.AllScreens.Length > 1 && WinApi.IsGlassEnabled) { nccsp.rect0.Bottom -= 1; } #endregion Marshal.StructureToPtr(nccsp, m.LParam, false); m.Result = IntPtr.Zero; handled = true; #endregion } else if (m.Msg == WinApi.WM_NCACTIVATE && Ribbon != null && Ribbon.ActualBorderMode == RibbonWindowMode.NonClientAreaCustomDrawn) { Ribbon.Invalidate(); handled = true; if (m.WParam == IntPtr.Zero) // if could be removed because result is ignored if WParam is TRUE { m.Result = (IntPtr)1; } } else if ((m.Msg == WinApi.WM_ACTIVATE || m.Msg == WinApi.WM_PAINT) && WinApi.IsVista) //0x06 - 0x000F { m.Result = (IntPtr)1; handled = false; } else if (m.Msg == WinApi.WM_NCHITTEST && (int)m.Result == 0) //0x84 { m.Result = new IntPtr(Convert.ToInt32(NonClientHitTest(new Point(WinApi.LoWord((int)m.LParam), WinApi.HiWord((int)m.LParam))))); handled = true; } else if (m.Msg == WinApi.WM_SYSCOMMAND) { uint param = IntPtr.Size == 4 ? (uint)m.WParam.ToInt32() : (uint)m.WParam.ToInt64(); if ((param & 0xFFF0) == WinApi.SC_RESTORE) { Form.Size = _storeSize; } else if (Form.WindowState == FormWindowState.Normal) { _storeSize = Form.Size; } } else if (m.Msg == WinApi.WM_WINDOWPOSCHANGING || m.Msg == WinApi.WM_WINDOWPOSCHANGED) // needed to update the title of MDI parent (at least) { if (Ribbon != null) { Ribbon.Invalidate(); } } } return(handled); }
protected override void WndProc(ref Message m) { if (!DesignMode) { IntPtr result = default(IntPtr); if (_isVistaOrHigher) { int dwmHandled = DwmApi.DwmDefWindowProc(m.HWnd, m.Msg, m.WParam, m.LParam, ref result); if (dwmHandled == 1) { m.Result = result; return; } } else if (m.Msg == (int)WinApi.Messages.WM_NCPAINT || m.Msg == (int)WinApi.Messages.WM_SIZING || m.Msg == (int)WinApi.Messages.WM_NCACTIVATE) { using (var graphics = Graphics.FromHwnd(m.HWnd)) { using (SolidBrush b = MetroPaint.GetStyleBrush(Style)) { graphics.FillRectangle(b, new Rectangle(0, 0, Width, 5)); } } } if (m.Msg == (int)WinApi.Messages.WM_NCCALCSIZE && (int)m.WParam == 1) { WinApi.NCCALCSIZE_PARAMS nccsp = (WinApi.NCCALCSIZE_PARAMS)Marshal.PtrToStructure(m.LParam, typeof(WinApi.NCCALCSIZE_PARAMS)); nccsp.rect0.Top += 0; nccsp.rect0.Bottom += 0; nccsp.rect0.Left += 0; nccsp.rect0.Right += 0; if (!isMarginOk) { dwmMargins.cyTopHeight = 0; dwmMargins.cxLeftWidth = borderWidth; dwmMargins.cyBottomHeight = borderWidth; dwmMargins.cxRightWidth = borderWidth; isMarginOk = true; } Marshal.StructureToPtr(nccsp, m.LParam, false); m.Result = IntPtr.Zero; } else if (m.Msg == (int)WinApi.Messages.WM_LBUTTONDBLCLK) { // Alow the form to be normalized / maximized when // clicked inside our top header area rectangle. if (_isMouseXyWithinTopHeaderArea) { WindowState = WindowState == FormWindowState.Maximized ? FormWindowState.Normal : FormWindowState.Maximized; _isMouseXyWithinTopHeaderArea = false; } } else if (m.Msg == (int)WinApi.Messages.WM_NCHITTEST && (int)m.Result == 0) { m.Result = HitTestNCA(m.HWnd, m.WParam, m.LParam); } else if (m.Msg == (int)WinApi.Messages.WM_GETMINMAXINFO) { OnGetMinMaxInfo(m.HWnd, m.LParam); } else { base.WndProc(ref m); } } else { base.WndProc(ref m); } }