文本框自定义的OnPaint [英] Textbox custom onPaint

查看:165
本文介绍了文本框自定义的OnPaint的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想创建一个自定义的OnPaint对我的文本框,它是工作...的这是工作但是,当我尝试输入一些东西,一个。文本框被渲染文本上述



这是我的构造函数:

 公开文本框()
{
字体=新System.Drawing.Font(濑越UI,11F,System.Drawing.FontStyle.Regular,System.Drawing.GraphicsUnit.Point, ((字节)(0)));
=背景色Color.White;
BORDERCOLOR = Color.Gray;
=边框样式System.Windows.Forms.BorderStyle.None;
的SetStyle(ControlStyles.UserPaint,真);
}



而OnPaint中:

 保护覆盖无效的OnPaint(System.Windows.Forms.PaintEventArgs E)
{
图形G = e.Graphics;
g.FillRectangle(backgroundBrush,0,0,this.Width,this.Height);

的SizeF fontSize的= g.MeasureString(文字,字体);
g.DrawString(文本,字体,新SolidBrush(前景色),新的PointF(5,5),cFormat);

g.DrawRectangle(borderPen,borderPen.Width / 2,borderPen.Width / 2,this.Width - borderPen.Width,this.Height - borderPen.Width);
}


解决方案

如果你只是想自定义文本框有一些自定义的边框(宽度和颜色),我有2个解决方案,在这里:




    <李>

    使用 ControlPaint ,这将允许你画边框与一些样式和颜色,但不能使用来吸引更多不同地(如 HatchBrush 可以做):

     公共类CustomTextBox:文本框
    {
    函数[DllImport(USER32)]
    私人静态外部的IntPtr GetWindowDC(IntPtr的HWND);
    结构RECT
    {
    公众诠释左,上,右,下;
    }
    结构NCCALSIZE_PARAMS
    {
    公共RECT newWindow;
    公共RECT oldWindow;
    公共RECT clientWindow;
    IntPtr的WINDOWPOS;
    }
    浮动clientPadding = 2;
    浮动actualBorderWidth = 4;
    颜色BORDERCOLOR = Color.Red;
    保护覆盖无效的WndProc(参考消息M)
    {
    //我们必须改变clientsize腾出空间边界
    //如果没有,边框如何限制厚是。如果
    (m.Msg == 0X83)//如果WM_NCCALCSIZE
    {
    (m.WParam == IntPtr.Zero)
    {
    RECT RECT =(RECT )Marshal.PtrToStructure(m.LParam的typeof(RECT));
    rect.left + = clientPadding;
    rect.right - = clientPadding;
    rect.top + = clientPadding;
    rect.bottom - = clientPadding;
    Marshal.StructureToPtr(RECT,m.LParam,FALSE);
    }
    ,否则
    {
    NCCALSIZE_PARAMS rects =(NCCALSIZE_PARAMS)Marshal.PtrToStructure(m.LParam的typeof(NCCALSIZE_PARAMS));
    rects.newWindow.left + = clientPadding;
    rects.newWindow.right - = clientPadding;
    rects.newWindow.top + = clientPadding;
    rects.newWindow.bottom - = clientPadding;
    Marshal.StructureToPtr(rects,m.LParam,FALSE);
    }
    }
    如果(m.Msg == 0x85未)// WM_NCPAINT
    {
    IntPtr的WDC = GetWindowDC(手柄);使用
    (图形G = Graphics.FromHdc(WDC)){
    ControlPaint.DrawBorder(G,新的Rectangle(0,0,Size.Width,Size.Height),BORDERCOLOR,actualBorderWidth,ButtonBorderStyle.Solid ,
    BORDERCOLOR,actualBorderWidth,ButtonBorderStyle.Solid,BORDERCOLOR,actualBorderWidth,ButtonBorderStyle.Solid,
    BORDERCOLOR,actualBorderWidth,ButtonBorderStyle.Solid);
    }
    的回报;
    }
    base.WndProc(REF米);
    }
    }

    下面是文本框的快照:




  1. FillRegion A 图形的方式油漆与各种的边界刷,这里我用 HatchBrush

     公共类CustomTextBox:文本框
    {
    函数[DllImport(USER32)]
    私人静态外部的IntPtr GetWindowDC(IntPtr的HWND);
    结构RECT
    {
    公众诠释左,上,右,下;
    }
    结构NCCALSIZE_PARAMS
    {
    公共RECT newWindow;
    公共RECT oldWindow;
    公共RECT clientWindow;
    IntPtr的WINDOWPOS;
    }
    INT clientPadding = 2;
    INT actualBorderWidth = 4;
    保护覆盖无效的WndProc(参考消息M)
    {
    //我们必须改变clientsize腾出空间边界
    //如果没有,边框如何限制厚是。如果
    (m.Msg == 0X83)//如果WM_NCCALCSIZE
    {
    (m.WParam == IntPtr.Zero)
    {
    RECT RECT =(RECT )Marshal.PtrToStructure(m.LParam的typeof(RECT));
    rect.left + = clientPadding;
    rect.right - = clientPadding;
    rect.top + = clientPadding;
    rect.bottom - = clientPadding;
    Marshal.StructureToPtr(RECT,m.LParam,FALSE);
    }
    ,否则
    {
    NCCALSIZE_PARAMS rects =(NCCALSIZE_PARAMS)Marshal.PtrToStructure(m.LParam的typeof(NCCALSIZE_PARAMS));
    rects.newWindow.left + = clientPadding;
    rects.newWindow.right - = clientPadding;
    rects.newWindow.top + = clientPadding;
    rects.newWindow.bottom - = clientPadding;
    Marshal.StructureToPtr(rects,m.LParam,FALSE);
    }
    }
    如果(m.Msg == 0x85未)// WM_NCPAINT
    {
    IntPtr的WDC = GetWindowDC(手柄);使用
    (图形G = Graphics.FromHdc(WDC)){
    矩形RECT =新的Rectangle(0,0,宽,高);
    矩形内=新的Rectangle(0,0,宽度,高度);
    inner.Offset(actualBorderWidth + 2,+ actualBorderWidth 2);
    inner.Width - = 2 * actualBorderWidth + 4;
    inner.Height - = 2 * actualBorderWidth + 4;
    区域R =新区域(矩形);
    r.Xor(内);
    使用(System.Drawing.Drawing2D.HatchBrush刷=新System.Drawing.Drawing2D.HatchBrush(System.Drawing.Drawing2D.HatchStyle.SmallCheckerBoard,Color.Green,Color.Red))
    {
    g.FillRegion(刷,R);
    }
    }
    的回报;
    }
    base.WndProc(REF米);
    }
    }

    下面是文本框快照:
    < IMG SRC =htt​​p://i.stack.imgur.com/qTGmH.pngALT =>结果,



I'm trying to create a custom onPaint for my textbox, it is working... it is working But when I try to type something, a textbox is rendering above the textbox.

This is my constructor:

public TextBox()
    {
        Font = new System.Drawing.Font("Segoe UI", 11F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
        BackColor = Color.White;
        BorderColor = Color.Gray;
        BorderStyle = System.Windows.Forms.BorderStyle.None;
        SetStyle(ControlStyles.UserPaint, true);
    }

And the onPaint:

protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
    {
        Graphics g = e.Graphics;
        g.FillRectangle(backgroundBrush, 0, 0, this.Width, this.Height);

        SizeF fontSize = g.MeasureString(Text, Font);
        g.DrawString(Text, Font, new SolidBrush(ForeColor), new PointF(5, 5), cFormat);

        g.DrawRectangle(borderPen, borderPen.Width / 2, borderPen.Width / 2, this.Width - borderPen.Width, this.Height - borderPen.Width);
    }

解决方案

If you just want a custom TextBox with some custom border (width and color), I have 2 solutions here:

  1. Using ControlPaint, this will allow you to draw border with some style and color but can't use Brush to draw more variously (like a HatchBrush can do):

    public class CustomTextBox : TextBox
    {
        [DllImport("user32")]
        private static extern IntPtr GetWindowDC(IntPtr hwnd);
        struct RECT
        {
          public int left, top, right, bottom;
        }
        struct NCCALSIZE_PARAMS
        {
          public RECT newWindow;
          public RECT oldWindow;
          public RECT clientWindow;
          IntPtr windowPos;
        }            
        float clientPadding = 2;  
        float actualBorderWidth = 4;
        Color borderColor = Color.Red;      
        protected override void WndProc(ref Message m)
        {
          //We have to change the clientsize to make room for borders
          //if not, the border is limited in how thick it is.
          if (m.Msg == 0x83) //WM_NCCALCSIZE   
          {
            if (m.WParam == IntPtr.Zero)
            {
                RECT rect = (RECT)Marshal.PtrToStructure(m.LParam, typeof(RECT));
                rect.left += clientPadding;
                rect.right -= clientPadding;
                rect.top += clientPadding;
                rect.bottom -= clientPadding;
                Marshal.StructureToPtr(rect, m.LParam, false);
            }
            else
            {
                NCCALSIZE_PARAMS rects = (NCCALSIZE_PARAMS)Marshal.PtrToStructure(m.LParam, typeof(NCCALSIZE_PARAMS));
                rects.newWindow.left += clientPadding;
                rects.newWindow.right -= clientPadding;
                rects.newWindow.top += clientPadding;
                rects.newWindow.bottom -= clientPadding;
                Marshal.StructureToPtr(rects, m.LParam, false);
            }
          }
          if (m.Msg == 0x85) //WM_NCPAINT    
          {         
             IntPtr wDC = GetWindowDC(Handle);
             using(Graphics g = Graphics.FromHdc(wDC)){                                                      
               ControlPaint.DrawBorder(g, new Rectangle(0,0,Size.Width, Size.Height), borderColor, actualBorderWidth, ButtonBorderStyle.Solid,
             borderColor, actualBorderWidth, ButtonBorderStyle.Solid, borderColor, actualBorderWidth, ButtonBorderStyle.Solid,
             borderColor, actualBorderWidth, ButtonBorderStyle.Solid); 
             }   
             return;          
          }
          base.WndProc(ref m);
        }
    }
    

    Here is the textbox snapshot:

  2. using FillRegion method of a Graphics to paint the border with various kinds of Brush, here I use HatchBrush:

    public class CustomTextBox : TextBox
    {
      [DllImport("user32")]
      private static extern IntPtr GetWindowDC(IntPtr hwnd);
      struct RECT
      {
        public int left, top, right, bottom;
      }
      struct NCCALSIZE_PARAMS
      {
        public RECT newWindow;
        public RECT oldWindow;
        public RECT clientWindow;
        IntPtr windowPos;
      }         
      int clientPadding = 2;   
      int actualBorderWidth = 4;     
      protected override void WndProc(ref Message m)
      {
          //We have to change the clientsize to make room for borders
          //if not, the border is limited in how thick it is.
          if (m.Msg == 0x83) //WM_NCCALCSIZE   
          {
            if (m.WParam == IntPtr.Zero)
            {
                RECT rect = (RECT)Marshal.PtrToStructure(m.LParam, typeof(RECT));
                rect.left += clientPadding;
                rect.right -= clientPadding;
                rect.top += clientPadding;
                rect.bottom -= clientPadding;
                Marshal.StructureToPtr(rect, m.LParam, false);
            }
            else
            {
                NCCALSIZE_PARAMS rects = (NCCALSIZE_PARAMS)Marshal.PtrToStructure(m.LParam, typeof(NCCALSIZE_PARAMS));
                rects.newWindow.left += clientPadding;
                rects.newWindow.right -= clientPadding;
                rects.newWindow.top += clientPadding;
                rects.newWindow.bottom -= clientPadding;
                Marshal.StructureToPtr(rects, m.LParam, false);
            }
          }
          if (m.Msg == 0x85) //WM_NCPAINT
          {                 
            IntPtr wDC = GetWindowDC(Handle);
            using(Graphics g = Graphics.FromHdc(wDC)){                                                
              Rectangle rect = new Rectangle(0,0,Width,Height);
              Rectangle inner = new Rectangle(0, 0, Width, Height);
              inner.Offset(actualBorderWidth + 2, actualBorderWidth + 2);
              inner.Width -= 2 * actualBorderWidth + 4;
              inner.Height -= 2 * actualBorderWidth + 4;
              Region r = new Region(rect);
              r.Xor(inner);
              using (System.Drawing.Drawing2D.HatchBrush brush = new System.Drawing.Drawing2D.HatchBrush(System.Drawing.Drawing2D.HatchStyle.SmallCheckerBoard, Color.Green, Color.Red))
              {                    
                g.FillRegion(brush, r);
              }
            }
            return;
          }
          base.WndProc(ref m);
      }
    }
    

    Here is the textbox snapshot:

这篇关于文本框自定义的OnPaint的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆