Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- using System.Collections.Generic;
- using System.ComponentModel;
- using System.Drawing;
- using System.Linq;
- using System.Runtime.InteropServices;
- using System.Text;
- using System.Windows.Forms;
- namespace WindowsFormsApplication1
- {
- public class RichTextBoxEx : RichTextBox
- {
- private int _borderWidth = 1;
- private Color _borderColor = Color.Black;
- public RichTextBoxEx() { }
- [Category("Border")]
- public int BorderWidth
- {
- get {
- return _borderWidth;
- }
- set {
- if (_borderWidth < 0)
- throw new ArgumentException("Border width must be non-negative", "BorderWidth");
- _borderWidth = value;
- Invalidate();
- InvalidateNC();
- }
- }
- [Category("Border")]
- public Color BorderColor
- {
- get
- {
- return _borderColor;
- }
- set
- {
- _borderColor = value;
- Invalidate();
- InvalidateNC();
- }
- }
- protected override CreateParams CreateParams
- {
- get
- {
- var cp = base.CreateParams;
- cp.ExStyle &= ~0x200; // WS_EX_CLIENTEDGE
- cp.Style &= ~0x00800000; // WS_BORDER
- return cp;
- }
- }
- protected override void WndProc(ref Message m)
- {
- switch (m.Msg)
- {
- case (int)NativeMethods.WM_NCCALCSIZE:
- if (m.WParam == IntPtr.Zero || m.WParam == new IntPtr(1))
- RecalcNonClientArea(m.LParam);
- break;
- case (int)NativeMethods.WM_NCPAINT:
- OnWMNCPaint(ref m);
- break;
- case (int)NativeMethods.WM_NCHITTEST:
- m.Result = PerformHitTest(new Point(m.LParam.ToInt32()));
- return;
- }
- base.WndProc(ref m);
- }
- protected override void OnResize(EventArgs eventargs)
- {
- InvalidateNC();
- base.OnResize(eventargs);
- }
- private void OnWMNCPaint(ref Message m)
- {
- var hDC = NativeMethods.GetWindowDC(m.HWnd);
- if (hDC == IntPtr.Zero) return;
- var hrgnWindow = IntPtr.Zero;
- var hrgnClient = IntPtr.Zero;
- try
- {
- var rect = new Rectangle(_borderWidth, _borderWidth, Width - (_borderWidth * 2), Height - (_borderWidth * 2));
- hrgnWindow = NativeMethods.CreateRectRgn(0, 0, Width, Height);
- hrgnClient = NativeMethods.CreateRectRgn(rect.Left, rect.Top, rect.Right, rect.Bottom);
- NativeMethods.CombineRgn(hrgnWindow, hrgnWindow, hrgnClient, 4); // RGN_DIFF
- NativeMethods.SelectClipRgn(hDC, hrgnWindow);
- using (Graphics g = Graphics.FromHdc(hDC))
- g.Clear(BorderColor);
- m.Result = IntPtr.Zero;
- }
- finally
- {
- NativeMethods.ReleaseDC(m.HWnd, hDC);
- if (hrgnWindow != IntPtr.Zero)
- NativeMethods.DeleteObject(hrgnWindow);
- if (hrgnClient != IntPtr.Zero)
- NativeMethods.DeleteObject(hrgnClient);
- }
- }
- private void InvalidateNC()
- {
- NativeMethods.SetWindowPos(this.Handle, IntPtr.Zero, 0, 0, 0, 0,
- NativeMethods.SWP_NOMOVE |
- NativeMethods.SWP_NOSIZE |
- NativeMethods.SWP_NOZORDER |
- NativeMethods.SWP_NOACTIVATE |
- NativeMethods.SWP_DRAWFRAME);
- }
- private void RecalcNonClientArea(IntPtr lParam)
- {
- NativeMethods.NCCALCSIZE_PARAMS csp;
- csp = (NativeMethods.NCCALCSIZE_PARAMS)Marshal.PtrToStructure(
- lParam,
- typeof(NativeMethods.NCCALCSIZE_PARAMS));
- csp.rcNewWindow.Top += _borderWidth;
- csp.rcNewWindow.Bottom -= _borderWidth;
- csp.rcNewWindow.Left += _borderWidth;
- csp.rcNewWindow.Right -= _borderWidth;
- Marshal.StructureToPtr(csp, lParam, false);
- }
- private IntPtr PerformHitTest(Point screenPos)
- {
- Point windowPos = this.Parent.PointToClient(screenPos);
- windowPos.Offset(-this.Location.X, -this.Location.Y);
- var clientWindowRect = new Rectangle(_borderWidth, _borderWidth, Width, Height);
- return clientWindowRect.Contains(windowPos) ? (IntPtr)NativeMethods.HTCLIENT : (IntPtr)NativeMethods.HTBORDER;
- }
- }
- public class NativeMethods
- {
- public const int WM_NCCALCSIZE = 0x83;
- public const int WM_NCHITTEST = 0x84;
- public const int WM_NCPAINT = 0x85;
- public const int SWP_NOSIZE = 0x0001;
- public const int SWP_NOMOVE = 0x0002;
- public const int SWP_NOZORDER = 0x0004;
- public const int SWP_NOREDRAW = 0x0008;
- public const int SWP_NOACTIVATE = 0x0010;
- public const int SWP_FRAMECHANGED = 0x0020;
- public const int SWP_DRAWFRAME = SWP_FRAMECHANGED;
- public const int HTCLIENT = 1;
- public const int HTBORDER = 18;
- [DllImport("user32.dll")]
- public static extern IntPtr GetWindowDC(IntPtr hWnd);
- [DllImport("user32.dll")]
- [return: MarshalAs(UnmanagedType.Bool)]
- public static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, int uFlags);
- [DllImport("user32.dll")]
- public static extern bool ReleaseDC(IntPtr hWnd, IntPtr hDC);
- [DllImport("gdi32.dll")]
- public static extern bool DeleteObject(IntPtr hObject);
- [DllImport("gdi32.dll")]
- public static extern IntPtr CreateRectRgn(int nLeftRect, int nTopRect, int nRightRect, int nBottomRect);
- [DllImport("gdi32.dll")]
- public static extern int CombineRgn(IntPtr hrgnDest, IntPtr hrgnSrc1,
- IntPtr hrgnSrc2, int fnCombineMode);
- [DllImport("gdi32.dll")]
- public static extern int SelectClipRgn(IntPtr hdc, IntPtr hrgn);
- public struct RECT { public int Left, Top, Right, Bottom; }
- public struct NCCALCSIZE_PARAMS
- {
- public RECT rcNewWindow;
- public RECT rcOldWindow;
- public RECT rcClient;
- IntPtr lppos;
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement