MFC 對(duì)話框編程要點(diǎn)
(一)對(duì)話框基本要點(diǎn)和生命周期
MFC對(duì)話框支持WYSIWYG編程模式,即What you see is what you get.。其類型分為模式對(duì)話框和非模式對(duì)話框
對(duì)話框由一個(gè)rc資源文件描述外觀;與一個(gè)cpp類相連接(通過ID);對(duì)話框內(nèi)的控件使用基于ID的變量映射來通訊。
模式對(duì)話框對(duì)象被定義后,通過調(diào)用DoModal()函數(shù)來顯示對(duì)話框并進(jìn)行相關(guān)操作,此函數(shù)當(dāng)對(duì)話框被關(guān)閉時(shí)返回。其返回值標(biāo)明了對(duì)話框是點(diǎn)擊OK退出(1),還是被Cancel(2)。
非模式對(duì)話框需要與某個(gè)View相關(guān)聯(lián),以便對(duì)話框退出時(shí)發(fā)送消息給對(duì)應(yīng)的View進(jìn)行必要的處理。
在對(duì)話框顯示前,系統(tǒng)會(huì)調(diào)用OnInitDialog()函數(shù),在這個(gè)函數(shù)中你可以設(shè)置一些控件屬性,進(jìn)行一些初始化工作。比如,設(shè)置滾動(dòng)條的最大最小值,設(shè)置List列表的初始值等。其方法是將控件ID作為參數(shù),調(diào)用GetDlgItem函數(shù)獲得控件的對(duì)象的指針(指針類型是CWnd*)然后使用對(duì)象提供的函數(shù)進(jìn)行操作。
ID對(duì)于一個(gè)組件來說非常重要,通過向?qū)?,我們可以將一個(gè)變量和一個(gè)組件進(jìn)行關(guān)聯(lián)(映射)來實(shí)現(xiàn)數(shù)據(jù)交換,而這種綁定的關(guān)鍵就是將一個(gè)組件的ID與成員變量關(guān)聯(lián)。
(二)數(shù)據(jù)交換機(jī)制
UpdateData(BOOL b)函數(shù)可以進(jìn)行變量和組件內(nèi)容的交換,當(dāng)UpdateData函數(shù)的參數(shù)為TRUE時(shí),數(shù)據(jù)從對(duì)話框控件傳遞給數(shù)據(jù)成員;參數(shù)為FALSE時(shí),數(shù)據(jù)從數(shù)據(jù)成員傳遞至對(duì)話框成員。數(shù)據(jù)交換的實(shí)現(xiàn)是通過調(diào)用 CDialog::DoDataExchange函數(shù)。
當(dāng)我們想改變獲得到個(gè)別控件中的數(shù)據(jù)時(shí),可以使用GetDlgItem函數(shù)得到對(duì)應(yīng)控件的指針,對(duì)指針進(jìn)行操作。
(三)特殊的Radio Button
Radio Button控件是分組的,同一組的Radio Button只能有一個(gè)被選中。這個(gè)機(jī)制的實(shí)現(xiàn)依賴于TAB順序,在資源視圖下按Ctrl-D鍵將顯示對(duì)話框的TAB焦點(diǎn)順序。舉一個(gè)例子來說明:
Radio1,Radio2,Radio3是三個(gè)不同的RadioButton控件,其焦點(diǎn)順序?yàn)?,2,3。為了實(shí)現(xiàn)分組Radio1的Group屬性應(yīng)該為TRUE,其余兩個(gè)為FALSE。如果又有兩個(gè)Radio4,Radio5焦點(diǎn)順序?yàn)?,7。則Radio4的Group屬性應(yīng)為TRUE,Radio4,Radio5被分為一組。
需要注意的是,Radio以Group屬性來分組,為了結(jié)束前一個(gè)組,你應(yīng)該將焦點(diǎn)順序?yàn)?,8的控件的Group屬性設(shè)為TRUE,否則編譯器會(huì)產(chǎn)生一個(gè)警告。
(四)一些技巧
通過向?qū)?,我們可以將一個(gè)類成員變量和控件關(guān)聯(lián)以進(jìn)行數(shù)據(jù)交換,例如將一個(gè)CString類型的變量和Edit控件關(guān)聯(lián)。將一個(gè)int變量和一組Radio Button關(guān)聯(lián)。但是,人總有犯錯(cuò)的時(shí)候,當(dāng)我們修改或需要?jiǎng)h除這種關(guān)聯(lián)時(shí),麻煩就來了。
在我的使用過程中沒有發(fā)現(xiàn)VS2005提供了刪除“已被關(guān)聯(lián)的控件成員變量”的向?qū)В晕沂褂玫氖潜容^麻煩的手動(dòng)刪除。
1、 在對(duì)話框頭文件中刪除成員變量的定義
2、 在對(duì)話框cpp文件中刪除構(gòu)造函數(shù)初始化列表中的對(duì)應(yīng)變量的初始化
3、 在對(duì)話框cpp文件中刪除DoDataExchange函數(shù)中的對(duì)應(yīng)語句(根據(jù)變量名)
此時(shí),在class view中的向?qū)е?,已?jīng)可以重新設(shè)定控件所關(guān)聯(lián)的成員變量了。
登錄框的制作:
在顯示主窗口之前顯示一個(gè)模式對(duì)話框來提示用戶登錄是一個(gè)常用的功能。只需要在PreCreateWindow函數(shù)中加入顯示對(duì)話框的代碼就可以完成這個(gè)功能。
有些時(shí)候,我們可能需要從一個(gè)控件對(duì)象來得到它的ID。比如,你的對(duì)話框中有好幾個(gè)滾動(dòng)條,那么這些滾動(dòng)條的事件都在OnHScroll ,OnVScroll中被響應(yīng)。如何區(qū)分是哪個(gè)滾動(dòng)條就需要確定ID。
在這兩個(gè)函數(shù)的參數(shù)中有一個(gè)CScrollBar* pScrollBar指針,我們可以通過調(diào)用
pScrollBar->GetDlgCtrlID()來獲得ID,ID是一個(gè)整數(shù)。
在對(duì)話框編程中往往需要改變某個(gè)控件的文字,比如Edit控件和static text控件。此時(shí)使用SetDlgItemText(int nID, LPCTSTR lpzString)函數(shù)比較方便。