您的位置:首页 > 编程语言 > C#

C# WinForm控件美化扩展系列之TabControl控件(1)

2010-04-10 13:31 507 查看

C# WinForm控件美化扩展系列之TabControl控件(1)

2009-10-30 来自:CS 程序员之窗 字体大小:【

摘要:这篇文章我们将介绍TabControl控件的美化,因为它跟NumericUpDown控件一样,也包含一个UpDownButton按钮,这篇文章只介绍对TabControl的UpDownButton按钮的美化,接下来的文章将一步步的介绍对TabControl的完全美化。

前面的文章C# WinForm控件美化扩展系列之UpDown控件NumericUpDown中介绍了对NumericUpDown控件的美化,这篇文章我们将介绍TabControl控件的美化,因为它跟NumericUpDown控件一样,也包含一个UpDownButton按钮,这篇文章只介绍对TabControl的UpDownButton按钮的美化,接下来的文章将一步步的介绍对TabControl的完全美化。
当TabControl控件的TabPage页比较多的时候,TabPage页有些显示不完,它就会显示一个UpDownButton按钮,用来操作移动TabPage的显示。这个UpDownButton按钮不像NumericUpDown控件那样容易得到,需要通过API函数FindWindowEx来得到,通过FindWindowEx函数来查找UpDownButton按钮,需要知道它的类名,通过SPY++可以查询到,它的类名为“msctls_updown32”。看看查找UpDownButton按钮的代码:
private IntPtr FindUpDownButton()
{
return NativeMethods.FindWindowEx(
base.Handle,
IntPtr.Zero,
UpDownButtonClassName,
null);
}
得到了UpDownButton按钮,就可以用NumericUpDown一样的步骤方法对它进行美化了,不过要注意的是,当TabControl控件增加TabPage页或者TabControl控件调整大小的时候,需要查询是否需要显示UpDownButton按钮,否者就不能对它进行美化了,因为如果刚开始的时候控件不需要显示UpDownButton按钮的话,是查询不到它的,那样就没能对它的绘制消息进行截取。
跟以前一样,还是要实现一个UpDownButtonNativeWindow类,把UpDownButton的句柄分配给它,就可以通过它截取UpDownButton的消息了。在这个类里面,截取WM_PAINT消息,重绘UpDownButton控件。来看看UpDownButtonNativeWindow类的完整实现代码:
private class UpDownButtonNativeWindow : NativeWindow, IDisposable
{
private TabControlEx _owner;
private bool _bPainting;

public UpDownButtonNativeWindow(TabControlEx owner)
: base()
{
_owner = owner;
base.AssignHandle(owner.UpDownButtonHandle);
}

private bool LeftKeyPressed()
{
if (SystemInformation.MouseButtonsSwapped)
{
return (NativeMethods.GetKeyState(NativeMethods.VK_RBUTTON) < 0);
}
else
{
return (NativeMethods.GetKeyState(NativeMethods.VK_LBUTTON) < 0);
}
}

private void DrawUpDownButton()
{
bool mouseOver = false;
bool mousePress = LeftKeyPressed();
bool mouseInUpButton = false;

NativeMethods.RECT rect = new NativeMethods.RECT();

NativeMethods.GetClientRect(base.Handle, ref rect);

Rectangle clipRect = Rectangle.FromLTRB(
rect.Top, rect.Left, rect.Right, rect.Bottom);

Point cursorPoint = new Point();
NativeMethods.GetCursorPos(ref cursorPoint);
NativeMethods.GetWindowRect(base.Handle, ref rect);

mouseOver = NativeMethods.PtInRect(ref rect, cursorPoint);

cursorPoint.X -= rect.Left;
cursorPoint.Y -= rect.Top;

mouseInUpButton = cursorPoint.X < clipRect.Width / 2;

using (Graphics g = Graphics.FromHwnd(base.Handle))
{
UpDownButtonPaintEventArgs e =
new UpDownButtonPaintEventArgs(
g,
clipRect,
mouseOver,
mousePress,
mouseInUpButton);
_owner.OnPaintUpDownButton(e);
}
}

protected override void WndProc(ref Message m)
{
switch (m.Msg)
{
case NativeMethods.WM_PAINT:
if (!_bPainting)
{
NativeMethods.PAINTSTRUCT ps =
new NativeMethods.PAINTSTRUCT();
_bPainting = true;
NativeMethods.BeginPaint(m.HWnd, ref ps);
DrawUpDownButton();
NativeMethods.EndPaint(m.HWnd, ref ps);
_bPainting = false;
m.Result = NativeMethods.TRUE;
}
else
{
base.WndProc(ref m);
}
break;
default:
base.WndProc(ref m);
break;
}
}

#region IDisposable 成员

public void Dispose()
{
_owner = null;
base.ReleaseHandle();
}

#endregion
}
根据前面的说明,需要在控件创建、增加TabPage页、调整大小的时候,对其进行消息截取,看看下面相应的几个方法:
protected override void OnHandleCreated(EventArgs e)
{
base.OnHandleCreated(e);
if (UpDownButtonHandle != IntPtr.Zero)
{
if (_upDownButtonNativeWindow == null)
{
_upDownButtonNativeWindow = new UpDownButtonNativeWindow(this);
}
}
}

protected override void OnCreateControl()
{
base.OnCreateControl();

if (UpDownButtonHandle != IntPtr.Zero)
{
if (_upDownButtonNativeWindow == null)
{
_upDownButtonNativeWindow = new UpDownButtonNativeWindow(this);
}
}
}

protected override void OnControlAdded(ControlEventArgs e)
{
base.OnControlAdded(e);

if (UpDownButtonHandle != IntPtr.Zero)
{
if (_upDownButtonNativeWindow == null)
{
_upDownButtonNativeWindow = new UpDownButtonNativeWindow(this);
}
}
}

protected override void OnSizeChanged(EventArgs e)
{
base.OnSizeChanged(e);
if (UpDownButtonHandle != IntPtr.Zero)
{
if (_upDownButtonNativeWindow == null)
{
_upDownButtonNativeWindow = new UpDownButtonNativeWindow(this);
}
}
}
当然,在控件销毁的时候,也需要清理UpDownButtonNativeWindow:
protected override void OnHandleDestroyed(EventArgs e)
{
base.OnHandleDestroyed(e);
if (_upDownButtonNativeWindow != null)
{
_upDownButtonNativeWindow.Dispose();
_upDownButtonNativeWindow = null;
}
}
这样,我们实现了对TabControl的UpDownButton按钮的美化,因为这个代码还没有完整的实现TabControl的美化,所以先不提供源码下载了,接下来的文章将实现对TabControl进一步的美化,到时候就可以把完整的代码提供下载了,希望大家继续关注。

声明:
本文版权归作者和CS 程序员之窗所有,欢迎转载,转载必须保留以下版权信息,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
作者:Starts_2000
出处:CS 程序员之窗 http://www.csharpwin.com
你可以免费使用或修改提供的源代码,但请保留源代码中的版权信息,详情请查看:
CS程序员之窗开源协议 http://www.csharpwin.com/csol.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: