C#仿QQ皮肤-TextBox 控件实现

    技术2022-05-20  39

    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 


    最新回复(0)