對話框分為模態對話框和非模態對話框,創建模態對話框用DialogBox(),創建非模態對話框用CreateDialog(),一個對話框通常都應當有一個父窗口,對話框的定位以父窗口的坐標系統為基准,父窗口關閉對話框也隨即關閉。如果模態對話框沒有父窗口就不再具有模態對話框的特性(用戶必須處理完模態對話框的要求之後才能繼續在主窗口的操作)。例如使用MessageBox(NULL,"Message","Error",MB_OK)彈出一個警告對話框阻止用戶的進一步操作,但是第一個參數指定其父窗口為NULL,該信息框將不再具有預料的功能,在該對話框顯示時,用戶仍然能夠在程序的主窗口中進行操作。
一、 模態對話框和非模態對話框
1、 調用模態對話框
調用DialogBox()或者DialogBoxIndirect(),模態對話框顯示後,其父窗口接到一個WM_CANCELMODE消息,要求其釋放對鼠標的捕獲,供對話框使用。對話框有自己的消息隊列,當該消息隊列空閒時,其父窗口將接收到WM_ENTRYIDLE消息,可以在這個消息的處理函數中進行後台操作。在處理的過程中應不斷調用PeekMessage()監視對話框的消息隊列,一旦發現消息立刻將控制權轉移給對話框。
2、 調用非模態對話框
調用CreateDialog()或者CreateDialogIndirect(),參數和DialogBox()的參數完全相同,不過非模態對話框不會自動顯示,因此要再調用一下ShowWindow()函數,或者在資源編輯器中編輯對話框時指定對話框的Style為Visible。例如:
ShowWindow(CreateDialog(hInst,(LPCSTR)IDD_DIALOG,hwnd,(DLGPROC)DlgProc),TRUE);
二、 對話框模板
對話框模板用來描述一個對話框的外觀和其包含的控件,一個對話框可以一個可執行程序中的對話框資源,也可以使用一個內存模板。
1、 使用內存模板建立對話框
內存對話框模板由兩部分組成,第一部為一個DLGTEMPLATE(或DLGTEMPLATEEX)結構,描述對話框的整體結構,第二部分為若干個DLGITEMTEMPLATE(或DLGITEMTEMPLATEEX)結構,描述對話框內部的控件,模板建立後調用CreateDialogIndirect()或DialogBoxIndirect()函數建立對話框
2、 DLGTEMPLATE結構
typedef struct {
DWord style;
DWord dwExtendedStyle;
Word cdit;
short x;
short y;
short cx;
short cy;
} DLGTEMPLATE, *LPDLGTEMPLATE;
三、 DLGITEMTEMPLATE結構
typedef struct {
DWord style;
DWord dwExtendedStyle;
short x;
short y;
short cx;
short cy;
Word id; // on Windows 95/98, this is a byte.
} DLGITEMTEMPLATE, *PDLGITEMTEMPLATE;
四、 Modeless對話框
1、 調用非模態對話框
if(!IsWindow(hwndDlg))
{
hwndDlg=CreateDialog(hInst,(LPCSTR)IDD_DLG,hWnd,(DLGPROC)DlgProc);
ShowWindow(hwndDlg,SW_SHOW);
}
IsWindow()函數判斷hwndDlg是否已經指向一個窗口,如果返回TRUE,表示對話框已經顯示,不需要再調用對話框,如果返回FALSE,調用CreateDialog()顯示對話框。要注意一點,hwndDlg必須聲明為全局變量,而不是對話框函數的私有變量,否則每次對話框函數被調用都將重新初始化該變量IsWindow(hwndDlg)總方會FALSE,上面的判斷語句就形同虛設了。同時應在調用EndDialog()前設hwndDlg=NULL,否則對話框關閉後IsWindow(hwndDlg)總返回TRUE,再也打不開了。
2、 處理非模態對話框消息
對於非模態對話框,對話框接收的消息有可能被傳遞給父窗口,因此在父窗口的消息處理中派遣消息之前要區分來自窗口的和來自對話框的消息:
if(!IsDialogMessage(&msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}