作者:Kenny Kerr
翻譯:Dflying Chen
原文:http://weblogs.asp.net/kennykerr/archive/2006/07/12/Windows-Vista-for-Developers-_1320_-Part-1-_1320_-Aero-Wizards.aspx
請同時參考《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