简介
这篇文章是关于发现在Windows Vista中使用新的Windows Vista用户界面的控件。包含在项目中的一些组件(Commandlinks的ImageButton,SplitButton),就像Windows Vista的主题控制工作。
这篇文章的目的是实现大多数的界面效果(如fade-in/out)整个Windows Vista中看到的效果。背景
大多数的Windows Vista的用户可能会发现新的用户界面。每个控制是一步一个更好的Windows XP相比,它来完成的,与可爱的小褪色效果。然而,微软Visual Studio默认情况下不支持完整的Vista主题。虽然Visual Studio 2005中试图解决这一问题的视觉样式,它仍然不会允许控制,以实现整个Windows Vista的所有可见的视觉效果。
本文包括:获取对一些常用控件(按钮,复选框,单选按钮,文本框,组合框)的淡入淡出效果淡出效果,获得的图像按钮上,和保存获取工具栏上的淡出效果获取MainMenus和ContextMenus Windows Vista的主题化获得CommandLinks和SplitButtons获得不同颜色的Progressbars获得类似资源管理器的接口列表框和的TreeView
它利用USER32.DLL SendMessage函数()函数,以及uxtheme.dll setwindowtheme()一定的控制功能,为了呈现一些控制到预期的水平。先决条件
您将需要以下的东西来完成本教程:Windows Vista中NET框架2.0(已预装在Windows Vista)
其他一些(可选)有用的东西:{A}通用控件
{S0}
大多数控件都已经准备好为Windows Vista的主题化。我敢肯定,你有听说过EnableVisualStyles()的权利? EnableVisualStyles()通常被称为主题意识的控制,以获得用户界面主题。虽然Visual Studio 2005已经有了这个做的,Visual Studio 2003中并没有在默认情况下。如果你想使共同控制的主题,你可以查看希思管家} {A3的文章。
EnableVisualStyles()影响以下控制:文本框RichTextBox中HScrollBar垂直滚动条ProgressBar的TabControl的(部分)MainMenu的的ContextMenu组合框DataGrid中ListBox中ListView中TreeView的的DateTimePickerMonthCalendar分离器的TrackBarStatusBar的工具栏TreeView的ListView中按钮分组框中(部分)
虽然Visual Studio 2005支持其中包括控制视觉主题化,这些控件不具有"全"为主题,其中包括淡入淡出效果。通过设置的FlatStyle系统,可以解决这个问题。但是,这样做,图像不会显示等控制手段。在下一节中,这个问题可以很容易地解决。获取图像按钮和其他控件工作
通过设置按钮的FlatStyle系统,使得按钮和其他一些图像无法显示这些按钮。但是,本节旨在解决这个问题,通过使用尽可能少的代码。
如何来完成这件事?好了,我们需要发挥在user32.dll中发现的SendMessage()的功能。
首先,我们将需要申报的功能(但首先,你将需要进口System.Runtime.InteropServices)://Imports the user32.dll
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern IntPtr SendMessage
(IntPtr hWnd, int msg, int wParam, int lParam);
要设置一个控制的形象,我们将需要使用的BM_SETIMAGE [0x00F7]消息。现在,我们将使用一个图标(在System.Drawing声明)作为一个图像,因为它很容易得到的图标的句柄。{C}
这段代码的功能是检索您要显示的图标按钮(名为"button1的")的处理,并发送一条消息到Windows设置要使用的按钮图标。
你可以设置你想要什么样的图标设置"buttonicon"。您可以通过使用下面的代码:buttonicon = new Icon(SystemIcons.Exclamation, 40, 40);
SetImage();
使用该系统的惊叹号图标。什么,你会得到:
如果你想使用位图/图像,而不是一个图标,你可以使用GetHIcon()从位图的方法来检索位图的处理和使用手柄设置按钮的形象。IntPtr iconhandle = IntPtr.Zero;
Bitmap image = new Bitmap("C:\images\an_image.png");
iconhandle = image_.GetHicon();
SendMessage(this.Handle, VistaConstants.BM_SETIMAGE, 1, (int)iconhandle);
此按钮仍然支持其他正常的按钮有淡入淡出效果。
然而,有一个小问题,使用此方法。如果这个按钮的文本设置为"",无图像显示。这个问题是可以解决的CreateParams()函数的使用和分配BS_ICON主题按钮。//CreateParams property
protected override CreateParams CreateParams
{
get
{
CreateParams cParams = base.CreateParams;
if (this.ShowIconOnly == true)
{
//Render button without text
cParams.Style |= 0x00000040; // BS_ICON value
}
return cParams;
}
}
这种方法是最好的做法从从按钮继承的类。CommandLinks
CommandLinks真的只是按钮,分配不同的主题。他们的主题和他们的价值观(从CommCtrl.h在Windows Vista SDK)如下:BS_COMMANDLINK [0x0000000E]
第一步是创建按钮继承一个类。然后,我们可以覆盖的CreateParams()功能,使按钮使用各自的主题。为主题的生效,您需要对系统设置按钮的FlatStyle。下面是将commandLink类:using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices
public class CommandLink : Button
{
const int BS_COMMANDLINK = 0x0000000E;
//Set button's flatstyle to system
public CommandLink()
{
this.FlatStyle = FlatStyle.System;
}
protected override CreateParams CreateParams
{
get
{
CreateParams cParams = base.CreateParams;
//Set the button to use Commandlink styles
cParams.Style |= BS_COMMANDLINK;
return cParams;
}
}
}
然后你可以建立项目,就像一个正常的按钮使用在Windows窗体组件(因为它是从一个正常的按钮继承)。将commandLink的样子:
{S2}
*鼠标是通过将commandLink,但PRINTSCREEN不会捕获鼠标。
按钮,支持淡入淡出效果,就像实际控制。
但是等待?将commandLink的"注意事项"在哪里?那么,我们就可以实现该功能BCM_SETNOTE [0x00001609]消息发送到Windows。我们可以纳入一个属性设置轻松将commandLink的说明。const uint BCM_SETNOTE = 0x00001609;
//Imports the user32.dll
[DllImport("user32.dll", CharSet = CharSet.Unicode)]
static extern IntPtr SendMessage
(HandleRef hWnd, UInt32 Msg, IntPtr wParam, string lParam);
//Note property
private string note_ = "";
public string Note
{
get
{
return this.note_;
}
set
{
this.note_ = value;
this.SetNote(this.note_);
}
}
//Sets the button's note
void SetNote(string NoteText)
{
//Sets the note
SendMessage(new HandleRef(this, this.Handle),
BCM_SETNOTE, IntPtr.Zero, NoteText);
}
你会得到:
你也可以使用CommandLinks按钮图标/图像显示同样的方法:
{S4}的SplitButtons
{五}
就像CommandLinks,SplitButtons只是简单的按钮。您可以设置其样式SplitButton的使用的CreateParams方法:BS_SPLITBUTTON [0x0000000C]
然而,即使在设置样式,如何你会联想到一个菜单(ContextMenu中)按钮?为此,我们可以首先将发射每当splitbutton"下拉菜单"上的人点击的事件关联。首先,我们会听取重写的WndProc()方法发送到按钮的所有邮件。碰巧BCN_SETDROPDOWNSTATE [0x1606]消息将发送时,被点击下拉。此消息引发了数次,但只有一个消息发生是独一无二的,"1"的价值WPARAMS。最好的做法是在另一个类的消息进行过滤。此示例代码将火推下拉时是一个自定义事件(DropDown_Clicked)。protected override void WndProc(ref Message m)
{
// Listen for operating system messages;
// Filter out a lot of messages here
//The dropdown glyph changes:
//Mousedown (at dropdown area) => Dropdown Event fired
// => Glyph changes => MouseUp => Glyph Changes
switch (m.Msg)
{
case (VistaControls.VistaConstants.BCM_SETDROPDOWNSTATE):
//PROBLEM: other buttons also have would encounter this message
if (m.HWnd == this.Handle)
{
////This message seems to occur when the drop down is clicked;
////Occurs several times, but one of them have the value of 1
////in WParams
if (m.WParam.ToString() == "1")
{
DropDown_Clicked();
}
}
break;
}
base.WndProc(ref m);
}
使用这个自定义事件,我们可以显示出,只要按下按钮的下拉部分(完整的代码演示)的ContextMenu。这还不是全部尽管。我们只分配一个推下拉时,会被解雇的事件。我们需要在合适的时间下拉字形变化。有一些消息,我们可以用它来实现字形的正确画。他们的WM_PAINT消息[0x0F的],WM_LBUTTONDOWN [0x201],WM_MOUSELEAVE 0x2A3,WM_LBUTTONUP [0x202]和WM_KILLFOCUS [0x08的]消息。我们可以运行代码时,这些消息是通过重写的WndProc()消息发送。 (代码放在这里太乱了,但完整的代码可以通过Windows Vista控制演示。)
{中六}
此控件还支持淡入淡出效果。提示文本框
在Windows Vista中的一些文本框提示用户他们应该是什么类型(例如:在搜索框中)。它通常会出现一些灰色文字的文本框上,当用户试图键入到TextBox的东西就会消失。此功能为"提示旗帜"知道。在TextBox使用EM_SETCUEBANNER [0x1501]消息,您可以启用此功能。SendMessage(textbox1.Handle, 0x1500 + 1, IntPtr.Zero,
"Please type in something.");
{七}Mainmenus和Contextmenus
默认MainMenus(或MainMenuStrip)和ContextMenus(或的ContextMenuStrip)在Visual Studio 2005不完全支持Windows Vista的主题:
如果你想获得你的主菜单和上下文菜单Windows Vista主题,您将需要使用的Visual Studio 2003版本,或在Visual Studio 2005的向后兼容的版本(称为"主菜单"和"的ContextMenu") 。
您可以指定ContextMenus使用它的ContextMenu属性(可能在VB.NET隐藏在Visual Studio 2005)的控制。工具栏
虽然在Visual Studio 2005的默认工具栏做了Windows Vista的外观(如果Rendermode设置为系统),它并不拥有这一切。大多数Windows Vista上的工具栏有淡入淡出的效果。为了得到它,你将需要使用Visual Studio 2003版本或在Visual Studio 2005(及以上)的向后兼容的版本,并设置它的外形扁平,以获得褪色的效果。
,您可以使用工具栏上的按钮图像列表以及。工具栏的正确使用Visual Studio 2003中的ImageList,呼叫applications.DoEvents()函数后application.EnableVisualStyles()函数(唐Kackman )。Progressbars
在Windows Vista中,progressbars在不同的口味,最常见的是绿色的进度。不过,也有红色和黄色版本以及(有一个蓝色的版本,被称为米,但就是无法访问)。进度条的颜色似乎对应到具体的进度状态。您可以设置这些国家使用PBM_SETSTATE [0x40F]消息。国PBST_NORMAL [0x0001],PBST_ERROR [地图0x0002]和PBST_PAUSE [0x0003]。SendMessage(progressbar1.Handle, 0x400 + 16, 0x0001, 0); //Normal; Green
SendMessage(progressbar1.Handle, 0x400 + 16, 0x0002, 0); //Error; Red
SendMessage(progressbar1.Handle, 0x400 + 16, 0x0003, 0); //Pause; Yellow
的TreeView和ListViews
默认情况下的TreeView和ListViews不具备资源管理器相同的外观:
然而,位的代码,你可以使它看起来像这样:
您将需要使用UxTheme.dll文件中发现的SetWindowTheme()函数。您可以通过使用下面的代码://Imports the UXTheme DLL
[DllImport("uxtheme", CharSet = CharSet.Unicode)]
public extern static Int32 SetWindowTheme
(IntPtr hWnd, String textSubAppName, String textSubIdList);
然后,你可以设置相应的控制使用的样式使用下面的代码:SetWindowTheme(listView1.Handle, "explorer", null);
"ListView1的"是你的ListView。你可以做的TreeView这一点。
但是,还有更多。在Windows资源管理器中,这些ListViews以及半透明的选择。您可以通过调用LVS_EX_DOUBLEBUFFER [0x00010000]扩展样式。
的TreeView在Windows资源管理器中也有淡入淡出的效果。这样就可以实现通过TVS_EX_FADEINOUTEXPANDOS [0x0040]扩展样式。SendMessage(treeview1.Handle, 0x1100 + 44, 0x0040, 0x0040);
的TreeView也有"自动滚动"功能。您可以启用通过TVS_EX_AUTOHSCROLL [0x0020]扩展样式。
兴趣点SendMessage(treeview1.Handle, 0x1100 + 44, 0x0020, 0x0020);
可能有几个消息或功能,可用于修改主题,可能无法在有限的文件在Windows Vista中发现的控制。当然,这是一种不寻常的,我们必须使用旧版本的控制(如MainMenu和ContextMenu),以实现新的Windows Vista的图形用户界面的全部潜力。
值得注意的事情
我没有在Visual Studio 2003测试上面的代码,我也没有运行Windows XP上的应用程序(我没有做它向后兼容",但")。
自定义控件演示一些旧的Windows版本,可能无法正常工作的CommandLinks,SplitButtons和ProgressBars。
这是在Visual Studio 2005和Windows Vista的测试。参考文献(浏览使用左侧的导航窗格)历史版本1.10:2007年06月17日日 - 几个控件添加/修改版本1.00:2007年5月20日日 - 初始