您的位置:首页 > 其它

How to CreateWizard翻译

2014-04-17 13:50 169 查看
How to Create Wizards
         综述:

                   Wizard是PropertySheet类型的一种,它提供一种简单而有效的路引导用户处理整个操作过程。Wizard是一种简化用户体验的方法。Wizard允许你将复杂的操作简化为简单的几步,例如配置应用程序。在Wizard中的每一步,你都可以设置需要的操作。

                   Wizard实际上是一种PropertySheet。PropertySheet本质上是一个Page的容器,这些Page都是一个对话框。然而正规的PropertySheet允许用户在任意时间访问任意的Page。Wizard在序列中显示页面。作为Tab的替代,Wizard使用Backward和Forward来实现导航。

                  有两种Wizard风格:旧版的Wizard97风格和Aero风格(只在Vista后续中有)。第三种风格,仅仅是使用PSH_WIZARD或PSH_WIZARD_LITE标志,这个标志将显示一个没有标题和水印的一个简单的PropertySheet。水印就是出现在某些页面左边的位图。

                   以上讨论都是基于控件版本5.8或者更高的版本。

一、Instructions

         实现一个Wizard就和实现一个正规的PropertySheet一样。在绝大部分基础层面上,实现一个Wizard就是设置PROPSHEETHEADER的一个或多个下列的标志:

        

Flag

Style

PSH_WIZARD

一个简单的Wizard,没有标题和位图。

PSH_WIZARD_LITE

与PSH_WIZARD相似,只是在外观上有微小的差别。例如the divider above the buttons is set to the full width of the window.

PSH_WIZARD97

Wizard97样式的Wizard,有可选的header、header位图和水印。

PSH_WIZARD | PSH_AEROWIZARD

An Aero Wizard. Aero Wizards do not use watermarks or header bitmaps. They require the single-threaded apartment (STA) model.

一个AeroWizard,AeroWizard不使用水印或者header位图,它要求单线程模式。

         实现一个Wizard的基本过程:

1.      为每一个Page创建一个对话框模板。

2.      为每一个Page定义PROPSHEETPAGE结构,这个结构定义Page并包含指向对话框模板、位图和其他资源的指针。

3.      将上一步定义的PROPSHEETPAGE传递给CreatePropertySheetPage()函数来创建Page的HPROPSHEETPAGE句柄。

4.      为Wizard定义一个PROPSHEETHEADER结构。

5.      将PROPSHEETHEADER结构传递给PropertySheet()函数来显示Wizard。

6.      每个Page实现一个对话框处理函数,来处理来自内部Control和Wizard Buttonn的消息,同时处理Windows消息。

二、Createthe Dialog Box Templates

                   有两种WizardPage:内部Page和外部Page。外部Page是欢迎页和结束页,其他的都是内部Page。

(1)      外部页模板

欢迎页和结束页的基本布局是一致的。下图就显示了Wizard97的介绍页。

 

            对于Wizard97的外部页来说,对话框模板是317x193的对话框单元。 这个外部页占据了整个Wizard,处理底下的Back、Next和Cancel按钮。模板左边是为水印位图保留的,不能放置任何控件。这个水印位图由PROPSHEETHEADER结构指定并且自动被添加到页中,所以当你设计外部页的时候,要为这个水印位图保留空间。(怎么保留空间没说)

            当你创建水印位图的时候,你必须考虑到对话框的大小可能变化。例如,用户选择了大号的系统字体,同样语言的不同也会导致不同的字体度量。当页变大时,为水印保留的区域也随之变大。但是你却不能改变水印图也不能拉伸位图以适应保留区域。作为替代,位图将保留原大小,位于保留区域的左上角。没有被水印位图覆盖的保留区域,将会被水印位图左上角像素来填充。

如果你需要不同的水印位图来适应字体尺寸,那么有两种方案可供选择:

A. 在创建Wizard之前,获取字体尺寸,然后选择合适大小的位图。

B. 创建Wizard的时候不指定位图,Wizard97会将该区域留空,然后选择合适大小的位图来作为保留区域的水印。

                   在页的右边,你可以像普通的对话框一样来摆放自己的控件。页右边的背景色是由系统决定的,你无法控制。一般来说右边都是放置两个静态控件。上面的控件是标题,拥有大而醒目的字体(对于Wizard97是12
点的Verdana字体)。另外一个是用来显示解释性信息的,使用标准的对话框字体。

              欢迎页与结束页的区别就是,欢迎页Back按钮不可用,结束页Next按钮编程Finish按钮。

              注意:在Aero Wizard中,Back按钮被替换为一个箭头按钮。

              你可以通过PSM_SETFINISHTEXT消息来设置Finish按钮。默认情况下,Finish按钮不包含键盘加速功能。如果想要这个功能,那么使用PSM_SETFINISHTEXT发送带有&标记的文字。例如,&Finish表示定义F为该按钮的加速键。

(2)      内部页模板

                   内部页与外部页有少许的不同,下图显示了一个Wizard97的内部页的例子,它带有一个占位符位图:

                  

                   顶部区域是由PropertySheet进行处理的。所以它没有被包含在页的对话框模板中。顶部区域的内容在页的PROPSHEETPAGE和Wizard的PROPSHEETHEADER中指定。因为内部页需要匹配顶部区域和底部的按钮区域,所以Wizard97的对话框模板为317x143对话框单元。这要比外部页的模板要小。

                   下图显示了AeroWizard根据同一模板显示的效果:

                  

三、Define the Wizard Pages

         在你创建完对话框模板并关联诸如位图和字符串等资源后,你就可以创建PropertySheet Page了。这个过程与标准的PropertySheet的创建过程很相似。首先,填充PROPSHEETPAGE结构的相应的成员(有一些成员在Wizard中指定。)然后,调用CreatePropertySheetPage()函数创建HPROPSHEETPAGE句柄。

         下列Wizard相关的标志可以再PROPSHEETPAGE中的dwFlags设置。

Flag

Description

PSP_HIDEHEADER

在Wizard97样式中,用来设置外部页,这个页的头部不会被显示,水印将会显示。

PSP_USEHEADERTITLE

在Wizard97中,这个标志用在内部页,用来讲一个标题放在头部区域。或者在AeroWizard中的客户区域顶部。

PSP_USEHEADERSUBTITLE

在Winzard97中,这个标志用在内部页,用来将子标题放在头部区域。

         如果设置了PSP_USEHEADERTITLE或者PSP_USEHEADERSUBTITLE标志,就可以使用pszHeaderTitle和pszHeaderSubtitle成员分别设置标题和子标题。当你为PROPSHEETPAGE和PROPSHEETHEADER结构设置文本字符串的时候,你既可以使用字符串指针,也可以使用MAKEINTRESOURCE宏来从字符串资源中设置该值。字符串资源是从wizard的PROPSHEETHEADER结构中的hInstance成员指定的模块中加载的。

         当你调用CreatePropertySheetPage()函数创建一个Page的时候,将结果保存在HPROPSHEETPAGE句柄数组之中。这个数组在创建PropertySheet的时候会被用到。一个Page所在数组的下标决定了该Page的默认显示顺序。当你创建一个Page的HPROPSHEETPAGE句柄后,你可以重用该PROPSHEETPAGE结构来创建下一个页面,当然了根据需要分配给该结构新的值。

         另外一种方法是每个Page使用独立的PROPSHEETPAGE结构,并且创建该结构的数组。当创建PropertSheet的时候,该结构可以用来替代HPROPSHEETPAGE数组。使用PROPSHEETPAGE结构就不用CreatePropertySheetPage()函数了,但是将消耗更多的内存。否则这两种方法也就没有什么不同了。

         后面这个例子是通过设置PROPSHEETPAGE的值来定义一个内部的Wizard97的Page。在这个例子中,Page的标题、子标题和对话框模板都被定义在了资源文件中。随后将调用CreateProperttySheetPage来P创建Page的HPROPSHEETPAGE句柄。因为这个Page是第二个页面,所以设置数组中的下标为1。

 

四、Custom Page Data

         当你创建Page的时候,你可以使用PROPSHEETPAGE结构中的lParam来设置自定义的数据。最典型的用法就是分配一个指向自定义结构的指针。

         当Page第一次被选中时,该页的对话框处理函数接收到WM_INITDIALOG消息。该消息中的lParam的值是一个指向该Page的PROPSHEETPAGE结构的指针(也就是刚才说的用来传递自定义数据的指针)。你可以通过SetWindowLongPtr()函数并使用GWL_USERDATA作为参数索引,来保存该数据以便在随后的消息中使用。多个页面有相同的数据(PROPSHeETPAGE)并且任何一个页面改变该数据将影响其他页面的。

 

五、Define the Wizard Property Sheet

         正如正常的PropertySheet一样,你通过填充PROPSHEETHEADER结构来定义WizardPropertySheet。这个结构可以定义组成Wizard的页面和页面默认的显示顺序。然后你可以调用PropertySheet()函数启动该Wizard。

         在Wizard97中,PROPSHEETHEADER结构的pszCaption会被忽略。而Wizard会显示当前页面在该页的对话框模板中指定的Caption(标题)。如果对话框模板省略了该标题,那么前一个页面的标题将被显示。因此,为了在所有页面都显示同一个标题,那么最好在欢迎页面(也就是第一页面)的对话框模板中设置标题信息。

         在AeroWizard样式中,对话框标题从pszCation中取得。

         如果你创建了HPROPSHEETPAGE数组,那么设置PRPSHEETHEADER的phppage成员。如果你创建了PROPSHEETPAGE数组,那么设置PROPSHEETHEADER中的ppsp成员,并且设置PROPSHEETHEADER的dwFlags包含PSH_PROPSHEETPAGE标志。

         以下代码定义了psh变量为PROPSHEETHEADER结构,并且调用PropertySheet()函数启动了该Wizard。Wizard97样式的Wizard同时具有水印和头部图像,并且都被指定在了资源文件中。ahpsp数组包含所有HPROPSHEETPAGE句柄。

 

六、The Dialog Box Procedure

         每一个Wizar的Page都需要一个对话框处理函数来处理Windows消息,尤其要处理来自自身控件和Wizard的通知消息。有三个消息是是素有Wizard都要处理的,即WM_INITDIALOG、WM_DESTROY和WM_NOTIFY。

         WM_NOTIFY消息是在Page被显示之前接收和wizard上的任何安按钮被按下时接收到的。该消息的lParam是一个指向NMHDR结构的指针,通知ID就在该结构的code成员中。其中四个通知代码是大部分wizard需要处理的。

        

Code

Description

PSN_SETACTIVE

在Page被显示之前收到

PSN_WIZBACK

当Back按钮被按下时收到。

PSN_WIZNEXT

当next按钮被按下时收到。

PSN_WIZFINISH

当Finish按钮被按下时收到

 

 

七、Handle WM_INITDIALOG and WM_DESTROY

         当一个Page第一次被显示时,它的对话框处理函数将收到WM_INITDIALOG消息。收到这个消息可以让对话框完成初始化,如存储自定义数据或者设置字体。

         当pPropertySheet销毁时,页面将收到WM_DESTROY消息。虽然Wizard是自动被系统销毁,但是处理该消息允许你做一些清理操作。

 

八、Handle PSN_SETACTIVE

         当一个Page准备显示时,PSN_SETACTIVE消息将发出。一个Page第一次被显示时,PSN_SETACTIVE跟随WM_INITDIALOG消息一起发送。如果一个页面随后再次被访问,那么它将只收到PSN_SETACTIVE通知。这个通知消息通常被用来初始化页面的数据和允许特定的按钮。

         默认情况下,Wizard显示Back、Next和Cancel按钮并且按钮都是可用状态。如果想禁止一个按钮或者用Finish替换Next,那么必须发送PSM_SETWIZBUTTONS消息。当这个消息发出后,这个按钮的状态将被保存,直到它被另外一个PSM_SETWIZBUTTONS消息更改,即使心得页面被选中。典型的,所有PSN_SETACTIVE消息的处理者发送这个消息允许指定按钮的状态,从而保证页面都有正确的按钮状态。

         你可以使用这个消息在任何事件改变按钮的状态。作为一个例子,如果你想让Next按钮被初始化为不可用。直到用户填写了所有必要的信息,那么你可以使用这个消息在用户填写完成后发送,来允许进入下一个页面。

         下面的代码片段使用了PropSheet_SetWizButtons宏,在内部页面显示前允许Back和Next按钮。

 

九、Handle PSN_WIZNEXT, PSNWIZBACK, and PSN_WIZFINISH

         当Next或者Back按钮被单击时,你将收到PSN_WIZNEXT或者PSN_WIZBACK通知代码。默认情况下,Wizard自动进入后一个或者前一个页面。处理该消息的原因就是,防止切换页面,或者改变默认的页面切换顺序。

         为了避免切换页面,处理按钮的通知消息,调用SetWindowLong()函数将DWL_MSGRESULT的值设置为-1。并且返回TRUE值。

         为了改变标准的页面顺序,到达指定的页面。调用SetWindowLong函数,将DWL_MSGRESULT的值设置为某个页面的对话框资源的ID值,并且返回TRUE。

         当Finish或者Cancel按钮被按下,将收到PSN_WIZFINISH或者PSN_RESET通知。当两者之中被按下一个时,Wizard将自动被系统销毁。但是你可以处理该消息,如果你需要在系统销毁之前完成清理工作。为了能组织Wizard被销毁,当你收到PSN_WIZFINISH通知时,调用SetWindowLong函数并将DWL_MSGREESULT的值设置为TRUE,并且返回TRUE。

 

十、Backward Compatible Wizards

 

 

 

 

 

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: