zoukankan      html  css  js  c++  java
  • 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, 
    this1, 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, 
    00, 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, 
    00, 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, 
    this1, 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;
            }
        }
    }
    本人的博客不再维护从2013年就不再维护了 需要我帮助的朋友请到我的个人论坛 http://www.sufeinet.com 进行讨论,感谢大家对我的支持!
  • 相关阅读:
    vue 防抖 节流
    数组取最小数据长度,确定长度截取,看是否全等 ,全等通过不等提示,需要拆分
    数组去重取不重复的数据
    vue
    vue2.0 子组件获取父组件值 使用v-model可渲染不能更改
    使用mpvue 开发小程序 遇到的坑
    ztree 样式更改
    vue 跨域请求
    记录 vue2.0 再使用过程中遇到的问题
    bug
  • 原文地址:https://www.cnblogs.com/sufei/p/1969602.html
Copyright © 2011-2022 走看看