1. using System; 
  2. using System.Collections.Generic; 
  3. using System.ComponentModel; 
  4. using System.Data; 
  5. using System.Drawing; 
  6. using System.Linq; 
  7. using System.Text; 
  8. using System.Windows.Forms; 
  9. using System.Runtime.InteropServices; 
  10.  
  11. namespace TextDemo 
  12.     public partial class Form3 : Form 
  13.     { 
  14.         public Form3() 
  15.         { 
  16.             InitializeComponent();  
  17.         } 
  18.  
  19.         /// <summary>  
  20.         /// 添加一个继承自textbox的新类,重写WndProc方法,在重写的方法里重绘边框就可以了  
  21.         /// </summary>  
  22.         /// <param name="m"></param>  
  23.         protectedoverridevoid WndProc(ref Message m) 
  24.         { 
  25.             base.WndProc(ref m); 
  26.             borderDrawer borderDrawer1 = new borderDrawer(); 
  27.             borderDrawer1.DrawBorder(ref m, this.Width, this.Height); 
  28.         } 
  29.     }
  30.     #region 第一种方法,使用时必须把文本框的BorderStyle为FixedSingle才能使用  
  31.     [ToolboxItem(true)] 
  32.     publicclass TextBoxXP : System.Windows.Forms.TextBox 
  33.     { 
  34.         /// <summary>   
  35.         /// 获得当前进程,以便重绘控件   
  36.         /// </summary>   
  37.         /// <param name="hWnd"></param>   
  38.         /// <returns></returns>   
  39.         [System.Runtime.InteropServices.DllImport("user32.dll")] 
  40.         staticextern IntPtr GetWindowDC(IntPtr hWnd); 
  41.         [System.Runtime.InteropServices.DllImport("user32.dll")] 
  42.         staticexternint ReleaseDC(IntPtr hWnd, IntPtr hDC); 
  43.  
  44.         /// <summary>   
  45.         /// 是否启用热点效果   
  46.         /// </summary>   
  47.         privatebool _HotTrack = true
  48.  
  49.         /// <summary>   
  50.         /// 边框颜色   
  51.         /// </summary>   
  52.         private Color _BorderColor = Color.Black; 
  53.  
  54.         /// <summary>   
  55.         /// 热点边框颜色   
  56.         /// </summary>   
  57.         private Color _HotColor = Color.FromArgb(0x33, 0x5E, 0xA8); 
  58.  
  59.         /// <summary>   
  60.         /// 是否鼠标MouseOver状态   
  61.         /// </summary>   
  62.         privatebool _IsMouseOver = false;
  63.         #region 属性  
  64.         /// <summary>   
  65.         /// 是否启用热点效果   
  66.         /// </summary>   
  67.         [Category("行为"), 
  68.        Description("获得或设置一个值,指示当鼠标经过控件时控件边框是否发生变化。只在控件的BorderStyle为FixedSingle时有效"), 
  69.        DefaultValue(true)] 
  70.         publicbool HotTrack 
  71.         { 
  72.             get 
  73.             { 
  74.                 returnthis._HotTrack; 
  75.             } 
  76.             set 
  77.             { 
  78.                 this._HotTrack = value; 
  79.                 //在该值发生变化时重绘控件,下同   
  80.                 //在设计模式下,更改该属性时,如果不调用该语句,   
  81.                 //则不能立即看到设计试图中该控件相应的变化   
  82.                 this.Invalidate(); 
  83.             } 
  84.         } 
  85.         /// <summary>   
  86.         /// 边框颜色   
  87.         /// </summary>   
  88.         [Category("外观"), 
  89.        Description("获得或设置控件的边框颜色"), 
  90.        DefaultValue(typeof(Color), "#A7A6AA")] 
  91.         public Color BorderColor 
  92.         { 
  93.             get 
  94.             { 
  95.                 returnthis._BorderColor; 
  96.             } 
  97.             set 
  98.             { 
  99.                 this._BorderColor = value; 
  100.                 this.Invalidate(); 
  101.             } 
  102.         } 
  103.         /// <summary>   
  104.         /// 热点时边框颜色   
  105.         /// </summary>   
  106.         [Category("外观"), 
  107.        Description("获得或设置当鼠标经过控件时控件的边框颜色。只在控件的BorderStyle为FixedSingle时有效"), 
  108.        DefaultValue(typeof(Color), "#335EA8")] 
  109.         public Color HotColor 
  110.         { 
  111.             get 
  112.             { 
  113.                 returnthis._HotColor; 
  114.             } 
  115.             set 
  116.             { 
  117.                 this._HotColor = value; 
  118.                 this.Invalidate(); 
  119.             } 
  120.         }
  121.         #endregion 属性  
  122.  
  123.         /// <summary>   
  124.         ///   
  125.         /// </summary>   
  126.         public TextBoxXP() 
  127.             : base() 
  128.         { 
  129.         } 
  130.  
  131.         /// <summary>   
  132.         /// 鼠标移动到该控件上时   
  133.         /// </summary>   
  134.         /// <param name="e"></param>   
  135.         protectedoverridevoid OnMouseMove(MouseEventArgs e) 
  136.         { 
  137.             //鼠标状态   
  138.             this._IsMouseOver = true
  139.             //如果启用HotTrack,则开始重绘   
  140.             //如果不加判断这里不加判断,则当不启用HotTrack,   
  141.             //鼠标在控件上移动时,控件边框会不断重绘,   
  142.             //导致控件边框闪烁。下同   
  143.             //谁有更好的办法?Please tell me , Thanks。   
  144.             if (this._HotTrack) 
  145.             { 
  146.                 //重绘   
  147.                 this.Invalidate(); 
  148.             } 
  149.             base.OnMouseMove(e); 
  150.         } 
  151.         /// <summary>   
  152.         /// 当鼠标从该控件移开时   
  153.         /// </summary>   
  154.         /// <param name="e"></param>   
  155.         protectedoverridevoid OnMouseLeave(EventArgs e) 
  156.         { 
  157.             this._IsMouseOver = false
  158.  
  159.             if (this._HotTrack) 
  160.             { 
  161.                 //重绘   
  162.                 this.Invalidate(); 
  163.             } 
  164.             base.OnMouseLeave(e); 
  165.         } 
  166.  
  167.         /// <summary>   
  168.         /// 当该控件获得焦点时   
  169.         /// </summary>   
  170.         /// <param name="e"></param>   
  171.         protectedoverridevoid OnGotFocus(EventArgs e) 
  172.         { 
  173.  
  174.             if (this._HotTrack) 
  175.             { 
  176.                 //重绘   
  177.                 this.Invalidate(); 
  178.             } 
  179.             base.OnGotFocus(e); 
  180.         } 
  181.         /// <summary>   
  182.         /// 当该控件失去焦点时   
  183.         /// </summary>   
  184.         /// <param name="e"></param>   
  185.         protectedoverridevoid OnLostFocus(EventArgs e) 
  186.         { 
  187.             if (this._HotTrack) 
  188.             { 
  189.                 //重绘   
  190.                 this.Invalidate(); 
  191.             } 
  192.             base.OnLostFocus(e); 
  193.         } 
  194.  
  195.         /// <summary>   
  196.         /// 获得操作系统消息   
  197.         /// </summary>   
  198.         /// <param name="m"></param>   
  199.         protectedoverridevoid WndProc(ref Message m) 
  200.         { 
  201.  
  202.             base.WndProc(ref m); 
  203.             if (m.Msg == 0xf || m.Msg == 0x133) 
  204.             { 
  205.                 //拦截系统消息,获得当前控件进程以便重绘。   
  206.                 //一些控件(如TextBox、Button等)是由系统进程绘制,重载OnPaint方法将不起作用.   
  207.                 //所有这里并没有使用重载OnPaint方法绘制TextBox边框。   
  208.                 //   
  209.                 //MSDN:重写 OnPaint 将禁止修改所有控件的外观。   
  210.                 //那些由 Windows 完成其所有绘图的控件(例如 Textbox)从不调用它们的 OnPaint 方法,   
  211.                 //因此将永远不会使用自定义代码。请参见您要修改的特定控件的文档,   
  212.                 //查看 OnPaint 方法是否可用。如果某个控件未将 OnPaint 作为成员方法列出,   
  213.                 //则您无法通过重写此方法改变其外观。   
  214.                 //   
  215.                 //MSDN:要了解可用的 Message.Msg、Message.LParam 和 Message.WParam 值,   
  216.                 //请参考位于 MSDN Library 中的 Platform SDK 文档参考。可在 Platform SDK(“Core SDK”一节)   
  217.                 //下载中包含的 windows.h 头文件中找到实际常数值,该文件也可在 MSDN 上找到。   
  218.                 IntPtr hDC = GetWindowDC(m.HWnd); 
  219.                 if (hDC.ToInt32() == 0) 
  220.                 { 
  221.                     return
  222.                 } 
  223.  
  224.                 //只有在边框样式为FixedSingle时自定义边框样式才有效   
  225.                 if (this.BorderStyle == BorderStyle.FixedSingle) 
  226.                 { 
  227.                     //边框Width为1个像素   
  228.                     System.Drawing.Pen pen = new Pen(this._BorderColor, 1); ; 
  229.  
  230.                     if (this._HotTrack) 
  231.                     { 
  232.                         if (this.Focused) 
  233.                         { 
  234.                             pen.Color = this._HotColor; 
  235.                         } 
  236.                         else 
  237.                         { 
  238.                             if (this._IsMouseOver) 
  239.                             { 
  240.                                 pen.Color = this._HotColor; 
  241.                             } 
  242.                             else 
  243.                             { 
  244.                                 pen.Color = this._BorderColor; 
  245.                             } 
  246.                         } 
  247.                     } 
  248.                     //绘制边框   
  249.                     System.Drawing.Graphics g = Graphics.FromHdc(hDC); 
  250.                     g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias; 
  251.                     g.DrawRectangle(pen, 0, 0, this.Width - 1, this.Height - 1); 
  252.                     pen.Dispose(); 
  253.                 } 
  254.                 //返回结果   
  255.                 m.Result = IntPtr.Zero; 
  256.                 //释放   
  257.                 ReleaseDC(m.HWnd, hDC); 
  258.             } 
  259.         } 
  260.     } 
  261.     #endregion  
  262.   
  263.     /// <summary>  
  264.     /// 第二种方法  
  265.     /// </summary>  
  266.     class borderDrawer : System.Windows.Forms.TextBox 
  267.     { 
  268.         private Color borderColor = Color.Red;   // 设置默认的边框颜色  
  269.         privatestaticint WM_NCPAINT = 0x0085;    // WM_NCPAINT message  
  270.         privatestaticint WM_ERASEBKGND = 0x0014; // WM_ERASEBKGND message  
  271.         privatestaticint WM_PAINT = 0x000F;      // WM_PAINT message  
  272.         [DllImport("user32.dll")] 
  273.         staticextern IntPtr GetDCEx(IntPtr hwnd, IntPtr hrgnclip, uint fdwOptions); 
  274.         //释放DC  
  275.         [DllImport("user32.dll")] 
  276.         staticexternint ReleaseDC(IntPtr hwnd, IntPtr hDC); 
  277.         /// <summary>  
  278.         /// 重绘边框的方法  
  279.         /// </summary>  
  280.         /// <param name="message"></param>  
  281.         /// <param name="width"></param>  
  282.         /// <param name="height"></param>  
  283.         publicvoid DrawBorder(ref Message message, int width, int height) 
  284.         { 
  285.             if (message.Msg == WM_NCPAINT || message.Msg == WM_ERASEBKGND || 
  286.                 message.Msg == WM_PAINT) 
  287.             { 
  288.                 IntPtr hdc = GetDCEx(message.HWnd, (IntPtr)1, 1 | 0x0020); 
  289.  
  290.                 if (hdc != IntPtr.Zero) 
  291.                 { 
  292.                     Graphics graphics = Graphics.FromHdc(hdc); 
  293.                     Rectangle rectangle = new Rectangle(0, 0, width, height); 
  294.                     ControlPaint.DrawBorder(graphics, rectangle, 
  295.                                  borderColor, ButtonBorderStyle.Solid); 
  296.  
  297.                     message.Result = (IntPtr)1; 
  298.                     ReleaseDC(message.HWnd, hdc); 
  299.                 } 
  300.             } 
  301.         } 
  302.     } 

原链接:http://blog.csdn.net/liujun198773/article/details/8486657

 

利用层原理,先设置TextBox的边框样式为None,再在TextBox上面绘制一个边框就可以了。