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

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。