首写这篇文章之前先跟大家说声抱歉,我很少写这方面的文章,所以一直不敢动手,之前的文章确实不带源的,因为当时只是想做为自己初次开发的记录过程,打算程序开发完后再来贴源的。不过从现在开始,我觉定还是把自己每次写的控件实例写出来,和大家一起探讨研究,这样也可增加自己学习经验。

  在这里先跟大家说一下,由于我也是菜鸟型人物,C#、Winform完全是因为兴趣爱好而自学的,所以很不专业,里面的一些说明、注释都是跟据我自己的理解来说明的,如果因为我的错误而对大家的造成误导,在这里我表示歉意,同时我希望大家能指出来,我会予以改正。

  我现们现在进入正题(基本以后用到GDI+会很多,所以GDI要学习一下,虽然我也不怎么会,但建议去看下,推荐一个网站:点击进入)

  效果如果:

  

  

  一.说明:

   1.提取QQ2010版的皮肤数据:因为我的程序皮肤是基于QQ的皮肤,所以我们要先提取出QQ的皮肤文件(当然,你也可以自己用PS做皮肤)。QQ的皮肤文件在QQ安装目录的一个名为Res.rdb打包文件里,要提取里同的皮肤文件,我要先解压他(工具:RDB打包解包工具)图如下。

    

    [基本上以后控件美化都会用到里面的皮肤文件]

2.窗口皮肤制作概要说明:QQ的窗口看上去是有光泽效果的,制作光泽效果是其实是一张半透明的PNG图片画在在窗口区域里。例如图

    

    看是去是不是有点明白了,所以我们要做的就是根据要求选一个透明的PNG图片,根据窗口大小画上去。

  二.制作(详细的自己看里面代码)

   1.在工程里新建一个(AlBaseForm.cs)代码窗口

   类文件     

代码

// 作者:阿龙(Along)
// QQ号:646494711
// QQ群:57218890
// 网站: http://www.8timer.com
// 博客: http://www.cnblogs.com/Along729/
// 声明:未经作者许可,任何人不得发布出售该源码,请尊重别人的劳动成果,谢谢大家支持
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing.Drawing2D;
using AlSkin.AlClass;

namespace AlSkin.AlForm
{
public partial class AlBaseForm : Form
{
#region 声明
private Bitmap _BacklightImg; // 窗体光泽背景图片
private Rectangle _BacklightLTRB; // 窗体光泽重绘边界
private int _RgnRadius = 4 ; // 设置窗口圆角
private int Rgn;
private Graphics g;
private bool _IsResize = true ; // 是否允许改变窗口大小
private FormSystemBtn _FormSystemBtnSet = FormSystemBtn.SystemAll;
private Bitmap btn_closeImg = ImageObject.GetResBitmap( " AlSkin.AlSkinImg.AlFormImg.btn_close.png " );
private Bitmap btn_maxImg = ImageObject.GetResBitmap( " AlSkin.AlSkinImg.AlFormImg.btn_max.png " );
private Bitmap btn_miniImg = ImageObject.GetResBitmap( " AlSkin.AlSkinImg.AlFormImg.btn_mini.png " );
private Bitmap btn_restoreImg = ImageObject.GetResBitmap( " AlSkin.AlSkinImg.AlFormImg.btn_restore.png " );
// 枚举系统按钮状态
public enum FormSystemBtn
{
SystemAll = 0 ,
SystemNo = 1 ,
btn_close = 2 ,
btn_miniAndbtn_close = 3 ,
btn_maxAndbtn_close = 4
}
#endregion

#region 构造函数
public AlBaseForm()
{
InitializeComponent();
this .SetStyle(ControlStyles.UserPaint, true ); // 自绘
this .SetStyle(ControlStyles.DoubleBuffer, true ); // 双缓冲
this .SetStyle(ControlStyles.ResizeRedraw, true ); // 调整大小时重绘
this .SetStyle(ControlStyles.AllPaintingInWmPaint, true ); // 禁止擦除背景.
this .SetStyle(ControlStyles.OptimizedDoubleBuffer, true ); // 双缓冲
// this.SetStyle(ControlStyles.Opaque, true); // 如果为真,控件将绘制为不透明,不绘制背景
this .SetStyle(ControlStyles.SupportsTransparentBackColor, true ); // 透明效果
SystemBtnSet();

}
#endregion

#region 属性

[DefaultValue( 4 )]
[CategoryAttribute( " 阿龙窗口属性 " ), Description( " 设置窗口圆角半径 " )]
public int RgnRadius
{
get { return this ._RgnRadius; }
set {
_RgnRadius = value;
this .Invalidate();
}

}

[CategoryAttribute( " 阿龙窗口属性 " ), Description( " 设置窗体光泽背景 " )]
public Bitmap BacklightImg
{

get { return this ._BacklightImg; }
set {
_BacklightImg = value;
this .Invalidate();
}
}

[CategoryAttribute( " 阿龙窗口属性 " ), Description( " 设置窗体光泽背景重绘边界,例如 10,10,10,10 " )]
public Rectangle BacklightLTRB
{

get { return this ._BacklightLTRB; }
set {
_BacklightLTRB = value;
if (_BacklightLTRB != Rectangle.Empty)
{
this .Invalidate();
}
}
}

[DefaultValue( true )]
[CategoryAttribute( " 阿龙窗口属性 " ), Description( " 是否允许改变窗口大小 " )]
public bool IsResize
{
get { return this ._IsResize; }
set { _IsResize = value;}
}

[CategoryAttribute( " 阿龙窗口属性 " ), Description( " 系统按钮设置 " )]
public FormSystemBtn FormSystemBtnSet
{
get
{
return _FormSystemBtnSet;
}
set
{
_FormSystemBtnSet = value;
this .Invalidate();

}
}
#endregion

#region 重写方法
protected override void OnInvalidated(InvalidateEventArgs e)
{
SetReion();
SystemBtnSet();
base .OnInvalidated(e);

}

// 重绘窗口
protected override void OnPaint(PaintEventArgs e)
{
try
{
g = e.Graphics;
g.SmoothingMode = SmoothingMode.HighQuality; // 高质量
g.PixelOffsetMode = PixelOffsetMode.HighQuality; // 高像素偏移质量
ImageDrawRect.DrawRect(g, _BacklightImg, ClientRectangle, Rectangle.FromLTRB(_BacklightLTRB.X, _BacklightLTRB.Y, _BacklightLTRB.Width, _BacklightLTRB.Height), 1 , 1 );
}
catch
{ }
}
// 重载WndProc方法
protected override void WndProc( ref Message m)
{
try
{
switch (m.Msg)
{
// 窗体客户区以外的重绘消息,一般是由系统负责处理
case Win32.WM_NCPAINT:
break ;
// 画窗体被激活或者没有被激活时的样子 // http://blog.csdn.net/commandos/archive/2007/11/27/1904558.aspx
case Win32.WM_NCACTIVATE:
if (m.WParam == (IntPtr)Win32.WM_FALSE)
{
m.Result = (IntPtr)Win32.WM_TRUE;
}
break ;
// 在需要计算窗口客户区的大小和位置时发送。通过处理这个消息,应用程序可以在窗口大小或位置改变时控制客户区的内容
case Win32.WM_NCCALCSIZE:
break ;
// 鼠标移动,按下或释放都会执行该消息
case Win32.WM_NCHITTEST:
WM_NCHITTEST( ref m);
break ;
default :
base .WndProc( ref m);
break ;
}
}
catch { }
}

#endregion

#region 方法
protected void SystemBtnSet()
{
switch (( int )_FormSystemBtnSet)
{
case 0 :
btn_close.BackImg = btn_closeImg;
btn_close.Location = new Point( this .Width - 43 , 6 );
btn_mini.BackImg = btn_miniImg;
btn_mini.Location = new Point( this .Width - 93 , 6 );
btn_max.BackImg = btn_maxImg;
btn_restore.BackImg = btn_restoreImg;
if (WindowState == FormWindowState.Normal)
{
btn_max.Location = new Point( this .Width - 68 , 6 );
btn_restore.Location = new Point( this .Width - 68 , - 20 );
}
else
{
btn_max.Location = new Point( this .Width - 68 , - 20 );
btn_restore.Location = new Point( this .Width - 68 , 6 );
}
break ;
case 1 :
btn_close.BackImg = btn_closeImg;
btn_close.Location = new Point( this .Width - 43 , - 20 );
btn_max.BackImg = btn_maxImg;
btn_max.Location = new Point( this .Width - 68 , - 20 );
btn_mini.BackImg = btn_miniImg;
btn_mini.Location = new Point( this .Width - 93 , - 20 );
btn_restore.BackImg = btn_restoreImg;
btn_restore.Location = new Point( this .Width - 68 , - 20 );
break ;
case 2 :
btn_close.BackImg = btn_closeImg;
btn_close.Location = new Point( this .Width - 43 , 6 );
btn_max.BackImg = btn_maxImg;
btn_max.Location = new Point( this .Width - 68 , - 20 );
btn_mini.BackImg = btn_miniImg;
btn_mini.Location = new Point( this .Width - 93 , - 20 );
btn_restore.BackImg = btn_restoreImg;
btn_restore.Location = new Point( this .Width - 68 , - 20 );
break ;
case 3 :
btn_close.BackImg = btn_closeImg;
btn_close.Location = new Point( this .Width - 43 , 6 );
btn_max.BackImg = btn_maxImg;
btn_max.Location = new Point( this .Width - 68 , - 20 );
btn_mini.BackImg = btn_miniImg;
btn_mini.Location = new Point( this .Width - 68 , 6 );
btn_restore.BackImg = btn_restoreImg;
btn_restore.Location = new Point( this .Width - 68 , - 20 );
break ;
case 4 :
btn_close.BackImg = btn_closeImg;
btn_close.Location = new Point( this .Width - 43 , 6 );
btn_mini.BackImg = btn_miniImg;
btn_mini.Location = new Point( this .Width - 93 , - 20 );
btn_max.BackImg = btn_maxImg;
btn_restore.BackImg = btn_restoreImg;
if (WindowState == FormWindowState.Normal)
{
btn_max.Location = new Point( this .Width - 68 , 6 );
btn_restore.Location = new Point( this .Width - 68 , - 20 );
}
else
{
btn_max.Location = new Point( this .Width - 68 , - 20 );
btn_restore.Location = new Point( this .Width - 68 , 6 );
}
break ;

}

}
/// <summary>
/// 给窗口圆角
/// </summary>
protected void SetReion()
{
Rgn = Win32.CreateRoundRectRgn( 5 , 5 , ClientRectangle.Width - 4 , ClientRectangle.Height - 4 , _RgnRadius, _RgnRadius);
Win32.SetWindowRgn( this .Handle, Rgn, true );
}
private void WM_NCHITTEST( ref Message m)
{
int wparam = m.LParam.ToInt32();
Point point = new Point(Win32.LOWORD(wparam),Win32.HIWORD(wparam));
point = PointToClient(point);
if (_IsResize)
{
if (point.X <= 8 )
{
if (point.Y <= 8 )
m.Result = (IntPtr)Win32.HTTOPLEFT;
else if (point.Y > Height - 8 )
m.Result = (IntPtr)Win32.HTBOTTOMLEFT;
else
m.Result = (IntPtr)Win32.HTLEFT;
}
else if (point.X >= Width - 8 )
{
if (point.Y <= 8 )
m.Result = (IntPtr)Win32.HTTOPRIGHT;
else if (point.Y >= Height - 8 )
m.Result = (IntPtr)Win32.HTBOTTOMRIGHT;
else
m.Result = (IntPtr)Win32.HTRIGHT;
}
else if (point.Y <= 8 )
{
m.Result = (IntPtr)Win32.HTTOP;
}
else if (point.Y >= Height - 8 )
m.Result = (IntPtr)Win32.HTBOTTOM;
else
m.Result = (IntPtr)Win32.HTCAPTION;
}
else
{ m.Result = (IntPtr)Win32.HTCAPTION; }
}
#endregion

#region 事件
private void btn_close_Click( object sender, EventArgs e)
{
this .Close();
}
private void btn_mini_Click( object sender, EventArgs e)
{
this .WindowState = FormWindowState.Minimized;
}

private void btn_max_Click( object sender, EventArgs e)
{
this .WindowState = FormWindowState.Maximized;
}

private void btn_restore_Click( object sender, EventArgs e)
{
this .WindowState = FormWindowState.Normal;
}
#endregion
}
}

我先声明几个变量 

代码

private Bitmap _BacklightImg; // 窗体光泽背景图片
private Rectangle _BacklightLTRB; // 窗体光泽重绘边界
private int _RgnRadius = 4 ; // 设置窗口圆角
private int Rgn;
private Graphics g;
private bool _IsResize = true ; // 是否允许改变窗口大小
private FormSystemBtn _FormSystemBtnSet = FormSystemBtn.SystemAll;
private Bitmap btn_closeImg = ImageObject.GetResBitmap( " AlSkin.AlSkinImg.AlFormImg.btn_close.png " );
private Bitmap btn_maxImg = ImageObject.GetResBitmap( " AlSkin.AlSkinImg.AlFormImg.btn_max.png " );
private Bitmap btn_miniImg = ImageObject.GetResBitmap( " AlSkin.AlSkinImg.AlFormImg.btn_mini.png " );
private Bitmap btn_restoreImg = ImageObject.GetResBitmap( " AlSkin.AlSkinImg.AlFormImg.btn_restore.png " );

通过自定义一些属性,后期可以定制自己的窗口效果

代码

#region 属性

[DefaultValue( 4 )]
[CategoryAttribute( " 阿龙窗口属性 " ), Description( " 设置窗口圆角半径 " )]
public int RgnRadius
{
get { return this ._RgnRadius; }
set {
_RgnRadius = value;
this .Invalidate();
}

}

[CategoryAttribute( " 阿龙窗口属性 " ), Description( " 设置窗体光泽背景 " )]
public Bitmap BacklightImg
{

get { return this ._BacklightImg; }
set {
_BacklightImg = value;
this .Invalidate();
}
}

[CategoryAttribute( " 阿龙窗口属性 " ), Description( " 设置窗体光泽背景重绘边界,例如 10,10,10,10 " )]
public Rectangle BacklightLTRB
{

get { return this ._BacklightLTRB; }
set {
_BacklightLTRB = value;
if (_BacklightLTRB != Rectangle.Empty)
{
this .Invalidate();
}
}
}

[DefaultValue( true )]
[CategoryAttribute( " 阿龙窗口属性 " ), Description( " 是否允许改变窗口大小 " )]
public bool IsResize
{
get { return this ._IsResize; }
set { _IsResize = value;}
}

[CategoryAttribute( " 阿龙窗口属性 " ), Description( " 系统按钮设置 " )]
public FormSystemBtn FormSystemBtnSet
{
get
{
return _FormSystemBtnSet;
}
set
{
_FormSystemBtnSet = value;
this .Invalidate();

}
}
#endregio

调用API 给窗口圆角

代码

/// <summary>
/// 给窗口圆角
/// </summary>
protected void SetReion()
{
Rgn = Win32.CreateRoundRectRgn( 5 , 5 , ClientRectangle.Width - 4 , ClientRectangle.Height - 4 , _RgnRadius, _RgnRadius);
Win32.SetWindowRgn( this .Handle, Rgn, true );
}

通过重载 OnPaint方法,把带光泽效果的PNG图片图上去

代码

// 重绘窗口
protected override void OnPaint(PaintEventArgs e)
{
try
{
g = e.Graphics;
g.SmoothingMode = SmoothingMode.HighQuality; // 高质量
g.PixelOffsetMode = PixelOffsetMode.HighQuality; // 高像素偏移质量
ImageDrawRect.DrawRect(g, _BacklightImg, ClientRectangle, Rectangle.FromLTRB(_BacklightLTRB.X, _BacklightLTRB.Y, _BacklightLTRB.Width, _BacklightLTRB.Height), 1 , 1 );
}
catch
{ }
}

通过重 重载WndProc方法 拦截窗口消息实现对窗口拖大缩小,系统按钮功能操作

代码

// 重载WndProc方法
protected override void WndProc( ref Message m)
{
try
{
switch (m.Msg)
{
// 窗体客户区以外的重绘消息,一般是由系统负责处理
case Win32.WM_NCPAINT:
break ;
// 画窗体被激活或者没有被激活时的样子 // http://blog.csdn.net/commandos/archive/2007/11/27/1904558.aspx
case Win32.WM_NCACTIVATE:
if (m.WParam == (IntPtr)Win32.WM_FALSE)
{
m.Result = (IntPtr)Win32.WM_TRUE;
}
break ;
// 在需要计算窗口客户区的大小和位置时发送。通过处理这个消息,应用程序可以在窗口大小或位置改变时控制客户区的内容
case Win32.WM_NCCALCSIZE:
break ;
// 鼠标移动,按下或释放都会执行该消息
case Win32.WM_NCHITTEST:
WM_NCHITTEST( ref m);
break ;
default :
base .WndProc( ref m);
break ;
}
}
catch { }

 三.窗口功能介绍

  

  通过自定义的属性可以改变窗口的一些效果:

  BacklightImg;//窗体光泽PNG图片 可自己定义QQ所有窗口效果基本上可以从这里设置

  BacklightLTRB;//窗体光泽重绘边界 一般窗体都要可随意大小化,这时参数可以设置 光泽PNG图,不会随着窗体的大小而变形

  指定同比放大缩小的距离

  FormSystemBtnSet;//窗口系统按钮设定

       SystemAll //显示全部

SystemNo//全部不显示

btn_close//只显示关闭按钮

btn_miniAndbtn_close//显示最小化与关闭按钮

     btn_maxAndbtn_close //显示最大化与关闭按钮

  IsResize;//是否允许改变窗口大小 (这个指限定鼠标拖动放大缩小窗口,完全限制请用FormBorderStyle属性)

  RgnRadius;//设置窗口圆角的大小

   好了,就写到这里,详细里可以参考源码。

  以前做的控件窗口虽然效果有点类似QQ,但不完善,结构比较混乱,我的目标是做出一套完全通用的QQ控件库出来.

  有什么错误或意见请回复我,我会予以改正,请大家多支持

  哇,测试加发布,就到12点了,先睡了,改天有空再更新!如果大家有兴趣请加群 57218890

源码下载

Sorry ,发现网站的服务器出了问题上,空间里面的数据全没了,链过来的文件已全失效,请等待恢复。如果大家愿意,请进

QQ群 57218890 里面都有备份,以后有更新也会传上去,在这里跟大家说一下!

转载于:https://www.cnblogs.com/Along729/archive/2010/12/05/Along.html

C# 高仿腾讯QQ (窗口皮肤美化)(附测试源码)相关推荐

  1. C# 高仿腾讯QQ (TextBox控件美化)(附源码)

    接上一篇<C# 高仿腾讯QQ (Bottom控件美化) > 这篇来说一下QQ皮肤TextBox控件的美化: (1).已修正 每次窗口最小化以后再还原会发现窗口底部往下移了几十个像素(但还不 ...

  2. 高仿腾讯 QQ,已经实现了纯文本,表情,图片,语音,位置等信息的发送。

    QQ 项目地址:HuTianQi/QQ 简介:高仿腾讯 QQ,已经实现了纯文本,表情,图片,语音,位置等信息的发送. 一款高仿腾讯 QQ 的 IM 软件,基于 bmob SDK,已经实现聊天,表情,图 ...

  3. html5互动场景制作系统,春哥技术博客高仿易企秀H5场景应用制作平台源码V1.0正式版发布...

    经过一个月的艰苦努力,春哥团队最新作品即将与大家见面了,<2015年6月春哥技术博客高仿易企秀H5场景应用制作平台源码V1.0正式版>即将来临, 现在春哥接受预定啦,春哥技术博客依然走价格 ...

  4. 高仿砍柴网自媒体新闻资讯网站源码(织梦DEDE内核+手机WAP版)

    高仿砍柴网自媒体新闻资讯网站源码(织梦DEDE内核+手机WAP版)下载地址: http://download.csdn.net/detail/chenhao0568/9312019#comment 安 ...

  5. html5仿腾讯,高仿腾讯QQ Xplan(X计划)的H5页面(1):threejs创建地球

    上个月底,在朋友圈看到一个号称"这可能是地球上最美的h5"的分享,点进入后发现这个h5还很别致,思考了一会,决定要不高仿一个? 到今天为止,高仿基本完成, 除了手机端的media控 ...

  6. C# 高仿腾讯QQ (实现QQ好友列表-基于ListBox的绘法)

    C#实现QQ好友列表,一直是我网上百搜却不得其解的控件,几乎找不到相关的信息,而找到的也不是我想要的那种.不过,曾在CSDN上看过到过网上一位大牛用C++实现QQ好友列表这种效果,当然,对于我这个C+ ...

  7. C#高仿腾讯QQ截图程序

    最近把以前制作的截图程序重新写了一下 动了一个大手术 高质量仿照的TX的截图程序 源码下载1(2012-12-09) http://download.csdn.net/detail/crystal_l ...

  8. Thinkphp高仿《拼多多拼团》商城系统源码 可封装APP 完美运营级

    介绍: [ThinkPHP内核]高仿<拼多多拼团>源码 可封装APP 多用户 完美运营级商城系统支持商家入驻 主要是基于ThinkPHP框架后台管理系统制作,是目前来说最新微信拼团系统.完 ...

  9. 高仿网易云音乐UI的微信小程序源码

    简介: 仿网易云音乐的微信小程序源码,名为YY音乐小程序,首页有每日推荐歌曲.歌单和热歌排行榜,功能不是特别多但是该有的都有. UI特别精致,简直就是克隆的网易云音乐. 源码下载:百度网盘自取 图片:

最新文章

  1. 英伟达首次实现SDF实时3D渲染,还是细节超清晰的那种
  2. mysql体系结构:
  3. 雅客EXCEL(6)-通用表格格式、销售实际案例(总结之前的知识点)
  4. PHP垃圾回收深入理解
  5. Oracle中如何查询一个表的所有字段名和数据类型
  6. 模拟Struts2实现
  7. 靠一强过Excel的工具,3年变成女领导,还把报表做成养老工作
  8. Perl中删除或替换字符串中特殊字符(如空格)的方法
  9. /usr/include/pcap/pcap.h源码
  10. Python解释器配置设置
  11. MFC 键盘鼠标钩子
  12. python接入图灵机器人_Python使用微信接入图灵机器人过程解析
  13. 什么是计算机网络中域名,什么是域名?
  14. [angular1.6]Error: “transition superseded“ ui-router 在angular1.6 报错误问题解决
  15. 七参数/六参数坐标转换(小角度)-- 公共点间接平差
  16. Office 2016 卡顿问题!如果其他方法都没有用就关掉硬件加速!
  17. shell脚本实现批量解析域名IP地址(支持多DNS)
  18. C++人工智能相关书籍
  19. 巡逻机器人(BFS)
  20. xmp打开方式是计算机程序,五步打开XMP文件

热门文章

  1. 在桌面右键菜单添加【切换电源计划】并且有【卓越性能】的选项
  2. caffeine的缓存
  3. 英特尔赋能智能边缘与AI产业,践行环境可持续发展
  4. python sorted原理_深入理解Python的sorted
  5. 一分钟了解什么是限流
  6. 昆山万象汇机器人_9月童趣沙龙活动,现场有你的身影么?
  7. L1-041 寻找250 (10 分)(三种常见的不断输入方法)
  8. 蛋花花讲解web前端助理需要做什么工作
  9. 图像接缝裁剪(seam carving)算法实现-SIGGRAPH 2007
  10. 树莓派4b外置wifi