VisualCMFC入門教程五共6_第1頁
VisualCMFC入門教程五共6_第2頁
VisualCMFC入門教程五共6_第3頁
VisualCMFC入門教程五共6_第4頁
VisualCMFC入門教程五共6_第5頁
已閱讀5頁,還剩12頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

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

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

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

4、 /產(chǎn)生無模式對話框 CTestDlg *dlg=new CTestDlg; dlg-Create(IDD_TEST_DLG); dlg-ShowWindow(SW_SHOW);void CMy51_s1View:OnDoModal() /產(chǎn)生有模式對話框 CTestDlg dlg; int iRet=dlg.DoModal(); TRACE(dlg return %dn,iRet);下載例子。如果你在調(diào)試這個程序時你會發(fā)現(xiàn)程序在退出后會有內(nèi)存泄漏,這是因為我沒有釋放無模式對話框所使用的內(nèi)存,這一問題會在以后的章節(jié)5.3 創(chuàng)建無模式對話框中專門講述。 關(guān)于在使用對話框時Enter鍵和Escap

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

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

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

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

9、ng szOut; szOut.Format(return value %d,iRet); AfxMessageBox(szOut);/重載OnOK,OnCancelvoid CTestDlg:OnOK()/什么也不做void CTestDlg:OnCancel()/什么也不做/在對話框中對三個按鈕消息進(jìn)行映射void CTestDlg:OnExit1() CDialog:OnOK();void CTestDlg:OnExit2() CDialog:OnCancel();void CTestDlg:OnExit3() CDialog:EndDialog(0XFF);由于重載了OnOK和OnCa

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

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

12、的。相關(guān)代碼如下: void CYourView:OnOpenDlg(void) /*假設(shè)IDD_TEST_DLG為已經(jīng)定義的對話框資源的ID號*/ CTestDlg *dlg=new CTestDlg; dlg-Create(IDD_TEST_DLG,NULL); dlg-ShowWindows(SW_SHOW); /*不要調(diào)用 delete dlg;*/在上面的代碼中我們新生成了一個對話框?qū)ο螅以谕顺龊瘮?shù)時并沒有銷毀該對象。因為如果此時銷毀該對象(對象被銷毀時窗口同時被銷毀),而此時對話框還在顯示就會出現(xiàn)錯誤。那么這就提出了一個問題:什么時候銷毀該對象。我時常使用的方法有兩個: 在對話

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

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

15、*/ CTestDlg2:CTestDlg2(CWnd* pParent /*=NULL*/) : CDialog(CTestDlg2:IDD, pParent) /*m_pParent為一成員變量,用于保存通知窗口的指針, 所以該指針不能是一個臨時指針*/ ASSERT(pParent); m_pParent=pParent; /AFX_DATA_INIT(CTestDlg2) / NOTE: the ClassWizard will add member initialization here /AFX_DATA_INIT void CTestDlg2:OnOK() CDialog:OnO

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

17、消息映射代碼*/ ON_MESSAGE(WM_DELETE_DLG,OnDelDlgMsg) END_MESSAGE_MAP() /*實現(xiàn)消息處理函數(shù)*/ LONG CMy53_s1View:OnDelDlgMsg(WPARAM wP,LPARAM lP) delete (CTestDlg2*)wP; return 0; /*創(chuàng)建對話框*/ void CMy53_s1View:OnTest2() CTestDlg2 *dlg=new CTestDlg2(this); dlg-Create(IDD_TEST_DLG_2); dlg-ShowWindow(SW_SHOW); 在這種方法中我們利用消

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

19、M)szOut);/*在消息接收窗口中*/*映射消息處理函數(shù)*/ ON_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 here pDC-TextOut(0,0,Display String); pDC-TextOut(0,20,m_szOut);/*處理通知消息,保存信息

20、并更新顯示*/LONG CMy53_s1View:OnDlgNotifyMsg(WPARAM wP,LPARAM lP) m_szOut=(char*)wP; Invalidate(); return 0;此外這種用法利用消息傳遞數(shù)據(jù)的方法對有模式對話框和其他的窗口間通信也一樣有效。5.4 在對話框中進(jìn)行消息映射 利用對話框的一個好處是可以利用ClassWizard對對話框中各個控件產(chǎn)生的消息進(jìn)行映射,ClassWizrd可以列出各種控件可以使用的消息,并能自動產(chǎn)生代碼。在本節(jié)中我們以一個例子來講解如何在對話框中對子窗口消息進(jìn)行映射同時還講解如何對對話框中的子窗口進(jìn)行初始化。 首先我們產(chǎn)生編輯

21、好一個對話框,如圖,在對話框中使用的控件和ID號如下表: ID類型IDC_RADIO_TEST_1圓形按鈕IDC_RADIO_TEST_2圓形按鈕IDC_BUTTON_TEST按鈕IDC_CHECK_TEST檢查按鈕IDC_TREE_TEST樹形控件IDC_LIST_CTRLList CtrlIDC_TAB_CTRLTab CtrlIDC_LIST_TEST列表框IDC_COMBO_TEST組合框IDC_EDIT_TEST輸入框首先我們需要在對話框的OnInitDialog()函數(shù)中對各個控件進(jìn)行初始化,這里我們使用CWnd* GetDlgItem( int nID )來通過ID號得到子窗口指

22、針。(類似的函數(shù)還有UINT GetDlgItemInt( int nID, BOOL* lpTrans = NULL, BOOL bSigned = TRUE ) 通過ID號得到子窗口中輸入的數(shù)字,int GetDlgItemText( int nID, CString& rString ) 通過ID號得到子窗口中輸入的文字)。代碼如下: BOOL CMy54_s1Dlg:OnInitDialog() CDialog:OnInitDialog(); /*添加初始化代碼*/ /初始化輸入框 (CEdit*)GetDlgItem(IDC_EDIT_TEST)-SetWindowText(this

23、 is a edit 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-AddString(item 2); pCB-AddString(item 3); 初始化Tab Ctr

24、l CTabCtrl* pTab=(CTabCtrl*)GetDlgItem(IDC_TAB_TEST); pTab-InsertItem(0,Tab Page1); pTab-InsertItem(1,Tab Page2); pTab-InsertItem(2,Tab Page3); 初始化ListCtrl CListCtrl* pList=(CListCtrl*)GetDlgItem(IDC_LIST_CTRL); pList-InsertColumn(0,Column 1,LVCFMT_LEFT,100); pList-InsertItem(0,Item 1); pList-Insert

25、Item(1,Item 2); pList-InsertItem(2,Item 3); 初始化TreeCtrl CTreeCtrl* pTree=(CTreeCtrl*)GetDlgItem(IDC_TREE_TEST); pTree-InsertItem(Node1,0,0); HTREEITEM hNode=pTree-InsertItem(Node2,0,0); pTree-InsertItem(Node2-1,0,0,hNode); pTree-InsertItem(Node2-2,0,0,hNode); pTree-Expand(hNode,TVE_EXPAND); return T

26、RUE; / return TRUE unless you set the focus to a control接下來我們需要利用ClassWizard對控件所產(chǎn)生的消息進(jìn)行映射,打開ClassWizard對話框,選中相關(guān)控件的ID,在右邊的列表中就會顯示出可用的消息。如我們對按鈕的消息進(jìn)行映射,在選中按鈕ID(IDC_BUTTON_TEST)后,會看到兩個消息,如圖,一個是BN_CLICKED,一個是BN_DOUBLECLICKED。雙擊BN_CLICKED后在彈出的對話框中輸入函數(shù)名,ClassWizard會產(chǎn)生按鈕被按的消息映射。 然后我們看看對TabCtrl的TCN_SELCHANGE

27、消息進(jìn)行映射,如圖,在TabCtrl的當(dāng)前頁選擇發(fā)生改變時這個消息會被發(fā)送,所以通過映射該消息可以在當(dāng)前頁改變時及時得到通知。最后我們對輸入框的EN_CHANGE消息進(jìn)行映射,如圖,在輸入框中的文本改變后該消息會被發(fā)送。相關(guān)的代碼如下: /頭文件中相關(guān)的消息處理函數(shù)定義 afx_msg void OnButtonTest(); afx_msg void OnSelchangeTabTest(NMHDR* pNMHDR, LRESULT* pResult); afx_msg void OnChangeEditTest(); /AFX_MSG DECLARE_MESSAGE_MAP()/CPP文件

28、中消息映射代碼 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()/消息處理函數(shù)void CMy54_s1Dlg:OnButtonTest() AfxMessageBox(you pressed a button);void CMy54_s1Dlg:OnSelchangeTabTest(NM

29、HDR* pNMHDR, LRESULT* pResult) TRACE(Tab Select changedn); *pResult = 0;void CMy54_s1Dlg:OnChangeEditTest() TRACE(edit_box text changedn); 對于其他的控件都可以采取類似的方法進(jìn)行消息映射。此外如果你對各種控件可以使用的消息不熟悉,你可以通過使用對話框,然后利用ClassWizard產(chǎn)生相關(guān)代碼的方法來進(jìn)行學(xué)習(xí),你也可以將ClassWizard產(chǎn)生的代碼直接拷貝到其他需要的地方(不瞞你說,我最開始就是這樣學(xué)的 :-D 這也算一個小竅門)。 5.5 在對話框中進(jìn)

30、行數(shù)據(jù)交換和數(shù)據(jù)檢查 MFC提供兩種方法在對話框中進(jìn)行數(shù)據(jù)交換和數(shù)據(jù)檢查(Dialog data exchange/Dialog data validation),數(shù)據(jù)交換和數(shù)據(jù)檢查的思想是將某一變量和對話框中的一個子窗口進(jìn)行關(guān)聯(lián),然后通過調(diào)用BOOL UpdateData( BOOL bSaveAndValidate = TRUE )來指示MFC將變量中數(shù)據(jù)放入子窗口還是將子窗口中數(shù)據(jù)取到變量中并進(jìn)行合法性檢查。在進(jìn)行數(shù)據(jù)交換時一個子窗口可以和兩種類型的變量相關(guān)聯(lián),一種是控件(Control)對象,比如說按鈕子窗口可以和一個CButton對象相關(guān)聯(lián),這種情況下你可以通過該對象直接控制子窗口,

31、而不需要象上節(jié)中講的一樣使用GetDlgItem(IDC_CONTROL_ID)來得到窗口指針;一種是內(nèi)容對象,比如說輸入框可以和一個CString對象關(guān)聯(lián),也可以和一個UINT類型變量關(guān)聯(lián),這種情況下你可以直接設(shè)置/獲取窗口中的輸入內(nèi)容。而數(shù)據(jù)檢查是在一個子窗口和一個內(nèi)容對象相關(guān)聯(lián)時在存取內(nèi)容時對內(nèi)容進(jìn)行合法性檢查,比如說當(dāng)一個輸入框和一個CString對象關(guān)聯(lián)時,你可以設(shè)置檢查CString的對象的最長/最小長度,當(dāng)輸入框和一個UINT變量相關(guān)聯(lián)時你可以設(shè)置檢查UINT變量的最大/最小值。在BOOL UpdateData( BOOL bSaveAndValidate = TRUE )被調(diào)用

32、后,合法性檢查會自動進(jìn)行,如果無法通過檢查MFC會彈出消息框進(jìn)行提示,并返回FALSE。設(shè)置DDX/DDV在VC中非常簡單,ClassWizard可以替你完成所有的工作,你只需要打開ClassWizard并選中Member Variables頁,如圖,你可以看到所有可以進(jìn)行關(guān)聯(lián)的子窗口ID列表,雙擊一個ID會彈出一個添加變量的對話框,如圖,填寫相關(guān)的信息后按下確定按鈕就可以了。然后選中你剛才添加的變量在底部的輸入框中輸入檢查條件,如圖。下面我們看一個例子,對話框上的子窗口如圖設(shè)置,各子窗口的ID和關(guān)聯(lián)的變量如下表: ID關(guān)聯(lián)的變量作用IDC_CHECK_TESTBOOL m_fCheck檢查框

33、是否被選中IDC_RADOI_TEST_1int m_iSel當(dāng)前選擇的圓形按鈕的索引IDC_COMBO_TESTCString m_szCombo組合框中選中的文本或是輸入的文本IDC_EDIT_TESTCString m_szEdit輸入框中輸入的文本,最大長度為5IDC_LIST_TESTCListBox m_lbTest列表框?qū)ο筮@時候ClassWizard會自動生成變量定義和相關(guān)代碼,在對話框的構(gòu)造函數(shù)中可以對變量的初始值進(jìn)行設(shè)置,此外在BOOL CDialog:OnInitDialog()中會調(diào)用UpdateData(FALSE),即會將變量中的數(shù)據(jù)放入窗口中 。相關(guān)代碼如下: /

34、頭文件中的變量定義,ClassWizard自動產(chǎn)生/ Dialog Data /AFX_DATA(CMy55_s1Dlg) enum IDD = IDD_MY55_S1_DIALOG ; CListBox m_lbTest; int m_iSel; CString m_szEdit; CString m_szCombo; BOOL m_fCheck; /AFX_DATA/構(gòu)造函數(shù)中賦初值CMy55_s1Dlg:CMy55_s1Dlg(CWnd* pParent /*=NULL*/) : CDialog(CMy55_s1Dlg:IDD, pParent) /AFX_DATA_INIT(CMy55

35、_s1Dlg) m_iSel = -1; m_szEdit = _T(); m_szCombo = _T(); m_fCheck = 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_iSe

36、l); DDX_Text(pDX, IDC_EDIT_TEST, m_szEdit); DDV_MaxChars(pDX, m_szEdit, 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

37、here 設(shè)置列表框中數(shù)據(jù) m_lbTest.AddString(String 1); m_lbTest.AddString(String 2); m_lbTest.AddString(String 3); m_lbTest.AddString(String 4); return TRUE; / return TRUE unless you set the focus to a control/對兩個按鈕消息處理/通過UpdateData(TRUE)得到窗口中數(shù)據(jù)void CMy55_s1Dlg:OnGet() if(UpdateData(TRUE) /數(shù)據(jù)合法性檢查通過,可以使用變量中存放的

38、數(shù)據(jù) CString szOut; szOut.Format(radio =%d ncheck 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和U

39、pdateData(BOOL)調(diào)用我們可以很方便的存取數(shù)據(jù),而且也可以同時進(jìn)行合法性檢查。5.6 使用屬性對話框?qū)傩詫υ捒虿煌谄胀▽υ捒虻氖撬芡瑫r提供多個選項頁,而每頁都可以由資源編輯器以編輯對話框的方式進(jìn)行編輯,這樣給界面開發(fā)帶來了方便。同時使用上也遵守普通對話框的規(guī)則,所以學(xué)習(xí)起來很方便。屬性對話框由兩部分構(gòu)成:多個屬性頁(CPropertyPage)和屬性對話框(CPropertySheet)。首先需要編輯屬性頁,在資源編輯器中選擇插入,并且選擇屬性對話框后就可以插入一個屬性頁,如圖,或者選擇插入一個對話框,然后將其屬性中的Style設(shè)置為Child,Border設(shè)置為Thin也可以

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

41、(IDD_PAGE_1); m_page2.Construct(IDD_PAGE_2); AddPage(&m_page1); AddPage(&m_page2);/創(chuàng)建有模式屬性對話框void CMy56_s1Dlg:OnMod() CSheet sheet; sheet.DoModal();/創(chuàng)建無模式屬性對話框void CMy56_s1Dlg:OnUnm() CSheet *sheet=new CSheet; sheet-Create();對于屬性對話框可以使用下面的一些成員函數(shù): CPropertyPage* CPropertySheet:GetActivePage( )得到當(dāng)前活動頁

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

43、OnApply() 在屬性對話框上按下“應(yīng)用”按鈕后被調(diào)用 void CPropertyPage:SetModified( BOOL bChanged = TRUE ) 設(shè)置當(dāng)前頁面上的數(shù)據(jù)被修改標(biāo)記,這個調(diào)用可以使“應(yīng)用”按鈕為允許狀態(tài)。 此外利用屬性對話框你可以生成向?qū)υ捒颍驅(qū)υ捒蛲瑯訐碛卸鄠€屬性頁,但同時只有一頁被顯示,而且對話框上顯示的按鈕為“上一步”,“下一步”/“完成”,向?qū)υ捒驎凑漳闾砑禹撁娴捻樞蛞来物@示所有的頁。在顯示屬性對話框前你需要調(diào)用void CPropertySheet:SetWizardMode()。使用向?qū)υ捒驎r需要對屬性頁的BOOL CProperty

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

45、禁止的“完成”按鈕,在完成某些操作后再顯示允許的“完成”按鈕。 在使用向?qū)υ捒驎r可以通過重載一些函數(shù)來達(dá)到控制的目的: void CPropertyPage:OnWizardBack() 按下了“上一步”按鈕。返回0表示有系統(tǒng)決定需要顯示的頁面,-1表示禁止頁面轉(zhuǎn)換,如果希望顯示一個特定的頁面需要返回該頁面的ID號。 void CPropertyPage:OnOnWizardNext() 按下了“下一步”按鈕。返回值含義與void CPropertyPage:OnWizardBack()相同。 void CPropertyPage:OnWizardFinish() 按下了“完成”按鈕。返回F

46、ALSE表示不允許繼續(xù),否則返回TRUE向?qū)υ捒驅(qū)⒈唤Y(jié)束。 在向?qū)υ捒虻腄oModal()返回值為ID_WIZFINISH或IDCANCEL。下面的代碼演示了如何創(chuàng)建并使用向?qū)υ捒颍?/創(chuàng)建有模式向?qū)υ捒騰oid CMy56_s1Dlg:OnWiz() CSheet sheet; sheet.SetWizardMode(); int iRet=sheet.DoModal();/返回ID_WIZFINISH或IDCANCEL/重載BOOL CPropertyPage:OnSetActive( )來控制顯示的按鈕BOOL CPage1:OnSetActive() (CPropertyShe

47、et*)GetParent()-SetWizardButtons(PSWIZB_BACK|PSWIZB_NEXT); return CPropertyPage:OnSetActive();BOOL CPage2:OnSetActive() (CPropertySheet*)GetParent()-SetWizardButtons(PSWIZB_BACK|PSWIZB_FINISH); return CPropertyPage:OnSetActive();5.7 使用通用對話框 在Windows系統(tǒng)中提供了一些通用對話框如:文件選擇對話框如圖,顏色選擇對話框如圖,字體選擇對話框如圖。在MFC中使

48、用C,CColorDialog,CFontDialog來表示。一般來講你不需要派生新的類,因為基類已經(jīng)提供了常用的功能。而且在創(chuàng)建并等待對話框結(jié)束后你可以通過成員函數(shù)得到用戶在對話框中的選擇。 C文件選擇對話框的使用:首先構(gòu)造一個對象并提供相應(yīng)的參數(shù),構(gòu)造函數(shù)原型如下:C( BOOL bOpen, LPCTSTR lpszDefExt = NULL, LPCTSTR lpsz = NULL, DWORD dwFlags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, LPCTSTR lpszFilter = NULL, CWnd* pParentWnd =

49、NULL );參數(shù)意義如下: bOpen 為TRUE則顯示打開對話框,為FALSE則顯示保存對話文件對話框。 lpszDefExt 指定默認(rèn)的文件擴展名。 lpsz 指定默認(rèn)的文件名。 dwFlags 指明一些特定風(fēng)格。 lpszFilter 是最重要的一個參數(shù),它指明可供選擇的文件類型和相應(yīng)的擴展名。參數(shù)格式如: Chart Files (*.xlc)|*.xlc|Worksheet Files (*.xls)|*.xls|Data Files (*.xlc;*.xls)|*.xlc; *.xls|All Files (*.*)|*.*|;文件類型說明和擴展名間用 | 分隔,同種類型文件的擴

50、展名間可以用 ; 分割,每種文件類型間用 | 分隔,末尾用 | 指明。 pParentWnd 為父窗口指針。 創(chuàng)建文件對話框可以使用DoModal(),在返回后可以利用下面的函數(shù)得到用戶選擇: CString C( ) 得到完整的文件名,包括目錄名和擴展名如:c:testtest1.txt CString C( ) 得到完整的文件名,包括擴展名如:test1.txt CString C( ) 得到完整的文件擴展名,如:txt CString C ( ) 得到完整的文件名,不包括目錄名和擴展名如:test1 POSITION C( ) 對于選擇了多個文件的情況得到第一個文件位置。 CString

51、 C( POSITION& pos ) 對于選擇了多個文件的情況得到下一個文件位置,并同時返回當(dāng)前文件名。但必須已經(jīng)調(diào)用過POSITION C( )來得到最初的POSITION變量。 CColorDialog顏色選擇對話框的使用:首先通過CColorDialog:CColorDialog( COLORREF clrInit = 0, DWORD dwFlags = 0, CWnd* pParentWnd = NULL )構(gòu)造一個對象,其中clrInit為初始顏色。通過調(diào)用DoModal()創(chuàng)建對話框,在返回后調(diào)用COLORREF CColorDialog:GetColor( )得到用戶選擇的顏

52、色值。 CFontDialog字體選擇對話框的使用:首先構(gòu)造一個對象并提供相應(yīng)的參數(shù),構(gòu)造函數(shù)原型如下: CFontDialog:CFontDialog( LPLOGFONT lplfInitial = NULL, DWORD dwFlags = CF_EFFECTS | CF_SCREENFONTS, CDC* pdcPrinter = NULL, CWnd* pParentWnd = NULL );構(gòu)造一個對象,其中參數(shù)lplfInitial指向一個LOGFONG結(jié)構(gòu)(該結(jié)構(gòu)介紹請見2.2 在窗口中輸出文字),如果該參數(shù)設(shè)置為NULL表示不設(shè)置初始字體。pdcPrinter指向一個代表打印

53、機設(shè)備環(huán)境的DC對象,若設(shè)置該參數(shù)則選擇的字體就為打印機所用。pParentWnd用于指定父窗口。通過調(diào)用DoModal()創(chuàng)建對話框,在返回后通過調(diào)用以下函數(shù)來得到用戶選擇: void CFontDialog:GetCurrentFont( LPLOGFONT lplf );用來獲得所選字體的屬性。該函數(shù)有一個參數(shù),該參數(shù)是指向LOGFONT結(jié)構(gòu)的指針,函數(shù)將所選字體的各種屬性寫入這個LOGFONT結(jié)構(gòu)中。 CString CFontDialog:GetFaceName( ) 得到所選字體名字。 int CFontDialog:GetSize( ) 得到所選字體的尺寸(以10個象素為單位)。

54、 COLORREF CFontDialog:GetColor( ) 得到所選字體的顏色。 BOOL CFontDialog:IsStrikeOut( )BOOL CFontDialog:IsUnderline( )BOOL CFontDialog:IsBold( )BOOL CFontDialog:IsItalic( )得到所選字體的其他屬性,是否有刪除線,是否有下劃線,是否為粗體,是否為斜體。 5.8 建立以對話框為基礎(chǔ)的應(yīng)用我認(rèn)為初學(xué)者使用以對話框為基礎(chǔ)的應(yīng)用是一個比較好的選擇,因為這樣一來可以擺脫一些開發(fā)界面的麻煩,此外也可以利用ClassWizard自動的添加消息映射。在VC中提供了生成“以對話框為基礎(chǔ)的應(yīng)用”的功能,你所需要選擇的是在使用AppWizard的第一步選擇“對話框為基礎(chǔ)的應(yīng)用”,如圖。VC會生成包含有應(yīng)用派生類和對話框派生類的代碼。在應(yīng)用類的InitInstance()成員函數(shù)中可以看到如下的代碼: BOOL CMy58_s1App:InitInstance() CMy58_s1Dlg dlg; m_pMainWnd =

溫馨提示

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

評論

0/150

提交評論