MFC教程對(duì)話框的編輯_第1頁
MFC教程對(duì)話框的編輯_第2頁
MFC教程對(duì)話框的編輯_第3頁
MFC教程對(duì)話框的編輯_第4頁
MFC教程對(duì)話框的編輯_第5頁
已閱讀5頁,還剩13頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

1、第五章對(duì)話框5.1 使用資源編輯器編輯對(duì)話框在Windows 開發(fā)中彈出對(duì)話框是一種常用的輸入/輸出手段,同時(shí)編輯好的對(duì)話框可以保存在資源文件中。Visual C+提供了對(duì)話框編輯工具,利用編輯工具可以方便的添加各種控件到對(duì)話框中,而且利用ClassWizard 可以方便的生成新的對(duì)話框類和映射消息。首先資源列表中按下右鍵,可以在彈出菜單中選擇“插入對(duì)話框”,如圖1。然后再打開該對(duì)話框進(jìn)行編輯,你會(huì)在屏幕上看到一個(gè)控件板,如圖2。你可以將所需要添加的控件拖到對(duì)話框上,或是先選中后再在對(duì)話框上用鼠標(biāo)畫出所占的區(qū)域。接下來我們?cè)趯?duì)話框上產(chǎn)生一個(gè)輸入框,和一個(gè)用于顯示圖標(biāo)的圖片框。之后我們使用鼠標(biāo)右

2、鍵單擊產(chǎn)生的控件并選擇其屬性,如圖3。我們可以在屬性對(duì)話框中編輯控件的屬性同時(shí)也需要指定控件ID,如圖4,如果在選擇對(duì)話框本身的屬性那么你可以選擇對(duì)話框的一些屬性,包括字體,外觀,是否有系統(tǒng)菜單等等。最后我們編輯圖片控件的屬性,如圖5,我們?cè)O(shè)置控件的屬性為顯示圖標(biāo)并指明一個(gè)圖標(biāo)ID。接下來我們添加一些其他的控件,最后的效果如圖6。按下CtrlT可以測試該對(duì)話框。此外在對(duì)話框中還有一個(gè)有用的特性,就是可以利用Tab 鍵讓輸入焦點(diǎn)在各個(gè)控件間移動(dòng),要達(dá)到這一點(diǎn)首先需要為控件設(shè)置在Tab 鍵按下時(shí)可以接受焦點(diǎn)移動(dòng)的屬性Tab Stop,如果某一個(gè)控件不打算利用這一特性,你需要清除這一屬性。然后從菜單

3、“Layout”選擇Tab Order來確定焦點(diǎn)移動(dòng)順序,如圖7。使用鼠標(biāo)依此點(diǎn)擊控件就可以重新規(guī)定焦點(diǎn)移動(dòng)次序。最后按下CtrlT進(jìn)行測試。最后我們需要為對(duì)話框產(chǎn)生新的類,ClassWizard 可以替我們完成大部分的工作,我們只需要填寫幾個(gè)參數(shù)就可以了。在編輯好的對(duì)話框上雙擊,然后系統(tǒng)回詢問是否添加新的對(duì)話框,選擇是并在接下來的對(duì)話框中輸入類名就可以了。ClassWizard 會(huì)為你產(chǎn)生所需要的頭文件和CPP 文件。然后在需要使用的地方包含相應(yīng)的頭文件,對(duì)于有模式對(duì)話框使用DoModal()產(chǎn)生,對(duì)于無模式對(duì)話框使用Create()產(chǎn)生。相關(guān)代碼如下;void CMy51_s1View:O

4、nCreateDlg()/產(chǎn)生無模式對(duì)話框CTestDlg *dlg=new CTestDlgdlg>Create(IDD_TEST_DLG)dlg>ShowWindow(SW_SHOW)void CMy51_s1View:OnDoModal()/產(chǎn)生有模式對(duì)話框CTestDlg dlgint iRet=dlg.DoModal()TRACE("dlg return %dn",iRet)下載例子。如果你在調(diào)試這個(gè)程序時(shí)你會(huì)發(fā)現(xiàn)程序在退出后會(huì)有內(nèi)存泄漏,這是因?yàn)槲覜]有釋放無模式對(duì)話框所使用的內(nèi)存,這一問題會(huì)在以后的章節(jié)5.3 創(chuàng)建無模式對(duì)話框中專門講述。關(guān)于在使用對(duì)

5、話框時(shí)Enter 鍵和Escape 鍵的處理:在使用對(duì)話框是你會(huì)發(fā)現(xiàn)當(dāng)你按下Enter鍵或Escape 鍵都會(huì)退出對(duì)話框,這是因?yàn)镋nter 鍵會(huì)引起CDialog:OnOK()的調(diào)用,而Escape鍵會(huì)引起CDialog:OnCancel()的調(diào)用。而這兩個(gè)調(diào)用都會(huì)引起對(duì)話框的退出。在MFC 中這兩個(gè)成員函數(shù)都是虛擬函數(shù),所以我們需要進(jìn)行重載,如果我們不希望退出對(duì)話框那么我們可以在函數(shù)中什么都不做,如果需要進(jìn)行檢查則可以添加檢查代碼,然后調(diào)用父類的OnOK()或OnCancel()。相關(guān)代碼如下;void CTestDlg:OnOK()AfxMessageBox(" 你選擇確定&q

6、uot;)CDialog:OnOK()void CTestDlg:OnCancel()AfxMessageBox(" 你選擇取消")CDialog:OnCancel()5.2 創(chuàng)建有模式對(duì)話框使用有模式對(duì)話框時(shí)在對(duì)話框彈出后調(diào)用函數(shù)不會(huì)立即返回,而是等到對(duì)話框銷毀后才會(huì)返回(請(qǐng)注意在對(duì)話框彈出后其他窗口的消息依然會(huì)被傳遞)。所以在使用對(duì)話框時(shí)其他窗口都不能接收用戶輸入。創(chuàng)建有模式對(duì)話框的方法是調(diào)用CDialog:DoModal()。下面的代碼演示了這種用法:CYourView:OnOpenDlg()CYourDlg dlgint iRet=dlg.DoModal()CDia

7、log:DoModal()的返回值為IDOK,IDCANCEL。表明操作者在對(duì)話框上選擇“確認(rèn)”或是“取消”。由于在對(duì)話框銷毀前DoModal 不會(huì)返回,所以可以使用局部變量來引用對(duì)象。在退出函數(shù)體后對(duì)象同時(shí)也會(huì)被銷毀。而對(duì)于無模式對(duì)話框則不能這樣使用,下節(jié)5.3 創(chuàng)建無模式對(duì)話框中會(huì)詳細(xì)講解。你需要根據(jù)DoModal()的返回值來決定你下一步的動(dòng)作,而得到返回值也是使用有模式對(duì)話框的一個(gè)很大原因。使用有模式對(duì)話框需要注意一些問題,比如說不要在一些反復(fù)出現(xiàn)的事件處理過程中生成有模式對(duì)話框,比如說在定時(shí)器中產(chǎn)生有模式對(duì)話框,因?yàn)樵谏弦粋€(gè)對(duì)話框還未退出時(shí),定時(shí)器消息又會(huì)引起下一個(gè)對(duì)話框的彈出。同樣

8、的在你的對(duì)話框類中為了向調(diào)用者返回不同的值可以調(diào)用CDialog:OnOK() 或是CDialog:OnCancel()以返回IDOK 或IDCANCEL,如果你希望返回其他的值,你需要調(diào)用CDialog:EndDialog( int nResult )其中nResult 會(huì)作為DoModal()調(diào)用的返回值。下面的代碼演示了如何使用自己的函數(shù)來退出對(duì)話框:下載例子void CMy52_s1View:OnLButtonDown(UINT nFlags, CPoint point)/創(chuàng)建對(duì)話框并得到返回值CView:OnLButtonDown(nFlags, point)CTestDlg dlg

9、int iRet=dlg.DoModal()CString szOutszOut.Format("return value %d",iRet)AfxMessageBox(szOut)/重載OnOK,OnCancelvoid CTestDlg:OnOK()/什么也不做void CTestDlg:OnCancel()/什么也不做/在對(duì)話框中對(duì)三個(gè)按鈕消息進(jìn)行映射void CTestDlg:OnExit1()CDialog:OnOK()void CTestDlg:OnExit2()CDialog:OnCancel()void CTestDlg:OnExit3()CDialog:E

10、ndDialog(0XFF)由于重載了OnOK 和OnCancel 所以在對(duì)話框中按下Enter 鍵或Escape 鍵時(shí)都不會(huì)退出,只有按下三個(gè)按鈕中的其中一個(gè)才會(huì)返回。此外在對(duì)話框被生成是會(huì)自動(dòng)調(diào)用BOOL CDialog:OnInitDialog(),你如果需要在對(duì)話框顯示前對(duì)其中的控件進(jìn)行初始化,你需要重載這個(gè)函數(shù),并在其中填入相關(guān)的初始化代碼。利用ClassWizard 可以方便的產(chǎn)生一些默認(rèn)代碼,首先打開ClassWizard,選擇相應(yīng)的對(duì)話框類,在右邊的消息列表中選擇WM_INITDIALOG 并雙擊,ClassWizard 會(huì)自動(dòng)產(chǎn)生相關(guān)代碼,代碼如下:BOOL CTestDlg

11、:OnInitDialog()/*先調(diào)用父類的同名函數(shù)*/CDialog:OnInitDialog()/*填寫你的初始化代碼*/return TRUE有關(guān)對(duì)對(duì)話框中控件進(jìn)行初始化會(huì)在5.4 在對(duì)話框中進(jìn)行消息映射中進(jìn)行更詳細(xì)的講解5.3 創(chuàng)建無模式對(duì)話框無模式對(duì)話框與有模式對(duì)話框不同的是在創(chuàng)建后其他窗口都可以繼續(xù)接收用戶輸入,因此無模式對(duì)話框有些類似一個(gè)彈出窗口。創(chuàng)建無模式對(duì)話框需要調(diào)用BOOL CDialog:Create( UINT nIDTemplate, CWnd* pParentWnd = NULL )之后還需要調(diào)用BOOL CDialog:ShowWindow( SW_SHOW)進(jìn)

12、行顯示,否則無模式對(duì)話框?qū)⑹遣豢梢姷?。相關(guān)代碼如下:void CYourView:OnOpenDlg(void)/*假設(shè)IDD_TEST_DLG 為已經(jīng)定義的對(duì)話框資源的ID 號(hào)*/CTestDlg *dlg=new CTestDlgdlg>Create(IDD_TEST_DLG,NULL)dlg>ShowWindows(SW_SHOW)/*不要調(diào)用delete dlg*/在上面的代碼中我們新生成了一個(gè)對(duì)話框?qū)ο?,而且在退出函?shù)時(shí)并沒有銷毀該對(duì)象。因?yàn)槿绻藭r(shí)銷毀該對(duì)象(對(duì)象被銷毀時(shí)窗口同時(shí)被銷毀),而此時(shí)對(duì)話框還在顯示就會(huì)出現(xiàn)錯(cuò)誤。那么這就提出了一個(gè)問題:什么時(shí)候銷毀該對(duì)象。我時(shí)

13、常使用的方法有兩個(gè):在對(duì)話框退出時(shí)銷毀自己:在對(duì)話框中重載OnOK 與OnCancel 在函數(shù)中調(diào)用父類的同名函數(shù),然后調(diào)用DestroyWindow()強(qiáng)制銷毀窗口,在對(duì)話框中映射WM_DESTROY 消息,在消息處理函數(shù)中調(diào)用delete this強(qiáng)行刪除自身對(duì)象。相關(guān)代碼如下:void CTestDlg1:OnOK()CDialog:OnOK()DestroyWindow()void CTestDlg1:OnCancel()CDialog:OnCancel()DestroyWindow()void CTestDlg1:OnDestroy()CDialog:OnDestroy()AfxMe

14、ssageBox("call delete this")delete this這種方法的要點(diǎn)是在窗口被銷毀的時(shí)候,刪除自身對(duì)象。所以你可以在任何時(shí)候調(diào)用DestroyWindow() 以達(dá)到徹底銷毀自身對(duì)象的作用。(DestroyWindow() 的調(diào)用會(huì)引起OnDestroy()的調(diào)用)通過向父親窗口發(fā)送消息,要求其他窗口對(duì)其進(jìn)行銷毀:首先需要定義一個(gè)消息用于進(jìn)行通知,然后在對(duì)話框中映射WM_DESTROY 消息,在消息處理函數(shù)中調(diào)用消息發(fā)送函數(shù)通知其他窗口。在接收消息的窗口中利用ON_MESSAGE 映射處理消息的函數(shù),并在消息處理函數(shù)中刪除對(duì)話框?qū)ο?。相關(guān)代碼如下:/

15、*更改對(duì)話框的有關(guān)文件*/CTestDlg2:CTestDlg2(CWnd* pParent /*=NULL*/): CDialog(CTestDlg2:IDD, pParent)/*m_pParent 為一成員變量,用于保存通知窗口的指針,所以該指針不能是一個(gè)臨時(shí)指針*/ASSERT(pParent)m_pParent=pParent/AFX_DATA_INIT(CTestDlg2)/ NOTE: the ClassWizard will add member initialization here/AFX_DATA_INITvoid CTestDlg2:OnOK()CDialog:OnOK

16、()DestroyWindow()void CTestDlg2:OnCancel()CDialog:OnCancel()DestroyWindow()void CTestDlg2:OnDestroy()CDialog:OnDestroy()/*向其他窗口發(fā)送消息,將自身指針作為一個(gè)參數(shù)發(fā)送*/m_pParent>PostMessage(WM_DELETE_DLG,(WPARAM)this)/*在消息接收窗口中添加消息映射*/*在頭文件中添加函數(shù)定義*/afx_msg LONG OnDelDlgMsg(WPARAM wP,LPARAM lP)/*添加消息映射代碼*/ON_MESSAGE(W

17、M_DELETE_DLG,OnDelDlgMsg)END_MESSAGE_MAP()/*實(shí)現(xiàn)消息處理函數(shù)*/LONG CMy53_s1View:OnDelDlgMsg(WPARAM wP,LPARAM lP)delete (CTestDlg2*)wPreturn 0/*創(chuàng)建對(duì)話框*/void CMy53_s1View:OnTest2()CTestDlg2 *dlg=new CTestDlg2(this)dlg>Create(IDD_TEST_DLG_2)dlg>ShowWindow(SW_SHOW)在這種方法中我們利用消息來進(jìn)行通知,在Window 系統(tǒng)中利用消息進(jìn)行通知和傳遞數(shù)據(jù)

18、的用法是很多的。同樣無模式對(duì)話框的另一個(gè)作用還可以用來在用戶在對(duì)話框中的輸入改變時(shí)可以及時(shí)的反映到其他窗口。下面的代碼演示了在對(duì)話框中輸入一段文字,然后將其更新到視圖的顯示區(qū)域中,這同樣也是利用了消息進(jìn)行通知和數(shù)據(jù)傳遞。/*在對(duì)話框中取出數(shù)據(jù),并向其他窗口發(fā)送消息和數(shù)據(jù),將數(shù)據(jù)指針作為一個(gè)參數(shù)發(fā)送*/void CTestDlg2:OnCommBtn()char szOut30GetDlgItemText(IDC_OUT,szOut,30)m_pParent>SendMessage(WM_DLG_NOTIFY,(WPARAM)szOut)/*在消息接收窗口中*/*映射消息處理函數(shù)*/ON_

19、MESSAGE(WM_DLG_NOTIFY,OnDlgNotifyMsg)/*在視圖中繪制出字符串m_szOut*/void CMy53_s1View:OnDraw(CDC* pDC)CMy53_s1Doc* pDoc = GetDocument()ASSERT_VALID(pDoc)/ TODO: add draw code for native data herepDC>TextOut(0,0,"Display String")pDC>TextOut(0,20,m_szOut)/*處理通知消息,保存信息并更新顯示*/LONG CMy53_s1View:OnD

20、lgNotifyMsg(WPARAM wP,LPARAM lP)m_szOut=(char*)wPInvalidate()return 0此外這種用法利用消息傳遞數(shù)據(jù)的方法對(duì)有模式對(duì)話框和其他的窗口間通信也一樣有效。下載本節(jié)例子5.4 在對(duì)話框中進(jìn)行消息映射利用對(duì)話框的一個(gè)好處是可以利用ClassWizard 對(duì)對(duì)話框中各個(gè)控件產(chǎn)生的消息進(jìn)行映射,ClassWizrd 可以列出各種控件可以使用的消息,并能自動(dòng)產(chǎn)生代碼。在本節(jié)中我們以一個(gè)例子來講解如何在對(duì)話框中對(duì)子窗口消息進(jìn)行映射同時(shí)還講解如何對(duì)對(duì)話框中的子窗口進(jìn)行初始化。ID 類型IDC_RADIO_TEST_1 圓形按鈕IDC_RADIO_

21、TEST_2 圓形按鈕IDC_BUTTON_TEST 按鈕IDC_CHECK_TEST 檢查按鈕IDC_TREE_TEST 樹形控件IDC_LIST_CTRL List CtrlIDC_TAB_CTRL Tab CtrlIDC_LIST_TEST 列表框IDC_COMBO_TEST 組合框IDC_EDIT_TEST 輸入框首先我們產(chǎn)生編輯好一個(gè)對(duì)話框,如圖,在對(duì)話框中使用的控件和ID 號(hào)如下表:首先我們需要在對(duì)話框的OnInitDialog()函數(shù)中對(duì)各個(gè)控件進(jìn)行初始化,這里我們使用CWnd* GetDlgItem( int nID )來通過ID 號(hào)得到子窗口指針。( 類似的函數(shù)還有UINTG

22、etDlgItemInt( int nID, BOOL* lpTrans = NULL, BOOL bSigned = TRUE ) 通過ID 號(hào)得到子窗口中輸入的數(shù)字,int GetDlgItemText( int nID, CString& rString ) 通過ID 號(hào)得到子窗口中輸入的文字)。代碼如下:BOOL CMy54_s1Dlg:OnInitDialog()CDialog:OnInitDialog()/*添加初始化代碼*/初始化輸入框(CEdit*)GetDlgItem(IDC_EDIT_TEST)>SetWindowText("thisis a edi

23、t box")/初始化列表框CListBox* pListB=(CListBox*)GetDlgItem(IDC_LIST_TEST)pListB>AddString("item 1")pListB>AddString("item 2")pListB>AddString("item 3")/初始化組合框CComboBox* pCB=(CComboBox*)GetDlgItem(IDC_COMBO_TEST)pCB>AddString("item 1")pCB>AddStrin

24、g("item 2")pCB>AddString("item 3")/初始化Tab CtrlCTabCtrl* pTab=(CTabCtrl*)GetDlgItem(IDC_TAB_TEST)pTab>InsertItem(0,"TabPage1")pTab>InsertItem(1,"TabPage2")pTab>InsertItem(2,"TabPage3")/初始化ListCtrlCListCtrl* pList=(CListCtrl*)GetDlgItem(IDC

25、_LIST_CTRL)pList>InsertColumn(0,"Column 1",LVCFMT_LEFT,100)pList>InsertItem(0,"Item1")pList>InsertItem(1,"Item2")pList>InsertItem(2,"Item3")/初始化TreeCtrlCTreeCtrl* pTree=(CTreeCtrl*)GetDlgItem(IDC_TREE_TEST)pTree>InsertItem("Node1",0,0)

26、HTREEITEMhNode=pTree>InsertItem("Node2",0,0)pTree>InsertItem("Node21",0,0,hNode)pTree>InsertItem("Node22",0,0,hNode)pTree>Expand(hNode,TVE_EXPAND)return TRUE / return TRUE unless you set the focus to a control接下來我們需要利用ClassWizard 對(duì)控件所產(chǎn)生的消息進(jìn)行映射,打開ClassWizard

27、對(duì)話框,選中相關(guān)控件的ID,在右邊的列表中就會(huì)顯示出可用的消息。如我們對(duì)按鈕的消息進(jìn)行映射,在選中按鈕ID(IDC_BUTTON_TEST)后,會(huì)看到兩個(gè)消息,如圖,一個(gè)是BN_CLICKED,一個(gè)是BN_DOUBLECLICKED。雙擊BN_CLICKED 后在彈出的對(duì)話框中輸入函數(shù)名,ClassWizard 會(huì)產(chǎn)生按鈕被按的消息映射。然后我們看看對(duì)TabCtrl 的TCN_SELCHANGE 消息進(jìn)行映射,如圖,在TabCtrl 的當(dāng)前頁選擇發(fā)生改變時(shí)這個(gè)消息會(huì)被發(fā)送,所以通過映射該消息可以在當(dāng)前頁改變時(shí)及時(shí)得到通知。最后我們對(duì)輸入框的EN_CHANGE 消息進(jìn)行映射,如圖,在輸入框中的文

28、本改變后該消息會(huì)被發(fā)送。相關(guān)的代碼如下:/頭文件中相關(guān)的消息處理函數(shù)定義afx_msg void OnButtonTest()afx_msg void OnSelchangeTabTest(NMHDR* pNMHDR, LRESULT* pResult)afx_msg void OnChangeEditTest()/AFX_MSG5.5 在對(duì)話框中進(jìn)行數(shù)據(jù)交換和數(shù)據(jù)檢查MFC 提供兩種方法在對(duì)話框中進(jìn)行數(shù)據(jù)交換和數(shù)據(jù)檢查( Dialog data exchange/Dialog datavalidation),數(shù)據(jù)交換和數(shù)據(jù)檢查的思想是將某一變量和對(duì)話框中的一個(gè)子窗口進(jìn)行關(guān)聯(lián),然后通過調(diào)用BO

29、OL UpdateData( BOOL bSaveAndValidate = TRUE )來指示MFC 將變量中數(shù)據(jù)放入子窗口還是將子窗口中數(shù)據(jù)取到變量中并進(jìn)行合法性檢查。DECLARE_MESSAGE_MAP()/CPP 文件中消息映射代碼ON_BN_CLICKED(IDC_BUTTON_TEST,OnButtonTest)ON_NOTIFY(TCN_SELCHANGE, IDC_TAB_TEST,OnSelchangeTabTest)ON_EN_CHANGE(IDC_EDIT_TEST,OnChangeEditTest)/AFX_MSG_MAPEND_MESSAGE_MAP()/消息處理函

30、數(shù)void CMy54_s1Dlg:OnButtonTest()AfxMessageBox("you pressed a button")void CMy54_s1Dlg:OnSelchangeTabTest(NMHDR* pNMHDR, LRESULT* pResult)TRACE("Tab Select changedn")*pResult = 0void CMy54_s1Dlg:OnChangeEditTest()TRACE("edit_box text changedn")對(duì)于其他的控件都可以采取類似的方法進(jìn)行消息映射,下載例

31、子。此外如果你對(duì)各種控件可以使用的消息不熟悉,你可以通過使用對(duì)話框,然后利用ClassWizard 產(chǎn)生相關(guān)代碼的方法來進(jìn)行學(xué)習(xí),你也可以將ClassWizard 產(chǎn)生的代碼直接拷貝到其他需要的地方(不瞞你說,我最開始就是這樣學(xué)的:D這也算一個(gè)小竅門)。在進(jìn)行數(shù)據(jù)交換時(shí)一個(gè)子窗口可以和兩種類型的變量相關(guān)聯(lián),一種是控件(Control)對(duì)象,比如說按鈕子窗口可以和一個(gè)CButton 對(duì)象相關(guān)聯(lián),這種情況下你可以通過該對(duì)象直接控制子窗口,而不需要象上節(jié)中講的一樣使用GetDlgItem(IDC_CONTROL_ID)來得到窗口指針;一種是內(nèi)容對(duì)象,比如說輸入框可以和一個(gè)CString 對(duì)象關(guān)聯(lián),也

32、可以和一個(gè)UINT 類型變量關(guān)聯(lián),這種情況下你可以直接設(shè)置/獲取窗口中的輸入內(nèi)容。而數(shù)據(jù)檢查是在一個(gè)子窗口和一個(gè)內(nèi)容對(duì)象相關(guān)聯(lián)時(shí)在存取內(nèi)容時(shí)對(duì)內(nèi)容進(jìn)行合法性檢查,比如說當(dāng)一個(gè)輸入框和一個(gè)CString 對(duì)象關(guān)聯(lián)時(shí),你可以設(shè)置檢查CString 的對(duì)象的最長/最小長度,當(dāng)輸入框和一個(gè)UINT 變量相關(guān)聯(lián)時(shí)你可以設(shè)置檢查UINT 變量的最大/最小值。在BOOL UpdateData( BOOL bSaveAndValidate = TRUE )被調(diào)用后,合法性檢查會(huì)自動(dòng)進(jìn)行,如果無法通過檢查MFC 會(huì)彈出消息框進(jìn)行提示,并返回FALSE。設(shè)置DDX/DDV 在VC 中非常簡單,ClassWizar

33、d 可以替你完成所有的工作,你只需要打開ClassWizard 并選中Member Variables 頁,如圖,你可以看到所有可以進(jìn)行關(guān)聯(lián)的子窗口ID列表,雙擊一個(gè)ID 會(huì)彈出一個(gè)添加變量的對(duì)話框,如圖,填寫相關(guān)的信息后按下確定按鈕就可以了。然后選中你剛才添加的變量在底部的輸入框中輸入檢查條件,如圖。下面我們看一個(gè)例子,對(duì)話框上的子窗口如圖設(shè)置,各子窗口的ID 和關(guān)聯(lián)的變量如下表:ID 關(guān)聯(lián)的變量作用IDC_CHECK_TEST BOOL m_fCheck 檢查框是否被選中IDC_RADOI_TEST_1 int m_iSel 當(dāng)前選擇的圓形按鈕的索引IDC_COMBO_TEST CStri

34、ng m_szCombo 組合框中選中的文本或是輸入的文本IDC_EDIT_TESTCString m_szEdit 輸入框中輸入的文本,最大長度為5IDC_LIST_TESTCListBox m_lbTest 列表框?qū)ο筮@時(shí)候ClassWizard 會(huì)自動(dòng)生成變量定義和相關(guān)代碼,在對(duì)話框的構(gòu)造函數(shù)中可以對(duì)變量的初始值進(jìn)行設(shè)置,此外在BOOL CDialog:OnInitDialog()中會(huì)調(diào)用UpdateData(FALSE),即會(huì)將變量中的數(shù)據(jù)放入窗口中。相關(guān)代碼如下:/頭文件中的變量定義,ClassWizard 自動(dòng)產(chǎn)生/ Dialog Data/AFX_DATA(CMy55_s1Dlg

35、)enum IDD = IDD_MY55_S1_DIALOG CListBox m_lbTestint m_iSelCString m_szEditCString m_szComboBOOL m_fCheck/AFX_DATA/構(gòu)造函數(shù)中賦初值CMy55_s1Dlg:CMy55_s1Dlg(CWnd* pParent /*=NULL*/): CDialog(CMy55_s1Dlg:IDD, pParent)/AFX_DATA_INIT(CMy55_s1Dlg)m_iSel = 1m_szEdit = _T("")m_szCombo = _T("")m_f

36、Check = FALSE/AFX_DATA_INIT./ClassWizard 產(chǎn)生的關(guān)聯(lián)和檢查代碼void CMy55_s1Dlg:DoDataExchange(CDataExchange* pDX)CDialog:DoDataExchange(pDX)/AFX_DATA_MAP(CMy55_s1Dlg)DDX_Control(pDX, IDC_LIST_TEST,m_lbTest)DDX_Radio(pDX, IDC_RADIO_TEST_1, m_iSel)DDX_Text(pDX, IDC_EDIT_TEST,m_szEdit)DDV_MaxChars(pDX, m_szEdit,

37、5)DDX_CBString(pDX, IDC_COMBO_TEST, m_szCombo)DDX_Check(pDX, IDC_CHECK_TEST, m_fCheck)/AFX_DATA_MAP/在OnInitDialog 中利用已經(jīng)關(guān)聯(lián)過的變量m_lbTestBOOL CMy55_s1Dlg:OnInitDialog()CDialog:OnInitDialog()./ TODO: Add extra initialization here/設(shè)置列表框中數(shù)據(jù)m_lbTest.AddString("String1")m_lbTest.AddString("Str

38、ing2")m_lbTest.AddString("String3")m_lbTest.AddString("String4")return TRUE / return TRUE unless you set the focus to a control/對(duì)兩個(gè)按鈕消息處理/通過UpdateData(TRUE)得到窗口中數(shù)據(jù)void CMy55_s1Dlg:OnGet()if(UpdateData(TRUE)/數(shù)據(jù)合法性檢查通過,可以使用變量中存放的數(shù)據(jù)CString szOutszOut.Format("radio =%d nche

39、ck is %dnedit input is %sncomboBox input is %sn",m_iSel,m_fCheck,m_szEdit,m_szCombo)AfxMessageBox(szOut)/else 未通過檢查/通過UpdateData(FALSE)將數(shù)據(jù)放入窗口void CMy55_s1Dlg:OnPut()m_szEdit="onPut test"m_szCombo="onPut test"UpdateData(FALSE)在上面的例子中我們看到利用DDX/DDV 和UpdateData(BOOL)調(diào)用我們可以很方便的存

40、取數(shù)據(jù),而且也可以同時(shí)進(jìn)行合法性檢查。下載例子代碼5.6 使用屬性對(duì)話框?qū)傩詫?duì)話框不同于普通對(duì)話框的是它能同時(shí)提供多個(gè)選項(xiàng)頁,而每頁都可以由資源編輯器以編輯對(duì)話框的方式進(jìn)行編輯,這樣給界面開發(fā)帶來了方便。同時(shí)使用上也遵守普通對(duì)話框的規(guī)則,所以學(xué)習(xí)起來很方便。屬性對(duì)話框由兩部分構(gòu)成:多個(gè)屬性頁(CPropertyPage)和屬性對(duì)話框(CPropertySheet)。首先需要編輯屬性頁,在資源編輯器中選擇插入,并且選擇屬性對(duì)話框后就可以插入一個(gè)屬性頁,如圖,或者選擇插入一個(gè)對(duì)話框,然后將其屬性中的Style 設(shè)置為Child,Border 設(shè)置為Thin 也可以,如圖。然后根據(jù)這個(gè)對(duì)話框資源生成

41、一個(gè)新類,在選擇基類時(shí)選擇CPropertyPage,ClassWizard 會(huì)自動(dòng)生成相關(guān)的代碼。而對(duì)于CPropertySheet 也需要生成新類,并且將所有需要加入的屬性頁對(duì)象都作為成員變量。屬性對(duì)話框也分為有模式和無模式兩種,有模式屬性對(duì)話框使用DoModal()創(chuàng)建,無模式屬性對(duì)話框使用Create()創(chuàng)建。下面的代碼演示了如何創(chuàng)建屬性對(duì)話框并添加屬性頁:/修改CPropertySheet 派生類的構(gòu)造函數(shù)為如下形式CSheet:CSheet():CPropertySheet("test sheet", NULL, 0)m_page1.Construct(IDD_

42、PAGE_1)m_page2.Construct(IDD_PAGE_2)AddPage(&m_page1)AddPage(&m_page2)/創(chuàng)建有模式屬性對(duì)話框void CMy56_s1Dlg:OnMod()CSheet sheetsheet.DoModal()/創(chuàng)建無模式屬性對(duì)話框void CMy56_s1Dlg:OnUnm()CSheet *sheet=new CSheetsheet>Create()對(duì)于屬性對(duì)話框可以使用下面的一些成員函數(shù):CPropertyPage* CPropertySheet:GetActivePage( )得到當(dāng)前活動(dòng)頁的指針。BOOL C

43、PropertySheet:SetActivePage( int nPage )用于設(shè)置當(dāng)前活動(dòng)頁。int CPropertySheet:GetPageCount()用于得到當(dāng)前頁總數(shù)。void CPropertySheet:RemovePage( int nPage )用于刪除一頁。而對(duì)于屬性頁來將主要通過重載一些函數(shù)來達(dá)到控制的目的:void CPropertyPage:OnOK() 在屬性對(duì)話框上按下“確定”按鈕后被調(diào)用void CPropertyPage:OnCancel() 在屬性對(duì)話框上按下“取消”按鈕后被調(diào)用void CPropertyPage:OnApply() 在屬性對(duì)話框上

44、按下“應(yīng)用”按鈕后被調(diào)用void CPropertyPage:SetModified( BOOL bChanged = TRUE ) 設(shè)置當(dāng)前頁面上的數(shù)據(jù)被修改標(biāo)記,這個(gè)調(diào)用可以使“應(yīng)用”按鈕為允許狀態(tài)。此外利用屬性對(duì)話框你可以生成向?qū)?duì)話框,向?qū)?duì)話框同樣擁有多個(gè)屬性頁,但同時(shí)只有一頁被顯示,而且對(duì)話框上顯示的按鈕為“上一步”,“下一步”/“完成”,向?qū)?duì)話框會(huì)按照你添加頁面的順序依次顯示所有的頁。在顯示屬性對(duì)話框前你需要調(diào)用voidCPropertySheet:SetWizardMode() 。使用向?qū)?duì)話框時(shí)需要對(duì)屬性頁的BOOLCPropertyPage:OnSetActive( )

45、進(jìn)行重載, 并在其中調(diào)用voidCPropertySheet:SetWizardButtons( DWORD dwFlags )來設(shè)置向?qū)?duì)話框上顯示的按鈕。dwFlags 的取值可為以下值的“或”操作:PSWIZB_BACK 顯示“上一步”按鈕PSWIZB_NEXT 顯示“下一步”按鈕PSWIZB_FINISH 顯示“完成”按鈕PSWIZB_DISABLEDFINISH 顯示禁止的“完成”按鈕void CPropertySheet:SetWizardButtons( DWORD dwFlags )也可以在其他地方調(diào)用,比如說在顯示最后一頁時(shí)先顯示禁止的“完成”按鈕,在完成某些操作后再顯示允許

46、的“完成”按鈕。在使用向?qū)?duì)話框時(shí)可以通過重載一些函數(shù)來達(dá)到控制的目的:void CPropertyPage:OnWizardBack() 按下了“上一步”按鈕。返回0 表示有系統(tǒng)決定需要顯示的頁面,1表示禁止頁面轉(zhuǎn)換,如果希望顯示一個(gè)特定的頁面需要返回該頁面的ID 號(hào)。void CPropertyPage:OnOnWizardNext() 按下了“ 下一步” 按鈕。返回值含義與voidCPropertyPage:OnWizardBack()相同。void CPropertyPage:OnWizardFinish() 按下了“完成”按鈕。返回FALSE 表示不允許繼續(xù),否則返回TRUE 向?qū)?duì)

47、話框?qū)⒈唤Y(jié)束。在向?qū)?duì)話框的DoModal()返回值為ID_WIZFINISH 或IDCANCEL。下面的代碼演示了如何創(chuàng)建并使用向?qū)?duì)話框:/創(chuàng)建有模式向?qū)?duì)話框void CMy56_s1Dlg:OnWiz()CSheet sheetsheet.SetWizardMode()int iRet=sheet.DoModal()/返回ID_WIZFINISH 或IDCANCEL/重載BOOL CPropertyPage:OnSetActive( )來控制顯示的按鈕BOOL CPage1:OnSetActive()(CPropertySheet*)GetParent()>SetWizardBu

48、ttons(PSWIZB_BACK|PSWIZB_NEXT)return CPropertyPage:OnSetActive()BOOL CPage2:OnSetActive()(CPropertySheet*)GetParent()>SetWizardButtons(PSWIZB_BACK|PSWIZB_FINISH)return CPropertyPage:OnSetActive()下載本節(jié)例子。5.7 使用通用對(duì)話框在Windows 系統(tǒng)中提供了一些通用對(duì)話框如:文件選擇對(duì)話框如圖,顏色選擇對(duì)話框如圖,字體選擇對(duì)話框如圖。在MFC 中使用CFileDialog,CColorDial

49、og,CFontDialog 來表示。一般來講你不需要派生新的類,因?yàn)榛愐呀?jīng)提供了常用的功能。而且在創(chuàng)建并等待對(duì)話框結(jié)束后你可以通過成員函數(shù)得到用戶在對(duì)話框中的選擇。CFileDialog 文件選擇對(duì)話框的使用:首先構(gòu)造一個(gè)對(duì)象并提供相應(yīng)的參數(shù),構(gòu)造函數(shù)原型如下:CFileDialog:CFileDialog( BOOL bOpenFileDialog, LPCTSTR lpszDefExt = NULL, LPCTSTRlpszFileName = NULL, DWORD dwFlags = OFN_HIDEREADONLY |OFN_OVERWRITEPROMPT, LPCTSTR lp

50、szFilter = NULL, CWnd* pParentWnd = NULL )參數(shù)意義如下:bOpenFileDialog 為TRUE 則顯示打開對(duì)話框,為FALSE 則顯示保存對(duì)話文件對(duì)話框。lpszDefExt 指定默認(rèn)的文件擴(kuò)展名。lpszFileName 指定默認(rèn)的文件名。dwFlags 指明一些特定風(fēng)格。lpszFilter 是最重要的一個(gè)參數(shù),它指明可供選擇的文件類型和相應(yīng)的擴(kuò)展名。參數(shù)格式如:"Chart Files (*.xlc)|*.xlc|Worksheet Files (*.xls)|*.xls|Data Files (*.xlc*.xls)|*.xlc

51、*.xls|All Files(*.*)|*.*|"文件類型說明和擴(kuò)展名間用| 分隔,同種類型文件的擴(kuò)展名間可以用 分割,每種文件類型間用| 分隔,末尾用| 指明。pParentWnd 為父窗口指針。創(chuàng)建文件對(duì)話框可以使用DoModal(),在返回后可以利用下面的函數(shù)得到用戶選擇:CString CFileDialog:GetPathName( ) 得到完整的文件名, 包括目錄名和擴(kuò)展名如:c:testtest1.txtCString CFileDialog:GetFileName( ) 得到完整的文件名,包括擴(kuò)展名如:test1.txtCString CFileDialog:Get

52、ExtName( ) 得到完整的文件擴(kuò)展名,如:txtCString CFileDialog:GetFileTitle ( ) 得到完整的文件名,不包括目錄名和擴(kuò)展名如:test1POSITION CFileDialog:GetStartPosition( ) 對(duì)于選擇了多個(gè)文件的情況得到第一個(gè)文件位置。CString CFileDialog:GetNextPathName( POSITION& pos ) 對(duì)于選擇了多個(gè)文件的情況得到下一個(gè)文件位置, 并同時(shí)返回當(dāng)前文件名。但必須已經(jīng)調(diào)用過POSITIONCFileDialog:GetStartPosition( )來得到最初的POS

53、ITION 變量。CColorDialog 顏色選擇對(duì)話框的使用:首先通過CColorDialog:CColorDialog( COLORREFclrInit = 0, DWORD dwFlags = 0, CWnd* pParentWnd = NULL )構(gòu)造一個(gè)對(duì)象,其中clrInit 為初始顏色。通過調(diào)用DoModal() 創(chuàng)建對(duì)話框, 在返回后調(diào)用COLORREFCColorDialog:GetColor( )得到用戶選擇的顏色值。CFontDialog 字體選擇對(duì)話框的使用:首先構(gòu)造一個(gè)對(duì)象并提供相應(yīng)的參數(shù),構(gòu)造函數(shù)原型如下:CFontDialog:CFontDialog( LPLO

54、GFONT lplfInitial = NULL, DWORD dwFlags =CF_EFFECTS | CF_SCREENFONTS, CDC* pdcPrinter = NULL, CWnd* pParentWnd = NULL)構(gòu)造一個(gè)對(duì)象,其中參數(shù)lplfInitial 指向一個(gè)LOGFONG 結(jié)構(gòu)(該結(jié)構(gòu)介紹請(qǐng)見2.2 在窗口中輸出文字),如果該參數(shù)設(shè)置為NULL 表示不設(shè)置初始字體。pdcPrinter 指向一個(gè)代表打印機(jī)設(shè)備環(huán)境的DC 對(duì)象,若設(shè)置該參數(shù)則選擇的字體就為打印機(jī)所用。pParentWnd 用于指定父窗口。通過調(diào)用DoModal()創(chuàng)建對(duì)話框,在返回后通過調(diào)用以下函

55、數(shù)來得到用戶選擇:void CFontDialog:GetCurrentFont( LPLOGFONT lplf )用來獲得所選字體的屬性。該函數(shù)有一個(gè)參數(shù),該參數(shù)是指向LOGFONT 結(jié)構(gòu)的指針,函數(shù)將所選字體的各種屬性寫入這個(gè)LOGFONT 結(jié)構(gòu)中。CString CFontDialog:GetFaceName( ) 得到所選字體名字。int CFontDialog:GetSize( ) 得到所選字體的尺寸(以10 個(gè)象素為單位)。COLORREF CFontDialog:GetColor( ) 得到所選字體的顏色。BOOL CFontDialog:IsStrikeOut( )BOOL CFontDialog:IsUnderline( )BOOL CFontDialog:IsBold( )BOOL CFontDialog:IsItalic( )得到所選字體的其他屬性,是否有刪除線,是否有下劃線,是否為粗體,是否為斜體5.8 建立以對(duì)話框?yàn)榛A(chǔ)的應(yīng)用我認(rèn)為初學(xué)者使用以對(duì)話框?yàn)榛A(chǔ)的應(yīng)用是一個(gè)比較好的選擇,因?yàn)檫@樣一來可以擺脫一些開發(fā)界面的麻煩,此外也可以利用ClassWizard 自動(dòng)的添加消息映射。在VC 中提供了生成“以對(duì)話框?yàn)榛A(chǔ)的應(yīng)用”的功能,你所需要選擇的

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論