Windows Vista for Developers——第一部分:Aero向导
作者:Kenny Kerr
翻译:Dflying Chen
请同时参考《Windows Vista for Developers》系列。
Aero向导代表了由Windows 95系列操作系统最先引入的向导界面的最高发展水平。它给用户所常见的向导界面带来了一丝新意,能够更好地抓住用户的视线。在《Windows Vista for Developers》系列的第一部分中,我将演示如何用最少的代码将一个传统的向导更新为最新的Aero界面。
属性单(Property Sheets )
回忆一下,向导仅仅是一系列的由PROPSHEETHEADER 结构定义的属性单,并由PropertySheet 函数实现。ATL所提供的CPropertySheetImpl 类模板已经为我们生成了大部分使用PropertySheet 函数的代码。接下来就让我们从一个简单的属性单开始,然后将其“升级”为全新的Areo向导:
class SampleWizard :
public CPropertySheetImpl<SampleWizard>
{
public:
BEGIN_MSG_MAP(SampleWizard)
CHAIN_MSG_MAP(__super)
END_MSG_MAP()
SampleWizard() :
CPropertySheetImpl<SampleWizard>(IDS_TITLE)
{
VERIFY(AddPage(m_page));
}
private:
SamplePage m_page;
};
该SampleWizard 类继承于上面提到的CPropertySheetImpl 类模板,也就自动获取了基类提供的很多功能。message map简单地将消息传递给基类。构造函数调用了积累的构造函数,用来设置该向导的标题栏,并使用继承于CPropertySheetImpl的AddPage 方法添加了一个简单的页。SamplePage 类的定义如下:
class SamplePage :
public CPropertyPageImpl<SamplePage>
{
public:
BEGIN_MSG_MAP(SamplePage)
CHAIN_MSG_MAP(__super)
END_MSG_MAP()
enum { IDD = IDD_SAMPLE_PAGE };
};
SamplePage 类继承于CPropertyPageImpl 类模板,它提供了属性页所需要的大部分功能。SamplePage 的message map同样简单地将消息传递给基类。我们还需要为基类设置IDD (enum 类型的常量),以便其甄别将用于属性页的对话框资源。
这时,我们即可用下面的代码创建并显示出一个模态属性单了:
SampleWizard sampleWizard;
sampleWizard.DoModal();
第一行创建了一个SampleWizard 对象以及其多个基类的实例,其中之一就是生成调用PropertySheet 函数所必须的那个结构体。第二行SampleWizard 的DoModal 方法(继承于CPropertySheetImpl 类模板)负责调用PropertySheet 函数。结果就是我们看到了如下的一个简单的属性单:
经典向导(Classic Wizards )
若想将属性单变为经典样式的向导,你所需要做的只是在SampleWizard 构造函数中添加如下的语句:
m_psh.dwFlags |= PSH_WIZARD97;
上面这行代码将PSH_WIZARD97 标记(flag)与PROPSHEETHEADER 结构中现有的标记组合了起来。因为向导界面还包含有一个额外的标题区域,所以我们还需要修改SamplePage 类,添加一段标题文本:
class SamplePage :
public CPropertyPageImpl<SamplePage>
{
public:
BEGIN_MSG_MAP(SamplePage)
CHAIN_MSG_MAP(__super)
END_MSG_MAP()
enum { IDD = IDD_BLANK_PAGE };
SamplePage()
{
VERIFY(m_title.LoadString(IDS_PAGE_TITLE));
SetHeaderTitle(m_title);
}
private:
CString m_title;
};
SamplePage 构造函数使用继承于CPropertyPageImpl 的SetHeaderTitle 方法来设置标题区域。注意页的PROPSHEETPAGE 结构保留了该字符串的指针,所以该字符串的生存周期必须超过这个构造函数。
简单修改过后,结果却大不相同:
可以看到,前面出现在选项卡上的文字现在出现在了窗口标题栏中。
Aero向导(Aero Wizards )
现在只要将SampleWizard 构造函数中的PSH_WIZARD97 替换为PSH_AEROWIZARD ,即可看到全新的Aero向导界面:
可以看到,窗口的标题又回来了,而原本出现在属性单选项卡上的对话框说明文字却不见了踪影。
新的消息(New Messages )
Aero向导还提供了一些新的消息,用来让我们能够更好地控制向导中的控件。
PSM_SHOWWIZBUTTONS 消息用来显示或隐藏向导中的标准按钮。PropSheet_ShowWizButtons 宏可以帮你简单地发出这条消息。虽然使用起来并不是那么直观,但一旦掌握了也就不难了。PropSheet_ShowWizButtons 虽然是个宏,但我们可以将其想象为一个函数:
void PropSheet_ShowWizButtons(HWND handle,
DWORD buttons,
DWORD mask);
handle 参数用来甄别向导窗口的实例,buttons 参数用来指定将要显示哪些按钮,mask 参数则用来指定该宏将作用于哪些按钮上。若是某个按钮的标记同时出现在了buttons 和mask 参数中,那么将显示出该按钮。若某个按钮的标记只出现在了mask 参数中,那么该按钮将隐藏。我们可以使用如下的按钮标记:
- PSWIZB_BACK
- PSWIZB_NEXT
- PSWIZB_FINISH
- PSWIZB_CANCEL
例如,如下代码将显示出Next按钮,并隐藏Back按钮:
PropSheet_ShowWizButtons(handle,
PSWIZB_NEXT,
PSWIZB_BACK | PSWIZB_NEXT);
PSM_ENABLEWIZBUTTONS 消息用来启用或禁用某个标准按钮。PropSheet_EnableWizButtons 宏可以帮你简单地发出这条消息:
void PropSheet_EnableWizButtons(HWND handle,
DWORD buttons,
DWORD mask);
在区分按钮方面,这个宏的处理方法与PSM_SHOWWIZBUTTONS一样——buttons 参数用来指定将要启用/禁用哪些按钮,mask 参数则用来指定该宏将作用于哪些按钮上。例如,如下代码将启用Next按钮,并禁用Back按钮:
PropSheet_EnableWizButtons(handle,
PSWIZB_NEXT,
PSWIZB_BACK | PSWIZB_NEXT);
PSM_SETBUTTONTEXT消息用来修改Next、Finish和Cancel按钮上的文字。PropSheet_SetButtonText 宏可以帮你简单地发出这条消息:
void PropSheet_SetButtonText(HWND handle,
DWORD button,
PCWSTR text);
示例程序
为了让你更容易地体验到Aero向导所提供的各种增强功能,我创建了一个简单的向导界面,可以在这里下载:http://www.kennyandkarin.com/kenny/vista/aerowizardsample.zip