共用方式為


關於屬性表

屬性表 是一個視窗,可讓用戶檢視和編輯項目的屬性。 例如,試算表應用程式可以使用屬性表來讓使用者能夠設定儲存格的字型和框線屬性,或檢視和設定裝置的屬性,例如磁碟驅動器、印表機或滑鼠。

本節討論下列主題。

屬性表單基本概念

若要在應用程式中實作屬性表,請在專案中加入Prsht.h頭檔。 Prsht.h 包含與屬性表搭配使用的所有標識碼。

屬性表包含一或多個稱為頁面的重迭子視窗,每個視窗都包含用於設定相關屬性群組的控制視窗。 例如,頁面可以包含控件來設定專案的字型屬性,包括類型樣式、點大小、色彩等等。 每個頁面都有一個頁籤,用戶可以選取它,將頁面顯示在屬性頁的最前面。 例如,Date-Time 控制面板應用程式會顯示下列屬性表。

屬性表的螢幕快照有兩個分頁標籤,其中一個顯示時鐘和月曆控制項

具有多個索引標籤頁面的標準屬性表可讓使用者隨機存取所有屬性。 如果更適合依序設定屬性,您可以使用 精靈

屬性表對話框

屬性表及其包含的頁面實際上是對話框。 屬性表是系統定義的對話框,可管理頁面並提供它們的通用容器。 屬性頁面對話框可以是模態或非模態。 它包含框架、標題列和四個按鈕:OK取消套用和 [選擇性] 說明。 當使用者按鍵時,頁面的對話框程式會以 WM_NOTIFY 訊息的形式接收通知碼。

注意

本節中的所有資訊都不適用於精靈,其外觀和行為有些不同。 例如,精靈有一組不同的按鈕,而且沒有索引標籤。 如需詳細資訊,請參閱 建立精靈

屬性表中的每個頁面都是應用程式定義的無模式對話框,可管理用來檢視和編輯專案屬性的控件視窗。 您提供用來建立每個頁面的對話框範本,以及管理控件及設定對應專案屬性的對話框程式。

屬性表會在頁面取得或失去啟用時,以及當使用者按一下 [確定]、[取消]、[套用] 或 [說明] 按鈕時,將通知碼傳送至頁面的對話框程式。 通知會以 WM_NOTIFY 訊息的形式傳送。 lParam 參數是包含屬性表對話框視窗句柄的 NMHDR 結構位址。

某些通知碼需要頁面傳回 TRUEFALSE,以回應 WM_NOTIFY 訊息。 若要這樣做,頁面必須使用 SetWindowLong 函式,將頁面對話框的 [DWL_MSGRESULT] 值設定 為 [TRUE] 或 [FALSE]。

頁面

屬性表必須至少包含一個頁面,但不能包含超過 Windows 標頭檔中所定義的 MAXPROPPAGES 的值。 每個頁面都有以零起始的索引,屬性表會根據頁面加入至屬性表的順序來指派。 索引會用於您傳送至屬性表的訊息中。

屬性頁可以包含巢狀對話框。 當條件成立時,您必須為頂層對話框包含 WS_EX_CONTROLPARENT 樣式,並以父對話框的句柄呼叫 IsDialogMessage 函式。 這可確保使用者可以使用助記鍵和對話框導覽鍵,將焦點移至巢狀對話框中的控件。

每個頁面都有對應的圖示和標籤。 屬性表會為每個頁面建立索引標籤,並在索引標籤中顯示圖示和標籤。所有屬性表頁面都預期會使用非Bold 字型。 若要確保字型不是粗體,請在對話框範本中指定 DS_3DLOOK 樣式。

頁面對話框的程式不得呼叫 EndDialog 函式。 這麼做將會破壞整個屬性表,而不僅僅是頁面。

屬性表頁面的大小下限是水準 212 個對話框單位,垂直 114 個對話框單位。 如果頁面對話框小於這個,頁面將會放大,直到符合最小大小為止。 Prsht.h 頭檔包含三組屬性表頁面的建議大小,如下表所示。

大小 描述
PROP_SM_CXDLG 小屬性表頁面的對話框單位寬度。
PROP_SM_CYDLG 小屬性表頁面的對話框單位的高度。
PROP_MED_CXDLG 中型屬性表頁面的寬度,以對話單位計。
PROP_MED_CYDLG [高度],以對話框單位表示的中型屬性表頁面。
PROP_LG_CXDLG 大型屬性表頁面的對話框單位寬度。
PROP_LG_CYDLG 大型屬性表頁面的對話框單位的高度。

使用這些建議的大小有助於確保應用程式與其他Microsoft Windows 應用程式之間的視覺一致性。

在 Microsoft Visual Studio 資源編輯器中,您可以在 [新增資源] 對話方塊中建立適當大小的頁面。 展開 [對話框] 節點,然後選取 IDD_PROPPAGE_LARGEIDD_PROPPAGE_MEDIUMIDD_PROPPAGE_SMALL

屬性表會自動調整大小以容納最大的頁面。

屬性表的建立

建立屬性表之前,您必須定義一或多個頁面。 這牽涉到填入 PROPSHEETPAGE 結構,其中包含頁面的相關信息,也就是其圖示、卷標、對話框範本、對話框程式等等,然後在呼叫 createPropertySheetPage 函式時指定結構的位址。 函式會返回 HPROPSHEETPAGE 類型的句柄,該句柄可唯一識別頁面。

若要建立屬性表,您可以在呼叫 PropertySheet 函式時,指定 PROPSHEETHEADER 結構的位址。 結構會定義屬性表的圖示和標題,也包含您使用 createPropertySheetPage 取得之 HPROPSHEETPAGE 句柄陣列的位址。 PropertySheet 建立屬性頁面時,它會包含在陣列中識別的頁面。 頁面會以陣列中的順序出現在屬性表中。

將頁面指派給屬性表的另一種方式是指定 PROPSHEETPAGE 結構的陣列,而不是 HPROPSHEETPAGE 句柄的陣列。 在此情況下,PropertySheet 先為頁面建立句柄,再將它們新增至屬性表。

建立頁面時,其對話框程式會收到 WM_INITDIALOG 訊息。 訊息的 lParam 參數是建立頁面時所定義之 PROPSHEETPAGE 結構複本的指標。 特別是建立頁面時,結構的 lParam 成員可用來將應用程式定義的資訊傳遞至對話框程式。 除了 lParam 成員之外,此結構必須視為唯讀。 對除 lParam 外的任何內容進行修改,將會產生無法預測的結果。

當系統後續將頁面的 PROPSHEETPAGE 複本 結構傳遞給您的應用程式時,它會使用相同的指標。 結構的任何變更都會一併傳遞。 因為系統會忽略 lParam 成員,所以可以修改它以將資訊傳送至應用程式的其他部分。 例如,您可以使用 lParam,將資訊傳遞至頁面的 PropSheetPageProc 回呼函式。

PropertySheet 會自動設定屬性表的大小和初始位置。 此位置是以擁有者視窗的位置為基礎,而大小是以建立屬性表時頁面陣列中指定的最大頁面為基礎。 如果您希望頁面符合屬性表底部四個按鈕的寬度,請將最寬頁面的寬度設定為190個對話框單位。

屬性表的大小是從資源檔中對話框範本的 寬度高度 計算。 如需詳細資訊,請參閱 DIALOG ResourceDIALOGEX 資源。 不過請注意,基於相容性考慮,維度會相對於 MS Shell Dlg 字型計算,而不是頁面所使用的字型。 如果您設計使用另一個字型的頁面,可以使用下列其中一個建議。

  • 調整對話框範本的維度,以補償 MS Shell Dlg 字型與頁面實際使用的字型之間的大小差異。 例如,如果您選擇寬度為 MS Shell Dlg 兩倍的字型,請將對話框範本的 width 屬性設定為一般用法的兩倍。
  • 使用 DIALOGEX 範本,並設定 DS_SHELLFONT 對話框樣式。 在此情況下,屬性表管理員會解釋對話框範本的尺寸,相對於對話框範本所使用的字體。

新增和移除頁面

建立屬性表之後,應用程式可以藉由傳送 PSM_ADDPAGE 訊息,將頁面新增至現有頁面集的結尾。 若要在現有頁面之間插入頁面,請傳送 PropSheet_InsertPage 訊息。 請注意,屬性表的大小無法在建立之後變更。 任何新增或插入的頁面都必須不大於屬性表中目前最大的頁面。 若要移除頁面,請傳送 PSM_REMOVEPAGE 訊息。

當您定義頁面時,您可以指定屬性表在建立或移除頁面時所呼叫 PropSheetPageProc 回呼函式的位址。 使用 PropSheetPageProc 可讓您執行個別頁面的初始化和清除作業。

注意

當屬性表正在操作頁面列表時,會發生許多訊息和一個函數調用。 執行此動作時,嘗試修改頁面清單將會產生無法預期的結果。 請勿在實作 PropSheetPageProc或 處理下列通知和 Windows 訊息時新增、插入或移除頁面。

如果您在處理其中一則訊息時或 PropSheetPageProc 運作時,需要修改屬性表頁面,請張貼私人 Windows 訊息。 在屬性表管理員完成其工作之後,您的應用程式才會收到該訊息,此時可以安全地修改頁面清單。

當屬性表被銷毀時,它會自動銷毀已新增至它的所有頁面。 頁面會依用來建立頁面的陣列中指定的反向順序終結。 若要終結 CreatePropertySheetPage 函式所建立但未新增至屬性表的頁面,請使用 DestroyPropertySheetPage 函式。

屬性表標題和頁面標籤

您可以在用來建立屬性表的 PROPSHEETHEADER結構中指定屬性表的標題。 如果 dwFlags 成員包含 PSH_PROPTITLE 值,則屬性表會根據版本新增後綴 “Properties” 或前置詞 “Properties for”。 您可以使用 PSM_SETTITLE 訊息,在建立屬性表之後變更標題。 在 Aero Wizard 中,此訊息可用來動態變更內部頁面的標題。

根據預設,屬性表會使用對話框範本中指定的名稱字串做為頁面的標籤。 您可以在定義頁面的 PROPSHEETPAGE 結構中的 dwFlags 成員中包含 PSP_USETITLE 值,以覆寫名稱字串。 指定 PSP_USETITLE 時,pszTitle 成員必須包含頁面標籤字串的位址。

頁面啟用

屬性表一次只能有一個啟用的頁面。 在進行啟用的頁面位於重疊頁面堆疊的最上層。 用戶選取其索引標籤來啟動頁面;應用程式會使用 PSM_SETCURSEL 訊息來啟動頁面。

屬性表會將 PSN_KILLACTIVE 通知碼傳送至即將失去啟用狀態的頁面。 回應中,頁面必須驗證使用者對頁面所做的任何變更。 如果頁面在失去啟用之前需要額外的使用者輸入,請使用 SetWindowLong 函式,將頁面的 DWL_MSGRESULT 值設定為 TRUE。 此外,頁面必須顯示描述問題的消息框,並提供建議的動作。 當允許失去啟動時,將 DWL_MSGRESULT 設定為 FALSE

在看到取得啟用的頁面之前,屬性表會將 PSN_SETACTIVE 通知碼傳送至頁面。 頁面必須藉由初始化其控件視窗來回應。

幫助按鈕

屬性表可以顯示兩個 [說明] 按鈕:顯示在框架底部的屬性表 [說明] 按鈕、[確定] 旁的 [確定]/[取消]/[套用] 按鈕,以及提供內容相關說明的標準標題欄按鈕。

屬性表 [說明] 按鈕是選擇性的,可以逐頁啟用。 若要顯示一或多個頁面的屬性表中的 [說明] 按鈕:

  • 在屬性表的 PROPSHEETHEADER 結構中,於 dwFlags 成員設定 PSH_HASHELP 旗標。
  • 針對將顯示 [說明] 按鈕的每個頁面,在頁面 PROPSHEETPAGE 結構 dwFlags 中設定 PSP_HASHELP 旗標 成員。

當使用者按兩下 [說明] 按鈕時,使用中頁面會收到 PSN_HELP 通知碼。 頁面必須藉由顯示說明資訊來回應,通常是呼叫 WinHelp 函式。

移除標題欄說明按鈕

標題列上的 [說明] 按鈕預設會顯示,以便提供與內容相關的說明給 [確定/取消/套用] 按鈕。 不過,如有必要,可以移除此按鈕。 若要移除屬性表的標題列 [說明] 按鈕:

  • 對於 5.80 版之前的通用控件版本,您必須實作 屬性表回呼函式
  • 對於 5.80 版 及後續版本的通用控制項,您只需在屬性表的 PROPSHEETHEADER 結構中的 dwFlags 成員中設定 PSH_NOCONTEXTHELP 旗標。 不過,如果您需要與舊版通用控件版本的回溯相容性,則必須實作回呼函式。

若要實作一個屬性頁面回呼函數以移除標題列上的說明按鈕:

  • 請在屬性表的 PROPSHEETHEADER 結構中的 dwFlags 成員上設定 PSH_USECALLBACK 旗標。
  • PROPSHEETHEADER 結構的 pfnCallBack 成員設定為指向回呼函式。
  • 實作回調函式。 當此函式收到 PSCB_PRECREATE 訊息時,它也會收到屬性表對話框範本的指標。 從此範本中移除 DS_CONTEXTHELP 樣式。

下列範例說明如何實作這類回呼函式:

int CALLBACK RemoveContextHelpProc(HWND hwnd, UINT message, LPARAM lParam)
{
    switch (message) 
    {
    case PSCB_PRECREATE:
        // Remove the DS_CONTEXTHELP style from the
        // dialog box template
        if (((LPDLGTEMPLATEEX)lParam)->signature ==    
           0xFFFF)
           {
            ((LPDLGTEMPLATEEX)lParam)->style 
            &= ~DS_CONTEXTHELP;
        }
        else {
            ((LPDLGTEMPLATE)lParam)->style 
            &= ~DS_CONTEXTHELP;
        }
        return TRUE;
    }
    return TRUE;
}

如果未定義 DLGTEMPLATEEX 結構,請包含下列宣告:

#include <pshpack1.h>

typedef struct DLGTEMPLATEEX
{
    WORD dlgVer;
    WORD signature;
    DWORD helpID;
    DWORD exStyle;
    DWORD style;
    WORD cDlgItems;
    short x;
    short y;
    short cx;
    short cy;
} DLGTEMPLATEEX, *LPDLGTEMPLATEEX;

#include <poppack.h>

確定、取消和套用按鈕

確定套用 按鈕會指示屬性表的頁面去驗證並套用使用者所做的屬性變更,兩者功能類似。 唯一的差別在於按一下 [確定] 按鈕,這會在套用變更後銷毀屬性頁面。

當使用者按兩下 [確定] [確定][套用] 按鈕時,屬性表會將 PSN_KILLACTIVE 通知傳送至使用中頁面,讓您有機會驗證使用者的變更。 如果變更有效,頁面必須呼叫 SetWindowLong 函式,並將 DWL_MSGRESULT 值設定為 FALSE。 如果使用者的變更無效,頁面必須將 DWL_MSGRESULT 設定為 TRUE,並顯示對話方塊,告知用戶問題。 頁面會保持使用中狀態,直到將 DWL_MSGRESULT 設定為 FALSE,以回應 PSN_KILLACTIVE 訊息。

在某個頁面通過將 DWL_MSGRESULT 設為 FALSE來回應 PSN_KILLACTIVE 通知後,屬性表會將 PSN_APPLY 通知傳送給每個頁面。 當頁面收到此通知時,它必須將新的屬性套用至對應的專案。 若要向屬性表指出變更對頁面有效,請呼叫 SetWindowLong,並將 DWL_MSGRESULT 設定為 PSNRET_NOERROR。 如果頁面的變更無效,請返回錯誤。 這樣做可防止屬性表被銷毀,並將焦點返回到收到 PSN_APPLY 通知的頁面,或是在按下 [套用] 按鈕時擁有焦點的頁面。 若要傳回錯誤,並指出哪個頁面會收到焦點,請將 DWL_MSGRESULT 設定為下列其中一個值。

  • PSNRET_INVALID。 屬性表將不會被銷毀,焦點將返回至此頁面。
  • PSNRET_INVALID_NOCHANGEPAGE。 屬性表將不會被銷毀,焦點將會返回至按下按鈕之前具有焦點的頁面。

應用程式可以使用 PSM_APPLY 訊息來模擬選擇 [套用] 按鈕。

當頁面活躍時,[套用] 按鈕最初會被停用,表示尚未有任何屬性變更可供套用。 當頁面透過其中一個控件接收輸入,指出使用者已編輯屬性時,頁面必須將 PSM_CHANGED 訊息傳送至屬性表。 訊息會使屬性表啟用 套用按鈕。 如果使用者隨後按一下 [套用 ] 或 [取消 ] 按鈕,頁面必須重新初始化其控件,然後傳送 PSM_UNCHANGED 訊息來停用 [套用 ] 按鈕。

有時候 [套用] 按鈕會導致頁面對屬性表進行變更,而且無法復原變更。 發生這種情況時,頁面必須將 PSM_CANCELTOCLOSE 訊息傳送至屬性表。 訊息會使屬性表將 [確定] 按鈕的文字變更為 [關閉],表示無法取消套用的變更。

有時候頁面會變更需要重新啟動 Windows 的系統設定,或在變更生效之前重新啟動系統。 進行這類變更之後,頁面必須將 PSM_RESTARTWINDOWSPSM_REBOOTSYSTEM 訊息傳送至屬性表。 這些訊息會導致屬性表被銷毀後,PropertySheet 函式傳回 ID_PSRESTARTWINDOWSID_PSREBOOTSYSTEM 值。

當使用者點擊 [取消] 按鈕時,屬性清單會將 PSN_RESET 通知碼傳送至所有頁面,指出屬性清單即將被銷毀。 頁面必須使用通知來執行清除作業。

巫師

精靈是屬性表的特殊類型。 精靈的設計目的是以應用程式所控制的順序一次呈現一個頁面。 使用者不必按下索引標籤來從頁面群組中選取,而是透過按下按鈕,一次巡覽一個頁面。 例如,下列螢幕快照顯示 [新增硬體精靈] 中的歡迎頁面:

精靈歡迎頁面的 螢幕快照

下列螢幕快照顯示「航空精靈」的第一頁,這是 Windows Vista 中引進的新樣式。

航空精靈第一頁的螢幕快照

如需精靈的完整討論,請參閱 建立精靈