C#仿QQ皮肤-实现原理系列文章导航
http://www.cnblogs.com/sufei/archive/2010/03/10/1682847.html
大家还是先来看看效果吧
这次之所以一次写两个控件,其实主要是因为Label控件实在是太简单了没有必要放放一个文章里写,所以就一次性来了。
Label控件我就不再多说了,我直接把代码贴一下吧因为就几行代码,相信大家一眼就能看明白了。
using System.Collections.Generic; using System.Text; namespace CRD.WinUI.Misc
{
public class Label:System.Windows.Forms.Label
{
public Label()
: base()
{
this.BackColor = System.Drawing.Color.Transparent;
}
}
}
ListBox实现
咱们从第一行代码就要吧看出来是继承自系统控件而来的。
所以本身就具备了系统的ListBox的一些特性。老方法我们先来看看WndProc方法的实现
{
IntPtr hDC = IntPtr.Zero;
Graphics gdc = null;
switch (m.Msg)
{
case 133:
hDC = Win32.GetWindowDC(m.HWnd);
gdc = Graphics.FromHdc(hDC);
Win32.SendMessage(this.Handle, WM_ERASEBKGND, hDC.ToInt32(), 0);
SendPrintClientMsg();
Win32.SendMessage(this.Handle, WM_PAINT, 0, 0);
OverrideControlBorder(gdc);
m.Result = (IntPtr)1;
Win32.ReleaseDC(m.HWnd, hDC);
gdc.Dispose();
break;
case WM_PAINT:
base.WndProc(ref m);
hDC = Win32.GetWindowDC(m.HWnd);
gdc = Graphics.FromHdc(hDC);
OverrideControlBorder(gdc);
Win32.ReleaseDC(m.HWnd, hDC);
gdc.Dispose();
break;
default:
base.WndProc(ref m);
break;
}
}
这边的实现方法基本上和之前的控件一个样,所以我就不再多说原理了,大家随便看一下前几次的文章就明白了。
下面我们来看一下怎么样换皮肤的事件
也就是说在换皮肤的时候我们应该做那些工作
{
Graphics g = e.Graphics;
//绘制区域
Rectangle r = e.Bounds;
Font fn
= null;if (e.Index >= 0)
{
if (e.State == DrawItemState.None)
{
//设置字体、字符串格式、对齐方式
fn = e.Font;
string s = (string)this.Items[e.Index];
StringFormat sf = new StringFormat();
sf.Alignment = StringAlignment.Near;
//根据不同的状态用不同的颜色表示
if (e.State == (DrawItemState.NoAccelerator | DrawItemState.NoFocusRect))
{
e.Graphics.FillRectangle(new SolidBrush(Color.Red), r);
e.Graphics.DrawString(s, fn, new SolidBrush(Color.Black), r, sf);
e.DrawFocusRectangle();
}
else
{
e.Graphics.FillRectangle(new SolidBrush(Color.White), r);
e.Graphics.DrawString(s, fn, new SolidBrush(Shared.FontColor), r, sf);
e.DrawFocusRectangle();
}
}
else
{
fn = e.Font;
StringFormat sf = new StringFormat();
sf.Alignment = StringAlignment.Near;
string s = (string)this.Items[e.Index];
e.Graphics.FillRectangle(new SolidBrush(Shared.ControlBackColor), r);
e.Graphics.DrawString(s, fn, new SolidBrush(Shared.FontColor), r, sf);
}
}
}
其实这些都不是今天要说的重点,这个控件的实现基础跟之前的一些控件基本上是一样的,像Textbox就和这个差不多,
唯一我想说的是滚动条的实现,不多说了下面开始吧
滚动条的实现
如上面的图片大家已经看到了,图片在我的源代码里都有,我在这里就不多说了,一起来看是怎么实现 的吧,先说说思路,
第一步,先制做一个自己的滚动条,随便做只要自己感觉漂亮就可以,第二步就是,利用Api把Listbox现有的滚动条用现在的滚动条代替,第三步,让现有的滚动条和系统的滚动条实现同步即可。
我实现滚动条的代码,大家也可以自己写这里只是一个参考吧
看一下效果
看一下代码吧,具体的素材大家到我源代码里面找吧,呵呵
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data; using System.Text;
using System.Windows.Forms;
using System.Windows.Forms.Design;
using System.Diagnostics; namespace CRD.WinUI.Misc
{
[Designer(typeof(ScrollbarControlDesigner))]
public partial class CustomScrollbar : UserControl
{
protected Color moChannelColor = Color.Empty;
protected Image moUpArrowImage = null;//上箭头
//protected Image moUpArrowImage_Over = null;
//protected Image moUpArrowImage_Down = null;
protected Image moDownArrowImage = null;//下箭头
//protected Image moDownArrowImage_Over = null;
//protected Image moDownArrowImage_Down = null;
protected Image moThumbArrowImage = null;
protected Image moThumbTopImage = null;
protected Image moThumbTopSpanImage = null;
protected Image moThumbBottomImage = null;
protected Image moThumbBottomSpanImage = null;
protected Image moThumbMiddleImage = null;
protected int moLargeChange = 10;
protected int moSmallChange = 1;
protected int moMinimum = 0;
protected int moMaximum = 100;
protected int moValue = 0;
private int nClickPoint;
protected int moThumbTop = 0;
protected bool moAutoSize = false;
private bool moThumbDown = false;
private bool moThumbDragging = false;
public new event EventHandler Scroll = null;
public event EventHandler ValueChanged = null;
private int GetThumbHeight()
{
int nTrackHeight = (this.Height - (UpArrowImage.Height + DownArrowImage.Height));
float fThumbHeight = ((float)LargeChange / (float)Maximum) * nTrackHeight;
int nThumbHeight = (int)fThumbHeight;
if (nThumbHeight > nTrackHeight)
{
nThumbHeight = nTrackHeight;
fThumbHeight = nTrackHeight;
}
if (nThumbHeight < 56)
{
nThumbHeight = 56;
fThumbHeight = 56;
}
return nThumbHeight;
}
public CustomScrollbar()
{
InitializeComponent();
SetStyle(ControlStyles.ResizeRedraw,
SetStyle(ControlStyles.AllPaintingInWmPaint, true);
SetStyle(ControlStyles.DoubleBuffer, true);
moChannelColor
= Color.FromArgb(51, 166, 3);UpArrowImage = Bitmap.FromStream(Shared.AssemblyWinUI.GetManifestResourceStream("CRD.WinUI.Resources.Common.scroll.uparrow.png"), true, false);// BASSSkin.uparrow;//上箭头
DownArrowImage = Bitmap.FromStream(Shared.AssemblyWinUI.GetManifestResourceStream("CRD.WinUI.Resources.Common.scroll.downarrow.png"), true, false);// BASSSkin.downarrow;//下肩头
ThumbBottomImage = Bitmap.FromStream(Shared.AssemblyWinUI.GetManifestResourceStream("CRD.WinUI.Resources.Common.scroll.ThumbBottom.png"), true, false);// BASSSkin.ThumbBottom;
ThumbMiddleImage = Bitmap.FromStream(Shared.AssemblyWinUI.GetManifestResourceStream("CRD.WinUI.Resources.Common.scroll.ThumbMiddle.png"), true, false);// BASSSkin.ThumbMiddle;
this.Width = UpArrowImage.Width;//18px
base.MinimumSize = new Size(UpArrowImage.Width, UpArrowImage.Height + DownArrowImage.Height + GetThumbHeight());
}
[EditorBrowsable(EditorBrowsableState.Always), Browsable(
true), DefaultValue(false), Category("Behavior"), Description("LargeChange")]public int LargeChange
{
get { return moLargeChange; }
set
{
moLargeChange = value;
Invalidate();
}
}
[EditorBrowsable(EditorBrowsableState.Always), Browsable(
true), DefaultValue(false), Category("Behavior"), Description("SmallChange")]public int SmallChange
{
get { return moSmallChange; }
set
{
moSmallChange = value;
Invalidate();
}
}
[EditorBrowsable(EditorBrowsableState.Always), Browsable(
true), DefaultValue(false), Category("Behavior"), Description("Minimum")]public int Minimum
{
get { return moMinimum; }
set
{
moMinimum = value;
Invalidate();
}
}
[EditorBrowsable(EditorBrowsableState.Always), Browsable(
true), DefaultValue(false), Category("Behavior"), Description("Maximum")]public int Maximum
{
get { return moMaximum; }
set
{
moMaximum = value;
Invalidate();
}
}
[EditorBrowsable(EditorBrowsableState.Always), Browsable(
true), DefaultValue(false), Category("Behavior"), Description("Value")]public int Value
{
get { return moValue; }
set
{
moValue = value;
int nTrackHeight = (this.Height - (UpArrowImage.Height + DownArrowImage.Height));
float fThumbHeight = ((float)LargeChange / (float)Maximum) * nTrackHeight;
int nThumbHeight = (int)fThumbHeight;
if (nThumbHeight > nTrackHeight)
{
nThumbHeight = nTrackHeight;
fThumbHeight = nTrackHeight;
}
if (nThumbHeight < 56)
{
nThumbHeight = 56;
fThumbHeight = 56;
}
//figure out value
int nPixelRange = nTrackHeight - nThumbHeight;
int nRealRange = (Maximum - Minimum) - LargeChange;
float fPerc = 0.0f;
if (nRealRange != 0)
{
fPerc = (float)moValue / (float)nRealRange;
}
float fTop = fPerc * nPixelRange;
moThumbTop = (int)fTop;
Invalidate();
}
}
[EditorBrowsable(EditorBrowsableState.Always), Browsable(
true), DefaultValue(false), Category("Skin"), Description("Channel Color")]public Color ChannelColor
{
get { return moChannelColor; }
set { moChannelColor = value; }
}
[EditorBrowsable(EditorBrowsableState.Always), Browsable(
true), DefaultValue(false), Category("Skin"), Description("Up Arrow Graphic")]public Image UpArrowImage
{
get { return moUpArrowImage; }
set { moUpArrowImage = value; }
}
[EditorBrowsable(EditorBrowsableState.Always), Browsable(
true), DefaultValue(false), Category("Skin"), Description("Up Arrow Graphic")]public Image DownArrowImage
{
get { return moDownArrowImage; }
set { moDownArrowImage = value; }
}
[EditorBrowsable(EditorBrowsableState.Always), Browsable(
true), DefaultValue(false), Category("Skin"), Description("Up Arrow Graphic")]public Image ThumbBottomImage
{
get { return moThumbBottomImage; }
set { moThumbBottomImage = value; }
}
[EditorBrowsable(EditorBrowsableState.Always), Browsable(
true), DefaultValue(false), Category("Skin"), Description("Up Arrow Graphic")]public Image ThumbMiddleImage
{
get { return moThumbMiddleImage; }
set { moThumbMiddleImage = value; }
}
protected override void OnPaint(PaintEventArgs e)
{
e.Graphics.InterpolationMode
= System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor;if (UpArrowImage != null)
{
e.Graphics.DrawImage(UpArrowImage, new Rectangle(new Point(0, 0), new Size(this.Width, UpArrowImage.Height)));
}
Brush oBrush
= new SolidBrush(moChannelColor);Brush oWhiteBrush = new SolidBrush(Color.FromArgb(255, 255, 255));
// 函数名: rectangle
//功 能: 画一个矩形
//用 法: void far rectangle(int left, int top, int right, int bottom);
//draw channel left and right border colors
e.Graphics.FillRectangle(oWhiteBrush, new Rectangle(0, UpArrowImage.Height, 1, (this.Height - DownArrowImage.Height)));
e.Graphics.FillRectangle(oWhiteBrush, new Rectangle(this.Width - 1, UpArrowImage.Height, 1, (this.Height - DownArrowImage.Height)));
//draw channel
//e.Graphics.FillRectangle(oBrush, new Rectangle(1, UpArrowImage.Height, this.Width-2, (this.Height-DownArrowImage.Height)));
e.Graphics.DrawImage(ThumbBottomImage, new Rectangle(0, UpArrowImage.Height, this.Width, (this.Height - DownArrowImage.Height)));
//draw thumb
int nTrackHeight = (this.Height - (UpArrowImage.Height + DownArrowImage.Height));
float fThumbHeight = ((float)LargeChange / (float)Maximum) * nTrackHeight;
int nThumbHeight = (int)fThumbHeight;
if (nThumbHeight > nTrackHeight)
{
nThumbHeight = nTrackHeight;
fThumbHeight = nTrackHeight;
}
//MessageBox.Show(nThumbHeight.ToString());
if (nThumbHeight < 56)
{
nThumbHeight = 56;
fThumbHeight = 56;
}
//Debug.WriteLine(nThumbHeight.ToString());
//float fSpanHeight = (fThumbHeight - (ThumbMiddleImage.Height + ThumbTopImage.Height + ThumbBottomImage.Height)) / 2.0f;
//int nSpanHeight = (int)fSpanHeight;
int nTop = moThumbTop;//0
nTop += UpArrowImage.Height;//9px
//draw top画上面的按钮
//e.Graphics.DrawImage(ThumbTopImage, new Rectangle(0, nTop, this.Width, ThumbTopImage.Height));
//nTop += ThumbTopImage.Height;//10px
//draw top span
//Rectangle rect = new Rectangle(1, nTop, this.Width - 2, nSpanHeight);
//e.Graphics.DrawImage(ThumbTopSpanImage, 1.0f,(float)nTop, (float)this.Width-2.0f, (float) fSpanHeight*2);
// nTop += nSpanHeight;//11px
//draw middle
e.Graphics.DrawImage(ThumbMiddleImage, new Rectangle(0, nTop, this.Width, ThumbMiddleImage.Height));
//nTop += ThumbMiddleImage.Height;
//draw top span
//rect = new Rectangle(1, nTop, this.Width - 2, nSpanHeight*2);
//e.Graphics.DrawImage(ThumbBottomSpanImage, rect);
//nTop += nSpanHeight;
//draw bottom
//e.Graphics.DrawImage(Thu