第九章 對話方塊
模態對話方塊
對話方塊有兩類,一中是【模態】一中是【非模態】,模態對話方塊是指當我們結束這個對話方塊時,才能對同一個程式中的另一個對話方塊進行互動,不過這時我們可以切換到其他程式。而非模態對話方塊則不具有這種性質。
當我們建立一個對話方塊後,會產生一個建立的模板,比如:
ABOUTBOX DIALOG DISCARDABLE 32, 32, 180, 100
STYLE DS_MODALFRAME | WS_POPUP
FONT 8, "MS Sans Serif"
BEGIN
DEFPUSHBUTTON "OK",IDOK,66,80,50,14
ICON "ABOUT1",IDC_STATIC,7,7,21,20
CTEXT "About1",IDC_STATIC,40,12,100,8
CTEXT "About Box Demo Program",IDC_STATIC,7,40,166,8
CTEXT "(c) Charles Petzold, 1998",IDC_STATIC,7,52,166,8
END
·其中DIALOG DISCARDABLE 是關鍵字,後四個數字是對話方塊的位置和大小,位置是相對於父視窗顯示的。
·然後是STYLE
·FONT 字型
當然這些東西我們也可以在對話方塊屬性裡面調整。
如果我們想在對話方塊中用我們自訂的控制項,比如一個橢圓形的OK按鈕,我們可以使用一個子視窗來實現:
·先在main函數裡註冊一個類,”ok_button”
·然後我們就可以在上述的模板中,添加一個控制項:”ok_button”,可以寫成如下形式:
CONTROL "OK",IDOK,"ok_button",WS_GROUP | WS_TABSTOP,73,79,32,14
·這樣,我們就可以在dialog中建立一個自訂的按鈕了
對話方塊的處理常式
BOOL CALLBACK DialogProc(HWND , UINT , WPARAM , LPARAM );
對話方塊的處理常式和視窗訊息處理常式的區別:
·視窗訊息處理常式WndProc返回LRESULT,而DialogProc返回BOOL
·如過WndProc不處理這個訊息,那麼將會呼叫DefWindowProc,而DialogProc如果不處理傳回FALSE
·對話方塊程式不需要處理WM_PAINT 或 WM_DESTROY訊息,對話方塊程式不接受WM_REATE訊息,而是哎WM_INITDIALOG訊息處理期間對對話方塊進行初始化工作。
啟用對話方塊
如果我們顯示叫一個定義好的對話方塊,我們可以這樣做:
DialogBox(hInstance,MAKEINTRESOURCE(IDD_DIALOG),hwnd,DialogProc);
即使程式在顯示對話方塊時,WndProc也可以接收訊息。我們可以從對話方塊程式內部給WndProc發送訊息:
SendMessage(GetParent(hDlg), …);
當我們需要控制對話方塊的控制項時,我們可以使用函數來通過對話方塊控制代碼和控制項ID來獲得控制項的控制代碼:
GetDlgItem(hDlg,ID);
非模態對話方塊
非模態對話方塊可以讓我們在同一個程式中在不同的對話方塊中切換。模態對話方塊是用DialogBox來建立的,而非模態對話方塊則是用CreateDialog來建立的。
非模態對話方塊與模態對話方塊有幾點區別:
·非模態對話方塊通常包含一個標題列和系統功能表按鈕。
·非模態對話方塊訊息要通過程式式的訊息佇列,要將這些訊息傳送給對話方塊訊息視窗處理常式,則必須改變訊息佇列。
·非模態對話方塊使用DestroyWindow而不是EndDialog來結束非模態對話方塊。(如果使用了Close按鈕來結束對話方塊,我們必須處理WM_CLOSE訊息,windows內的對話方塊視窗訊息處理常式並不處理WM_CLOSE訊息。
while(GetMessage(&msg,NULL,0,0))
{
if(hDlgModeless == 0 || !IsDialogMessage(hDlgModeless,&msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg); }}
如果訊息是發給對話方塊的,那麼IsDialogMessage將它發送給對話方塊訊息處理常式,並傳回TRUE。只有hDlgMedeless為0或者訊息不是該對話方塊訊息時,才必須呼叫TranslateMessage函數。