引言
在本章節(jié)中我們來(lái)講解Windows/Win32編程中對(duì)話框的原理和對(duì)話框的創(chuàng)建,我們?cè)谇皫灼鹿?jié)中講解到了普通窗口中回調(diào)函數(shù)的處理,在普通窗口的窗口消息處理函數(shù)(回調(diào)函數(shù))中,系統(tǒng)會(huì)首先調(diào)用我們自己寫(xiě)的回調(diào)函數(shù),我們自己編寫(xiě)的回調(diào)函數(shù)沒(méi)有處理的消息,才會(huì)交給系統(tǒng)的缺省函數(shù)處理,但是對(duì)話框中消息處理機(jī)制不同,系統(tǒng)會(huì)首先調(diào)用系統(tǒng)中的回調(diào)函數(shù),在缺省函數(shù)中沒(méi)有處理的消息,才會(huì)尋找我們自己寫(xiě)的回調(diào)函數(shù)去處理。簡(jiǎn)單來(lái)說(shuō),在普通窗口中是我們自己寫(xiě)的回調(diào)函數(shù)調(diào)用系統(tǒng)缺省回調(diào)函數(shù),而在對(duì)話框中,是系統(tǒng)的缺省函數(shù)調(diào)用我們字節(jié)寫(xiě)的回調(diào)函數(shù)。
我們來(lái)編寫(xiě)一段偽代碼來(lái)幫助大家理解:
普通窗口:
WndProc(...){
... //我們自己寫(xiě)的回調(diào)函數(shù)過(guò)程
DefWinsowsProc(...); //之后調(diào)用系統(tǒng)缺省回調(diào)函數(shù)
}
而在對(duì)話框中,是系統(tǒng)的缺省函數(shù)調(diào)用我們寫(xiě)的回調(diào)函數(shù):
缺省函數(shù)( ... ){
... //系統(tǒng)寫(xiě)好的處理過(guò)程
自定義回調(diào)函數(shù); //我們自己寫(xiě)的回調(diào)函數(shù)
}
一.對(duì)話框原理
1.對(duì)話框的分類(lèi)
- 模式對(duì)話框
當(dāng)對(duì)話框顯示時(shí),會(huì)禁止其他窗口和用戶進(jìn)行交互 - 無(wú)模式對(duì)話框/非模式對(duì)話框
當(dāng)窗口顯示后,其他窗口仍可以與用戶進(jìn)行交互
2.對(duì)話框的基本使用
- 1.對(duì)話框消息處理函數(shù)
我們?cè)谇懊娴恼鹿?jié)中講解過(guò)在系統(tǒng)內(nèi)核中,局部窗口類(lèi),全局窗口類(lèi),系統(tǒng)窗口類(lèi)的保存方式,這個(gè)對(duì)話框處理函數(shù),就是保存于系統(tǒng)窗口類(lèi),我們給出一張圖來(lái)幫助大家理解:
我們來(lái)看看對(duì)話框窗口處理函數(shù)的過(guò)程:
我們來(lái)通過(guò)一段偽代碼來(lái)講解:
缺省函數(shù)(。。。){
..... //系統(tǒng)定義好的處理過(guò)程
if(DigProc){
我們自己寫(xiě)的窗口消息處理函數(shù)。
return 。。。;
}
...... //后續(xù)的缺省消息處理過(guò)程
};
- 2.注冊(cè)窗口類(lèi)(程序員一般不適用)
- 3.創(chuàng)建對(duì)話框
- 4.對(duì)話框的關(guān)閉
2.自定義對(duì)話框窗口消息處理函數(shù)
既然我們可以自己定義回調(diào)函數(shù),那么我們來(lái)看看在對(duì)話框中我們到底該怎么編寫(xiě)回調(diào)函數(shù):
MSDN官方文檔解釋DigProc回調(diào)函數(shù)
- 應(yīng)用程序定義的回調(diào)函數(shù)與
CreateDialoc
函數(shù)和DialocBox
函數(shù)系列一起使用(我們后文會(huì)講到)。它處理發(fā)送到模式或無(wú)模式對(duì)話框的消息。DLGPROC類(lèi)型定義指向此回調(diào)函數(shù)的指針。- 語(yǔ)法:
INT_PTR DlgProc( HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam){...}
其中,hWnd指定對(duì)話框的句柄,uMsg是消息,wParam和lParam都是消息的附加信息。
一般情況下,如果此回調(diào)函數(shù)(我們自定義的回調(diào)函數(shù))處理了消息,則對(duì)話框過(guò)程應(yīng)返回TURE,如果未處理,則返回FALSE。如果對(duì)話框過(guò)程返回FALSE,對(duì)話管理器將執(zhí)行默認(rèn)對(duì)話操作以響應(yīng)消息。
二.模式對(duì)話框
- 1.創(chuàng)建對(duì)話框
通過(guò)DialogBox
函數(shù)來(lái)創(chuàng)建,我們來(lái)看看這個(gè)函數(shù):
MSDN官方文檔解釋DialogBox函數(shù)
- 函數(shù)功能:從對(duì)話框模板資源創(chuàng)建模式對(duì)話框
語(yǔ)法:
void DialogBox(
HINSTANCE hInstance, //包含對(duì)話框模板的模塊的句柄
LPCTSTR lpTemplate, //對(duì)話框模板
HWND hWndparent, //擁有對(duì)話框的窗口句柄
DIGPROC lpDialogFunc //指向?qū)υ捒蜻^(guò)程的指針
};
DialogBox函數(shù)是一個(gè)阻塞函數(shù),只有當(dāng)對(duì)話框關(guān)閉后,才會(huì)返回,執(zhí)行后續(xù)代碼
返回值通過(guò)EndDialog
函數(shù)設(shè)置
- 2.對(duì)話框的關(guān)閉
關(guān)閉模式對(duì)話框,使用
EndDialog
函數(shù),不能使用DwstroyWindow
函數(shù)(原因我們后文會(huì)講到)。
MSDN官方文檔解釋EndDialog函數(shù)
- 函數(shù)功能:銷(xiāo)毀模式對(duì)話框,導(dǎo)致系統(tǒng)結(jié)束對(duì)對(duì)話框的任何處理
- 語(yǔ)法:
BOOL EndDialog(
HWND hDlg, //要銷(xiāo)毀的對(duì)話框的句柄
INT_PTR nResult //要從創(chuàng)建對(duì)話框的函數(shù)返回到應(yīng)用程序的值
);
注意這里的nResult參數(shù),它是DialogBox函數(shù)退出時(shí)的返回值,我們前面講到DialogBox
是一個(gè)阻塞函數(shù),我們可以通過(guò)EndDialog函數(shù)來(lái)設(shè)置DialogBox函數(shù)返回的值,通過(guò)不同的返回值,我們可以做不同的事。
- 3.對(duì)話框消息
WM_INITDIALOG–對(duì)話框創(chuàng)建之后,在對(duì)話框顯示之前,通知對(duì)話框窗口處理函數(shù)的消息,我們可以在此消息中完成自己初始化相關(guān)的工作。
三.模式對(duì)話框創(chuàng)建過(guò)程實(shí)踐
我們來(lái)帶領(lǐng)大家一步一步創(chuàng)建模式對(duì)話框:
- 1.我們需要模式對(duì)話框,首先我們肯定需要一個(gè)菜單資源,我這里用的是之前文章內(nèi)容中的菜單資源,怎樣添加資源,如果大家不會(huì)的話可以到Windows編程資源,菜單資源,圖標(biāo)資源,光標(biāo)資源,上下文菜單,字符串資源,加速鍵資源
文章中學(xué)習(xí)。 - 2.創(chuàng)建了菜單資源后,我們還需要做出一個(gè)i對(duì)話框資源:
添加->資源->Dialog資源
這里我就使用程序初始化時(shí)的模式對(duì)話框了,至于模式對(duì)話框之后的創(chuàng)建按鈕,我們后續(xù)會(huì)講到 - 3.做好前兩步之后,我們來(lái)到普通窗口回調(diào)函數(shù)來(lái)處理消息,我們的需求是當(dāng)點(diǎn)擊菜單中的關(guān)于按鈕后,出現(xiàn)這個(gè)模式對(duì)話框
我們先來(lái)到普通窗口的回調(diào)函數(shù)來(lái)處理點(diǎn)擊幫助按鈕的消息:這里給出的是命令消息的全部處理,幫助按鈕的消息處理在第三個(gè)分支
case WM_COMMAND: {
switch(LOWORD(wParam)) {
case MY_OPEN: {
sprintf(output, "打開(kāi)按鈕被點(diǎn)擊,請(qǐng)到回調(diào)函數(shù)中做具體處理。\n");
WriteConsole(g_hOUTPUT, output, strlen(output), 0, 0);
break;
}
case MY_QUIT: {
sprintf(output, "退出按鈕被點(diǎn)擊,請(qǐng)到回調(diào)函數(shù)中做具體處理。\n");
WriteConsole(g_hOUTPUT, output, strlen(output), 0, 0);
break;
}
case IDM_ABOUT: {
sprintf(output, "幫助按鈕被點(diǎn)擊,請(qǐng)到回調(diào)函數(shù)中做具體處理。\n");
WriteConsole(g_hOUTPUT, output, strlen(output), 0, 0);
int nResult = DialogBox(hIns, (char*)IDD_ABOUTBOX, hwnd, DiaLogProc);
if (nResult == 100) {
MessageBox(hwnd, "Success", "Infor", MB_OK);
}
}
case MY_NEWFILE: {
sprintf(output, "打開(kāi)新文件按鈕被點(diǎn)擊,請(qǐng)到回調(diào)函數(shù)中做具體處理。\n");
WriteConsole(g_hOUTPUT, output, strlen(output), 0, 0);
break;
}
case MY_LASTTIMEFILE: {
sprintf(output, "上次打開(kāi)文件按鈕被點(diǎn)擊,請(qǐng)到回調(diào)函數(shù)中做具體處理。\n");
WriteConsole(g_hOUTPUT, output, strlen(output), 0, 0);
break;
}
}
break;
}
我們來(lái)看看處理效果:
我們?cè)诔绦蜻\(yùn)行起來(lái)之后,我們發(fā)現(xiàn)一個(gè)問(wèn)題:程序無(wú)法退出,這時(shí)候我們就需要來(lái)到模式對(duì)話框的回調(diào)函數(shù)來(lái)處理這個(gè)關(guān)閉模式對(duì)話框的消息了:
INT CALLBACK DiaLogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) {
switch (uMsg){
case WM_SYSCOMMAND:{
if (wParam = WM_CLOSE) {
EndDialog(hwndDlg, 100);
}
break;
}
}
return FALSE;
}
這時(shí)候我們發(fā)現(xiàn)就可以正常退出程序了。
四.無(wú)模式對(duì)話框
- 創(chuàng)建對(duì)話框:
HWND CreateDialog(
HINSTANCE hInstance, //包含對(duì)話框模板的模塊句柄
LPCTSTR lpTemplate, //對(duì)話框模板
HWND hWndParent, //擁有對(duì)話框的窗口句柄
DLGPROC lpDialogFunc //指向?qū)υ捒蜻^(guò)程的指針
);
MSDN官方文檔解釋CreateDialog函數(shù)
該函數(shù)為非阻塞函數(shù),創(chuàng)建成功后返回窗口句柄,需要使用ShowWindow函數(shù)來(lái)顯示對(duì)話框文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-438171.html
- 非模式對(duì)話框的關(guān)閉:
關(guān)閉非模式對(duì)話框,需要使用DestroyWindow
函數(shù)來(lái)銷(xiāo)毀窗口,不能使用EndDialog
函數(shù)來(lái)關(guān)閉對(duì)話框。
今天的分享就到這里,如果文章中有錯(cuò)誤之處,還請(qǐng)大家指出來(lái),我會(huì)非常虛心地學(xué)習(xí),希望我們共同進(jìn)步?。?!文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-438171.html
到了這里,關(guān)于【windows編程之對(duì)話框】對(duì)話框原理,對(duì)話框的創(chuàng)建的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!