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

C#论坛同步更新:http://www.cckan.net/thread-1809-1-1.html (最新版)

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;
        }
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值