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)]
borderbox36. 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小时内删除。
发表评论