`
txf2004
  • 浏览: 6866683 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

C#仿QQ皮肤-基窗体FunctionFormBase的实现

 
阅读更多

C#仿QQ皮肤-实现原理系列文章导航
http://www.cnblogs.com/sufei/archive/2010/03/10/1682847.html

一周要过去了,本来打算多写点的,还是时间不够啊,费话不多说,开始写代码,今天 我们要做的是一个窗体,这个窗体是基于窗体FormBase,就是我们上一节所说到的FormBase与基用户控件FormBase1的实现 里面的FormBase窗体,有关FormBase的实现还请大家去看相应文章,这里不再做过多的说明。

我们先看一下实现的效果吧,第一张图是实现,第二张是正常使用时的样子

下面看一下怎么实现吧,

第一步,创建窗体

我们右键单击文件夹选择添加窗体就行了,名称当时是“FunctionFormBase”,然后单击确定,我们的窗体的大小不需要做任何的修改,那是因为那是继承自窗体FormBase而来的,上节我们讲过了, 他的大小是固定的,所以在这里不用再做设置;

只要这样一行继承的语句就OK了

///<summary>
///FunctionFormBase基窗体
///是构造EntryForm和SkinForm窗体的基础
///</summary>
publicpartialclassFunctionFormBase:FormBase

第二步,窗体的UI布局实现

我们可以看到第一张图,就是窗体的UI布局,相信大家一看就能明白是怎么实现 的,我还是大致的说一下是怎么会事吧。窗体一共是三个Panel

代码实现为:

代码
//
//ptbTopMiddle
//
this.ptbTopMiddle.Dock=System.Windows.Forms.DockStyle.Fill;
this.ptbTopMiddle.Location=newSystem.Drawing.Point(10,0);
this.ptbTopMiddle.Name="ptbTopMiddle";
this.ptbTopMiddle.Size=newSystem.Drawing.Size(669,31);
this.ptbTopMiddle.TabIndex=2;
this.ptbTopMiddle.TabStop=false;

//pnlBackGroup
//
this.pnlBackGroup.BackgroundImageLayout=System.Windows.Forms.ImageLayout.Stretch;
this.pnlBackGroup.Dock=System.Windows.Forms.DockStyle.Fill;
this.pnlBackGroup.Location=newSystem.Drawing.Point(0,31);
this.pnlBackGroup.Name="pnlBackGroup";
this.pnlBackGroup.Size=newSystem.Drawing.Size(689,444);
this.pnlBackGroup.TabIndex=9;

//
//ptbBottomMiddle
//
this.ptbBottomMiddle.Dock=System.Windows.Forms.DockStyle.Fill;
this.ptbBottomMiddle.Location=newSystem.Drawing.Point(10,0);
this.ptbBottomMiddle.Name="ptbBottomMiddle";
this.ptbBottomMiddle.Size=newSystem.Drawing.Size(669,37);
this.ptbBottomMiddle.TabIndex=3;

ptbTopMiddle左面是一个lblText 右面是两个CommandButton,这个控件是 我自己写的实现方法后面会提到这里不做详细说明,在ptbTopMiddle的两端分别是两个Panel,用来实现窗体的边角,和低部的ptbBottomMiddle 形式是一样的,下面我给出这些控件的初始代码

,我是通过Controls.Remove方法来实现 的,具体的代码如下所示

代码
//移除FormBase现有控件
this.Controls.Remove(this.pnlRight);
this.Controls.Remove(this.pnlLeft);
this.Controls.Remove(this.pnlBackGroup);
this.Controls.Remove(this.pnlCaption);
this.Controls.Remove(this.pnlBottom);

好了我们的布局就到这里吧

第三步,ptbTopMiddle功能实现

因为我们的窗体是一个Panel,所以在移动和鼠标松开时的效果要处理一下,先说一下标题和最小化吧

标题是个Label,我们需要重写定义一下,怎么样来实现呢,我们只要重写一下窗体的Text属性就行了。实现如下

代码

//最小化
publicnewboolMinimizeBox
{
get
{
returnbase.MinimizeBox;
}
set
{
base.MinimizeBox=value;
this.btnMin.Visible=value;
}
}

还有最后一个关闭按钮,这个更简单了,一个Close方法搞定

//关闭按钮
privatevoidbtnClose_Click(objectsender,EventArgse)
{
this.Close();
}

第四步,窗体移动效果

我们的窗体是没有实际的标题的所以 在这里要处理一下移动时的效果

在这里用到了一些Api,具体的说明 请大家参考代码中的类文章Win32类 ,一共有两个方法一个是鼠标移动时的方法

代码
//鼠标松开时
privatevoidcaption_MouseUp(objectsender,MouseEventArgse)
{
if(e.Button==MouseButtons.Right&&((Control)sender).Cursor==Cursors.Default&&e.Y<=SystemInformation.CaptionHeight)
{
Win32.TrackPopupMenu(Win32.GetSystemMenu(Handle,
0).ToInt32(),2,Cursor.Position.X,Cursor.Position.Y,0,Handle,0);
}
}

第五步,窗体样式 实现

样式方面第一个重点就是Windows消息的处理,跟其实窗体的实现原理是一样的,不同 是WindowsApi和消息,因为消息在这里还要用的到所以我加了个ref,呵呵 ,ref(ref 关键字使参数按引用传递。其效果是,当控制权传递回调用方法时,在方法中对参数所做的任何更改都将反映在该变量中)

代码
///<summary>
///Windows消息处理
///</summary>
///<paramname="m">Message</param>
protectedoverridevoidWndProc(refMessagem)
{
switch(m.Msg)
{
caseWin32.WM_COMMAND:
Win32.SendMessage(Handle,Win32.WM_SYSCOMMAND,(
int)m.WParam,(int)m.LParam);
break;
caseWin32.WM_SYSCOMMAND:
base.WndProc(refm);

if(m.WParam.ToInt64()==Win32.SC_RESTORE)
{
this.Height+=6;
this.Width+=6;
}
elseif(m.WParam.ToInt64()==Win32.SC_MAXIMIZE)
{
Application.DoEvents();
}

break;
default:
base.WndProc(refm);
break;
}
}

这个窗体的样式 除了Windows消息还有一个ReSetFormBitmap方法,因为这个方法是FromBase窗体 里我们在这里需要重写一下,

跟原先的方法实现是一样的,只是我要改几张图片,呵呵

代码
///<summary>
///设置窗体样式
///</summary>
publicoverridevoidReSetFormBitmap()
{
this.pnlCaption.BackgroundImage=Image.FromStream(Shared.AssemblyWinUI.GetManifestResourceStream("CRD.WinUI.Resources.Common.dialog2009.bordertm.bmp"));
this.ptbTopLeft.BackgroundImage=Image.FromStream(Shared.AssemblyWinUI.GetManifestResourceStream("CRD.WinUI.Resources.Common.dialog2009.bordertl.bmp"));
this.ptbTopMiddle.BackgroundImage=Image.FromStream(Shared.AssemblyWinUI.GetManifestResourceStream("CRD.WinUI.Resources.Common.dialog2009.bordertm.bmp"));
this.ptbTopRight.BackgroundImage=Image.FromStream(Shared.AssemblyWinUI.GetManifestResourceStream("CRD.WinUI.Resources.Common.dialog2009.bordertr.bmp"));

this.ptbLeft.BackgroundImage=Image.FromStream(Shared.AssemblyWinUI.GetManifestResourceStream("CRD.WinUI.Resources.Common.dialog2009.borderml.bmp"));
this.ptbRight.BackgroundImage=Image.FromStream(Shared.AssemblyWinUI.GetManifestResourceStream("CRD.WinUI.Resources.Common.dialog2009.bordermr.bmp"));

this.ptbBottomLeft.BackgroundImage=Image.FromStream(Shared.AssemblyWinUI.GetManifestResourceStream("CRD.WinUI.Resources.Common.dialog2009.borderbl.bmp"));
this.ptbBottomMiddle.BackgroundImage=Image.FromStream(Shared.AssemblyWinUI.GetManifestResourceStream("CRD.WinUI.Resources.Common.dialog2009.borderbm.bmp"));
this.ptbBottomRight.BackgroundImage=Image.FromStream(Shared.AssemblyWinUI.GetManifestResourceStream("CRD.WinUI.Resources.Common.dialog2009.borderbr.bmp"));

this.pnlBackGroup.BackgroundImage=Image.FromStream(Shared.AssemblyWinUI.GetManifestResourceStream("CRD.WinUI.Resources.Common.dialog2009.bg.bmp"));

BitmapcloseBitmap
=newBitmap(Bitmap.FromStream(Shared.AssemblyWinUI.GetManifestResourceStream("CRD.WinUI.Resources.MainWin.Button.CloseBtn.bmp")));
this.btnClose.NormalImage=closeBitmap.Clone(newRectangle(0,0,37,22),PixelFormat.Format64bppPArgb);
this.btnClose.MouseMoveImage=closeBitmap.Clone(newRectangle(37,0,37,22),PixelFormat.Format64bppPArgb);
this.btnClose.MouseDownImage=closeBitmap.Clone(newRectangle(74,0,37,22),PixelFormat.Format64bppPArgb);

BitmapminBitmap
=newBitmap(Bitmap.FromStream(Shared.AssemblyWinUI.GetManifestResourceStream("CRD.WinUI.Resources.MainWin.Button.MinBtn.bmp")));
this.btnMin.NormalImage=minBitmap.Clone(newRectangle(0,0,31,22),PixelFormat.Format64bppPArgb);
this.btnMin.MouseMoveImage=minBitmap.Clone(newRectangle(31,0,31,22),PixelFormat.Format64bppPArgb);
this.btnMin.MouseDownImage=minBitmap.Clone(newRectangle(62,0,31,22),PixelFormat.Format64bppPArgb);

this.CurrentSkinColor=SkinColor.Default;
}

文章中用到的所有素材请大家到源文件中去查找这里不再做过多的说明

到这里基本全部实现了,更具体的还请大家参考 源代码

老规矩这里附上窗体的所有实现 代码

代码
usingSystem;
usingSystem.Collections.Generic;
usingSystem.ComponentModel;
usingSystem.Data;
usingSystem.Drawing;

usingSystem.Text;
usingSystem.Windows.Forms;
usingCRD.Common;
usingSystem.Drawing.Imaging;

namespaceCRD.WinUI.Forms
{
///<summary>
///FunctionFormBase基窗体
///是构造EntryForm和SkinForm窗体的基础
///</summary>
publicpartialclassFunctionFormBase:FormBase
{
//构造器
publicFunctionFormBase()
{
//设置默认的皮肤
this.SetStyle(ControlStyles.DoubleBuffer|ControlStyles.AllPaintingInWmPaint,true);

InitializeComponent();

//移除FormBase现有控件
this.Controls.Remove(this.pnlRight);
this.Controls.Remove(this.pnlLeft);
this.Controls.Remove(this.pnlBackGroup);
this.Controls.Remove(this.pnlCaption);
this.Controls.Remove(this.pnlBottom);
}

///<summary>
///Windows消息处理
///</summary>
///<paramname="m">Message</param>
protectedoverridevoidWndProc(refMessagem)
{
switch(m.Msg)
{
caseWin32.WM_COMMAND:
Win32.SendMessage(Handle,Win32.WM_SYSCOMMAND,(
int)m.WParam,(int)m.LParam);
break;
caseWin32.WM_SYSCOMMAND:
base.WndProc(refm);

if(m.WParam.ToInt64()==Win32.SC_RESTORE)
{
this.Height+=6;
this.Width+=6;
}
elseif(m.WParam.ToInt64()==Win32.SC_MAXIMIZE)
{
Application.DoEvents();
}

break;
default:
base.WndProc(refm);
break;
}
}

///<summary>
///设置窗体样式
///</summary>
publicoverridevoidReSetFormBitmap()
{
this.pnlCaption.BackgroundImage=Image.FromStream(Shared.AssemblyWinUI.GetManifestResourceStream("CRD.WinUI.Resources.Common.dialog2009.bordertm.bmp"));
this.ptbTopLeft.BackgroundImage=Image.FromStream(Shared.AssemblyWinUI.GetManifestResourceStream("CRD.WinUI.Resources.Common.dialog2009.bordertl.bmp"));
this.ptbTopMiddle.BackgroundImage=Image.FromStream(Shared.AssemblyWinUI.GetManifestResourceStream("CRD.WinUI.Resources.Common.dialog2009.bordertm.bmp"));
this.ptbTopRight.BackgroundImage=Image.FromStream(Shared.AssemblyWinUI.GetManifestResourceStream("CRD.WinUI.Resources.Common.dialog2009.bordertr.bmp"));

this.ptbLeft.BackgroundImage=Image.FromStream(Shared.AssemblyWinUI.GetManifestResourceStream("CRD.WinUI.Resources.Common.dialog2009.borderml.bmp"));
this.ptbRight.BackgroundImage=Image.FromStream(Shared.AssemblyWinUI.GetManifestResourceStream("CRD.WinUI.Resources.Common.dialog2009.bordermr.bmp"));

this.ptbBottomLeft.BackgroundImage=Image.FromStream(Shared.AssemblyWinUI.GetManifestResourceStream("CRD.WinUI.Resources.Common.dialog2009.borderbl.bmp"));
this.ptbBottomMiddle.BackgroundImage=Image.FromStream(Shared.AssemblyWinUI.GetManifestResourceStream("CRD.WinUI.Resources.Common.dialog2009.borderbm.bmp"));
this.ptbBottomRight.BackgroundImage=Image.FromStream(Shared.AssemblyWinUI.GetManifestResourceStream("CRD.WinUI.Resources.Common.dialog2009.borderbr.bmp"));

this.pnlBackGroup.BackgroundImage=Image.FromStream(Shared.AssemblyWinUI.GetManifestResourceStream("CRD.WinUI.Resources.Common.dialog2009.bg.bmp"));

BitmapcloseBitmap
=newBitmap(Bitmap.FromStream(Shared.AssemblyWinUI.GetManifestResourceStream("CRD.WinUI.Resources.MainWin.Button.CloseBtn.bmp")));
this.btnClose.NormalImage=closeBitmap.Clone(newRectangle(0,0,37,22),PixelFormat.Format64bppPArgb);
this.btnClose.MouseMoveImage=closeBitmap.Clone(newRectangle(37,0,37,22),PixelFormat.Format64bppPArgb);
this.btnClose.MouseDownImage=closeBitmap.Clone(newRectangle(74,0,37,22),PixelFormat.Format64bppPArgb);

BitmapminBitmap
=newBitmap(Bitmap.FromStream(Shared.AssemblyWinUI.GetManifestResourceStream("CRD.WinUI.Resources.MainWin.Button.MinBtn.bmp")));
this.btnMin.NormalImage=minBitmap.Clone(newRectangle(0,0,31,22),PixelFormat.Format64bppPArgb);
this.btnMin.MouseMoveImage=minBitmap.Clone(newRectangle(31,0,31,22),PixelFormat.Format64bppPArgb);
this.btnMin.MouseDownImage=minBitmap.Clone(newRectangle(62,0,31,22),PixelFormat.Format64bppPArgb);

this.CurrentSkinColor=SkinColor.Default;
}

///<summary>
///重写的OnLoad
///</summary>
protectedoverridevoidOnLoad(EventArgse)
{
this.Controls.Add(this.pnlRight);
this.Controls.Add(this.pnlLeft);
this.Controls.Add(this.pnlBackGroup);
this.Controls.Add(this.pnlCaption);
this.Controls.Add(this.pnlBottom);

if(!DesignMode)
{
this.Hide();
}

base.OnLoad(e);

Win32.SetWindowLong(
this.Handle,-16,Win32.GetWindowLong(this.Handle,-16)-Win32.WS_MAXIMIZEBOX);

this.Show();
}

//关闭按钮
privatevoidbtnClose_Click(objectsender,EventArgse)
{
this.Close();
}

//最小化
privatevoidbtnMin_Click(objectsender,EventArgse)
{
this.WindowState=FormWindowState.Minimized;
}

//移动标题时
privatevoidCaption_MouseMove(objectsender,MouseEventArgse)
{
((Control)sender).Cursor
=Cursors.Default;
if(e.Button==MouseButtons.Left)
{
Win32.ReleaseCapture();
Win32.SendMessage(Handle,
274,61440+9,0);
}
}

//标题
publicoverridestringText
{
get
{
returnbase.Text;
}
set
{
base.Text=value;
if(this.lblText!=null)
this.lblText.Text=this.Text;
}
}

//最小化
publicnewboolMinimizeBox
{
get
{
returnbase.MinimizeBox;
}
set
{
base.MinimizeBox=value;
this.btnMin.Visible=value;
}
}

//鼠标松开时
privatevoidcaption_MouseUp(objectsender,MouseEventArgse)
{
if(e.Button==MouseButtons.Right&&((Control)sender).Cursor==Cursors.Default&&e.Y<=SystemInformation.CaptionHeight)
{
Win32.TrackPopupMenu(Win32.GetSystemMenu(Handle,
0).ToInt32(),2,Cursor.Position.X,Cursor.Position.Y,0,Handle,0);
}
}

}
}

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics