C#仿QQ皮肤-实现原理系列文章导航 http://www.cnblogs.com/sufei/archive/2010/03/10/1682847.html
大家都知道WinForm的文本框的边框颜色是不能修改的,在这里咱们就看一下怎么样使用Aip的方法来实现修改边框的效果。
不但可以修改文本框的,任何基本控件都行,包括Windows窗体在内。一会儿大家可以参考一个我的公共方法。
我们先来看看实现后的效果吧
正常显示时效果
在得到焦点时的效果
大可以应该可以看得出来有什么不同,第一个图上是增加一个边框,颜色很谈的一条线,在得到焦点时会改变文本框的背景色,当然在失去焦点时会还原过来
这些效果都是可以自己修改的,我给出来的只是一个样子,比较得到焦点时的颜色可以自己修改,正常显示时的边框都可以自己修改。
来看看实现方式吧
先来看看是怎么实现边框的吧第一步我们来新建一个TextBox组件类
然后我们来实现一个边框
我们先来设置一些东西看构造方法
public CTextBox() : base () { // 设置为单行边框 this .BorderStyle = BorderStyle.FixedSingle; // 强制将分配的样式应用到控件 this .UpdateStyles(); // 得到默认颜色关储存 objcolor = BackColor; }我之所以这样设置是为了下一步修改边框,保存默认颜色我不说大家也知道是为了什么吧。当然是在失去焦点时还原本来的颜色啦。
我们一起来看一下调用的代码吧
/// <summary> /// 重新设置边框 /// </summary> /// <param name="m"> 当前的Windows消息 </param> protected override void WndProc( ref Message m) { base .WndProc( ref m); if (m.Msg == 0xf || m.Msg == 0x133 ) { SkinHelp.ResetBorderColor(m, this , 1 , SkinHelp.ControlBorderBackColor); } }
我们只要重写一个WndProc这个方法就OK了,其实这里很简单。调用 一个父类的方法,然后判断消息的正确性,然后调用下面一个方法就可以了,我们主要一起来看一下ResetBorderColor方法吧
先看看方法的签名吧
/// <summary> /// 修改控件或窗体的边框,例如Textbox或是Form窗体 /// </summary> /// <param name="m"> 消息 </param> /// <param name="control"> 控件对象 </param> /// <param name="Nwidth"> 边框像素 </param> /// <param name="objcolor"> 边框颜色 </param> internal static void ResetBorderColor(Message m, Control control, int Nwidth, Color objcolor)
我们先来画一条线,根据颜色和边框像素取得一条线,其实这就是我们要的边框。
// 根据颜色和边框像素取得一条线 System.Drawing.Pen pen = pen = new Pen(objcolor, Nwidth);与此同时我们还要得到当前控件的句柄参考如下代码
// 得到当前的句柄 IntPtr hDC = Win32.GetWindowDC(m.HWnd); if (hDC.ToInt32() == 0 ) { return ; }我们绘制的方式就是,先得到句柄和边框效果,然后根据当前的句柄重新绘制一个新的Textbox出来,然后返回给当前的对象就OK了,代码书写过程如下
if (pen != null ) { // 绘制边框 System.Drawing.Graphics g = Graphics.FromHdc(hDC); g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias; g.DrawRectangle(pen, 0 , 0 , control.Width - Nwidth, control.Height - Nwidth); pen.Dispose(); }最后我们释放一下就可以了
// 释放 Win32.ReleaseDC(m.HWnd, hDC);这个方法的所有代码如下
/// <summary> /// 修改控件或窗体的边框,例如Textbox或是Form窗体 /// </summary> /// <param name="m"> 消息 </param> /// <param name="control"> 控件对象 </param> /// <param name="Nwidth"> 边框像素 </param> /// <param name="objcolor"> 边框颜色 </param> internal static void ResetBorderColor(Message m, Control control, int Nwidth, Color objcolor) { // 根据颜色和边框像素取得一条线 System.Drawing.Pen pen = pen = new Pen(objcolor, Nwidth); // 得到当前的句柄 IntPtr hDC = Win32.GetWindowDC(m.HWnd); if (hDC.ToInt32() == 0 ) { return ; } if (pen != null ) { // 绘制边框 System.Drawing.Graphics g = Graphics.FromHdc(hDC); g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias; g.DrawRectangle(pen, 0 , 0 , control.Width - Nwidth, control.Height - Nwidth); pen.Dispose(); } // 释放 Win32.ReleaseDC(m.HWnd, hDC); }其实有了这个方法之后我们不但但是可以做文本框的边框,几乎所有的控件和窗体都可以使用这个通用的方法来实现。
有关于win32的类在我的皮肤类文件里都有大家可以直接下载使用
这样我们的第一步工作就完成了,下面我们来实现一下得到和失去焦点时的效果吧,由于这个比较简单和就不一步一步的说了,一起来看看代码吧
/// <summary> /// 在得到焦点时修改文体框的背景色 /// </summary> /// <param name="e"></param> protected override void OnGotFocus(EventArgs e) { base .OnGotFocus(e); BackColor = Color.MistyRose; } /// <summary> /// 在失去焦点时还原文本框的颜色 /// </summary> /// <param name="e"></param> protected override void OnLostFocus(EventArgs e) { base .OnLostFocus(e); BackColor = objcolor; }好了这样我们的控件就可以出炉了,我们生成一下
我直接拉了几个大家其实不用运行就可以看到忆经有边框了。
这个方法正如我刚在所说的一样是通用的,如果你想做一个自己想要的窗体的话也可以这样来实现,直接传参数就行了,
但是不要忘记了把窗体的边框先删除了。就是设置为空。
下面是实现的所有代码
using System; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Linq; using System.Text; using System.Windows.Forms; using System.Drawing; namespace bxyztSkin.CControls{ public partial class CTextBox : System.Windows.Forms.TextBox { /// <summary> /// 类说明:CTextBox控件的实现用来代替系统的TextBox控件 /// 编码日期:2011-03-03 /// 编 码 人: 苏飞 /// 联系方式:361983679 Email:sufei.1013@163.com Blogs:sufei.cnblogs.com /// </summary> public CTextBox() : base () { // 设置为单选边框 this .BorderStyle = BorderStyle.FixedSingle; // 强制将分配的样式应用到控件 this .UpdateStyles(); // 得到默认颜色关储存 objcolor = BackColor; } #region 自定变量 Color objcolor; #endregion /// <summary> /// 重新设置边框 /// </summary> /// <param name="m"> 当前的Windows消息 </param> protected override void WndProc( ref Message m) { base .WndProc( ref m); if (m.Msg == 0xf || m.Msg == 0x133 ) { SkinHelp.ResetBorderColor(m, this , 1 , SkinHelp.ControlBorderBackColor); } } /// <summary> /// 在得到焦点时修改文体框的背景色 /// </summary> /// <param name="e"></param> protected override void OnGotFocus(EventArgs e) { base .OnGotFocus(e); BackColor = Color.MistyRose; } /// <summary> /// 在失去焦点时还原文本框的颜色 /// </summary> /// <param name="e"></param> protected override void OnLostFocus(EventArgs e) { base .OnLostFocus(e); BackColor = objcolor; } }}
欢迎大家转载,如有转载请注明文章来自: http://sufei.cnblogs.com/
签名:做一番一生引以为豪的事业;在有生之年报答帮过我的人;并有能力帮助需要帮助的人;
QQ:361983679 Email:sufei.1013@163.com MSN:sufei.1013@163.com