




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
1、5.1 使用資源編輯器編輯對話框在Windows開發(fā)中彈出對話框是一種常用的輸入/輸出手段,同時(shí)編輯好的對話框可以保存在資源文件中。Visual C+提供了對話框編輯工具,利用編輯工具可以方便的添加各種控件到對話框中,而且利用ClassWizard可以方便的生成新的對話框類和映射消息。首先資源列表中按下右鍵,可以在彈出菜單中選擇“插入對話框”,如圖1。然后再打開該對話框進(jìn)行編輯,你會(huì)在屏幕上看到一個(gè)控件板,如圖2。你可以將所需要添加的控件拖到對話框上,或是先選中后再在對話框上用鼠標(biāo)畫出所占的區(qū)域。接下來我們在對話框上產(chǎn)生一個(gè)輸入框,和一個(gè)用于顯示圖標(biāo)的圖片框。之后我們使用鼠標(biāo)右鍵單擊產(chǎn)生的控件
2、并選擇其屬性,如圖3。我們可以在屬性對話框中編輯控件的屬性同時(shí)也需要指定控件ID,如圖4,如果在選擇對話框本身的屬性那么你可以選擇對話框的一些屬性,包括字體,外觀,是否有系統(tǒng)菜單等等。最后我們編輯圖片控件的屬性,如圖5,我們設(shè)置控件的屬性為顯示圖標(biāo)并指明一個(gè)圖標(biāo)ID。接下來我們添加一些其他的控件,最后的效果如圖6。按下Ctrl-T可以測試該對話框。此外在對話框中還有一個(gè)有用的特性,就是可以利用Tab鍵讓輸入焦點(diǎn)在各個(gè)控件間移動(dòng),要達(dá)到這一點(diǎn)首先需要為控件設(shè)置在Tab鍵按下時(shí)可以接受焦點(diǎn)移動(dòng)的屬性Tab Stop,如果某一個(gè)控件不打算利用這一特性,你需要清除這一屬性。然后從菜單“Layout”選
3、擇Tab Order來確定焦點(diǎn)移動(dòng)順序,如圖7。使用鼠標(biāo)依此點(diǎn)擊控件就可以重新規(guī)定焦點(diǎn)移動(dòng)次序。最后按下Ctrl-T進(jìn)行測試。最后我們需要為對話框產(chǎn)生新的類,ClassWizard可以替我們完成大部分的工作,我們只需要填寫幾個(gè)參數(shù)就可以了。在編輯好的對話框上雙擊,然后系統(tǒng)回詢問是否添加新的對話框,選擇是并在接下來的對話框中輸入類名就可以了。ClassWizard會(huì)為你產(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)試這個(gè)程序時(shí)你會(huì)發(fā)現(xiàn)程序在退出后會(huì)有內(nèi)存泄漏,這是因?yàn)槲覜]有釋放無模式對話框所使用的內(nèi)存,這一問題會(huì)在以后的章節(jié)5.3 創(chuàng)建無模式對話框中專門講述。 關(guān)于在使用對話框時(shí)Enter鍵和Escap
5、e鍵的處理:在使用對話框是你會(huì)發(fā)現(xiàn)當(dāng)你按下Enter鍵或Escape鍵都會(huì)退出對話框,這是因?yàn)镋nter鍵會(huì)引起CDialog:OnOK()的調(diào)用,而Escape鍵會(huì)引起CDialog:OnCancel()的調(diào)用。而這兩個(gè)調(diào)用都會(huì)引起對話框的退出。在MFC中這兩個(gè)成員函數(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)建有模式對話框 使用有模式對話框時(shí)在對話框彈出后調(diào)用函數(shù)不會(huì)立即返回,而是等到對話框銷毀后才會(huì)返回(請注意在對話框彈出后其他窗口的消息依然會(huì)被傳遞)。所以在使用對話框時(shí)其他窗口都不能接收用戶輸入。創(chuàng)建有模式對話框的方法是調(diào)用CDialog:DoModal()。下面的代碼演示了這種用法: CYourView:OnOpenDlg() CYourDlg dlg; int iRet=dlg.DoModal();CDialog:DoModal()的返回值為IDOK,IDCANCEL
7、。表明操作者在對話框上選擇“確認(rèn)”或是“取消”。由于在對話框銷毀前DoModal不會(huì)返回,所以可以使用局部變量來引用對象。在退出函數(shù)體后對象同時(shí)也會(huì)被銷毀。而對于無模式對話框則不能這樣使用,下節(jié)5.3 創(chuàng)建無模式對話框中會(huì)詳細(xì)講解。 你需要根據(jù)DoModal()的返回值來決定你下一步的動(dòng)作,而得到返回值也是使用有模式對話框的一個(gè)很大原因。使用有模式對話框需要注意一些問題,比如說不要在一些反復(fù)出現(xiàn)的事件處理過程中生成有模式對話框,比如說在定時(shí)器中產(chǎn)生有模式對話框,因?yàn)樵谏弦粋€(gè)對話框還未退出時(shí),定時(shí)器消息又會(huì)引起下一個(gè)對話框的彈出。同樣的在你的對話框類中為了向調(diào)用者返回不同的值可以調(diào)用CDialo
8、g:OnOK()或是CDialog:OnCancel()以返回IDOK或IDCANCEL,如果你希望返回其他的值,你需要調(diào)用 CDialog:EndDialog( int nResult );其中nResult會(huì)作為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()/什么也不做/在對話框中對三個(gè)按鈕消息進(jìn)行映射void CTestDlg:OnExit1() CDialog:OnOK();void CTestDlg:OnExit2() CDialog:OnCancel();void CTestDlg:OnExit3() CDialog:EndDialog(0XFF);由于重載了OnOK和OnCa
10、ncel所以在對話框中按下Enter鍵或Escape鍵時(shí)都不會(huì)退出,只有按下三個(gè)按鈕中的其中一個(gè)才會(huì)返回。 此外在對話框被生成是會(huì)自動(dòng)調(diào)用BOOL CDialog:OnInitDialog(),你如果需要在對話框顯示前對其中的控件進(jìn)行初始化,你需要重載這個(gè)函數(shù),并在其中填入相關(guān)的初始化代碼。利用ClassWizard可以方便的產(chǎn)生一些默認(rèn)代碼,首先打開ClassWizard,選擇相應(yīng)的對話框類,在右邊的消息列表中選擇WM_INITDIALOG并雙擊,如圖,ClassWizard會(huì)自動(dòng)產(chǎn)生相關(guān)代碼,代碼如下: BOOL CTestDlg:OnInitDialog() /*先調(diào)用父類的同名函數(shù)*/
11、 CDialog:OnInitDialog(); /*填寫你的初始化代碼*/ return TRUE; 有關(guān)對對話框中控件進(jìn)行初始化會(huì)在5.4 在對話框中進(jìn)行消息映射中進(jìn)行更詳細(xì)的講解。 5.3 創(chuàng)建無模式對話框 無模式對話框與有模式對話框不同的是在創(chuàng)建后其他窗口都可以繼續(xù)接收用戶輸入,因此無模式對話框有些類似一個(gè)彈出窗口。創(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;*/在上面的代碼中我們新生成了一個(gè)對話框?qū)ο?,而且在退出函?shù)時(shí)并沒有銷毀該對象。因?yàn)槿绻藭r(shí)銷毀該對象(對象被銷毀時(shí)窗口同時(shí)被銷毀),而此時(shí)對話框還在顯示就會(huì)出現(xiàn)錯(cuò)誤。那么這就提出了一個(gè)問題:什么時(shí)候銷毀該對象。我時(shí)常使用的方法有兩個(gè): 在對話
13、框退出時(shí)銷毀自己:在對話框中重載OnOK與OnCancel在函數(shù)中調(diào)用父類的同名函數(shù),然后調(diào)用DestroyWindow()強(qiáng)制銷毀窗口,在對話框中映射WM_DESTROY消息,在消息處理函數(shù)中調(diào)用delete this;強(qiáng)行刪除自身對象。相關(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ǎn)是在窗口被銷毀的時(shí)候,刪除自身對象。所以你可以在任何時(shí)候調(diào)用DestroyWindow()以達(dá)到徹底銷毀自身對象的作用。(DestroyWindow()的調(diào)用會(huì)引起OnDestroy()的調(diào)用) 通過向父親窗口發(fā)送消息,要求其他窗口對其進(jìn)行銷毀:首先需要定義一個(gè)消息用于進(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為一成員變量,用于保存通知窗口的指針, 所以該指針不能是一個(gè)臨時(shí)指針*/ 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ā)送消息,將自身指針作為一個(gè)參數(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() /*實(shí)現(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ù)的用法是很多的。 同樣無模式對話框的另一個(gè)作用還可以用來在用戶在對話框中的輸入改變時(shí)可以及時(shí)的反映到其他窗口。下面的代碼演示了在對話框中輸入一段文字,然后將其更新到視圖的顯示區(qū)域中,這同樣也是利用了消息進(jìn)行通知和數(shù)據(jù)傳遞。 /*在對話框中取出數(shù)據(jù),并向其他窗口發(fā)送消息和數(shù)據(jù),將數(shù)據(jù)指針作為一個(gè)參數(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)行消息映射 利用對話框的一個(gè)好處是可以利用ClassWizard對對話框中各個(gè)控件產(chǎn)生的消息進(jìn)行映射,ClassWizrd可以列出各種控件可以使用的消息,并能自動(dòng)產(chǎn)生代碼。在本節(jié)中我們以一個(gè)例子來講解如何在對話框中對子窗口消息進(jìn)行映射同時(shí)還講解如何對對話框中的子窗口進(jìn)行初始化。 首先我們產(chǎn)生編輯
21、好一個(gè)對話框,如圖,在對話框中使用的控件和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ù)中對各個(gè)控件進(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,在右邊的列表中就會(huì)顯示出可用的消息。如我們對按鈕的消息進(jìn)行映射,在選中按鈕ID(IDC_BUTTON_TEST)后,會(huì)看到兩個(gè)消息,如圖,一個(gè)是BN_CLICKED,一個(gè)是BN_DOUBLECLICKED。雙擊BN_CLICKED后在彈出的對話框中輸入函數(shù)名,ClassWizard會(huì)產(chǎn)生按鈕被按的消息映射。 然后我們看看對TabCtrl的TCN_SELCHANGE
27、消息進(jìn)行映射,如圖,在TabCtrl的當(dāng)前頁選擇發(fā)生改變時(shí)這個(gè)消息會(huì)被發(fā)送,所以通過映射該消息可以在當(dāng)前頁改變時(shí)及時(shí)得到通知。最后我們對輸入框的EN_CHANGE消息進(jìn)行映射,如圖,在輸入框中的文本改變后該消息會(huì)被發(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 這也算一個(gè)小竅門)。 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ù)檢查的思想是將某一變量和對話框中的一個(gè)子窗口進(jìn)行關(guān)聯(lián),然后通過調(diào)用BOOL UpdateData( BOOL bSaveAndValidate = TRUE )來指示MFC將變量中數(shù)據(jù)放入子窗口還是將子窗口中數(shù)據(jù)取到變量中并進(jìn)行合法性檢查。在進(jìn)行數(shù)據(jù)交換時(shí)一個(gè)子窗口可以和兩種類型的變量相關(guān)聯(lián),一種是控件(Control)對象,比如說按鈕子窗口可以和一個(gè)CButton對象相關(guān)聯(lián),這種情況下你可以通過該對象直接控制子窗口,
31、而不需要象上節(jié)中講的一樣使用GetDlgItem(IDC_CONTROL_ID)來得到窗口指針;一種是內(nèi)容對象,比如說輸入框可以和一個(gè)CString對象關(guān)聯(lián),也可以和一個(gè)UINT類型變量關(guān)聯(lián),這種情況下你可以直接設(shè)置/獲取窗口中的輸入內(nèi)容。而數(shù)據(jù)檢查是在一個(gè)子窗口和一個(gè)內(nèi)容對象相關(guān)聯(lián)時(shí)在存取內(nèi)容時(shí)對內(nèi)容進(jìn)行合法性檢查,比如說當(dāng)一個(gè)輸入框和一個(gè)CString對象關(guān)聯(lián)時(shí),你可以設(shè)置檢查CString的對象的最長/最小長度,當(dāng)輸入框和一個(gè)UINT變量相關(guān)聯(lián)時(shí)你可以設(shè)置檢查UINT變量的最大/最小值。在BOOL UpdateData( BOOL bSaveAndValidate = TRUE )被調(diào)用
32、后,合法性檢查會(huì)自動(dòng)進(jìn)行,如果無法通過檢查MFC會(huì)彈出消息框進(jìn)行提示,并返回FALSE。設(shè)置DDX/DDV在VC中非常簡單,ClassWizard可以替你完成所有的工作,你只需要打開ClassWizard并選中Member Variables頁,如圖,你可以看到所有可以進(jìn)行關(guān)聯(lián)的子窗口ID列表,雙擊一個(gè)ID會(huì)彈出一個(gè)添加變量的對話框,如圖,填寫相關(guān)的信息后按下確定按鈕就可以了。然后選中你剛才添加的變量在底部的輸入框中輸入檢查條件,如圖。下面我們看一個(gè)例子,對話框上的子窗口如圖設(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ū)ο筮@時(shí)候ClassWizard會(huì)自動(dòng)生成變量定義和相關(guān)代碼,在對話框的構(gòu)造函數(shù)中可以對變量的初始值進(jìn)行設(shè)置,此外在BOOL CDialog:OnInitDialog()中會(huì)調(diào)用UpdateData(FALSE),即會(huì)將變量中的數(shù)據(jù)放入窗口中 。相關(guān)代碼如下: /
34、頭文件中的變量定義,ClassWizard自動(dòng)產(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/對兩個(gè)按鈕消息處理/通過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ù),而且也可以同時(shí)進(jìn)行合法性檢查。5.6 使用屬性對話框?qū)傩詫υ捒虿煌谄胀▽υ捒虻氖撬芡瑫r(shí)提供多個(gè)選項(xiàng)頁,而每頁都可以由資源編輯器以編輯對話框的方式進(jìn)行編輯,這樣給界面開發(fā)帶來了方便。同時(shí)使用上也遵守普通對話框的規(guī)則,所以學(xué)習(xí)起來很方便。屬性對話框由兩部分構(gòu)成:多個(gè)屬性頁(CPropertyPage)和屬性對話框(CPropertySheet)。首先需要編輯屬性頁,在資源編輯器中選擇插入,并且選擇屬性對話框后就可以插入一個(gè)屬性頁,如圖,或者選擇插入一個(gè)對話框,然后將其屬性中的Style設(shè)置為Child,Border設(shè)置為Thin也可以
40、,如圖。然后根據(jù)這個(gè)對話框資源生成一個(gè)新類,在選擇基類時(shí)選擇CPropertyPage,ClassWizard會(huì)自動(dòng)生成相關(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)前活動(dòng)頁
42、的指針。 BOOL CPropertySheet:SetActivePage( int nPage )用于設(shè)置當(dāng)前活動(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)記,這個(gè)調(diào)用可以使“應(yīng)用”按鈕為允許狀態(tài)。 此外利用屬性對話框你可以生成向?qū)υ捒?,向?qū)υ捒蛲瑯訐碛卸鄠€(gè)屬性頁,但同時(shí)只有一頁被顯示,而且對話框上顯示的按鈕為“上一步”,“下一步”/“完成”,向?qū)υ捒驎?huì)按照你添加頁面的順序依次顯示所有的頁。在顯示屬性對話框前你需要調(diào)用void CPropertySheet:SetWizardMode()。使用向?qū)υ捒驎r(shí)需要對屬性頁的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)用,比如說在顯示最后一頁時(shí)先顯示
45、禁止的“完成”按鈕,在完成某些操作后再顯示允許的“完成”按鈕。 在使用向?qū)υ捒驎r(shí)可以通過重載一些函數(shù)來達(dá)到控制的目的: void CPropertyPage:OnWizardBack() 按下了“上一步”按鈕。返回0表示有系統(tǒng)決定需要顯示的頁面,-1表示禁止頁面轉(zhuǎn)換,如果希望顯示一個(gè)特定的頁面需要返回該頁面的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來表示。一般來講你不需要派生新的類,因?yàn)榛愐呀?jīng)提供了常用的功能。而且在創(chuàng)建并等待對話框結(jié)束后你可以通過成員函數(shù)得到用戶在對話框中的選擇。 C文件選擇對話框的使用:首先構(gòu)造一個(gè)對象并提供相應(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)的文件擴(kuò)展名。 lpsz 指定默認(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; *.xls|All Files (*.*)|*.*|;文件類型說明和擴(kuò)展名間用 | 分隔,同種類型文件的擴(kuò)
50、展名間可以用 ; 分割,每種文件類型間用 | 分隔,末尾用 | 指明。 pParentWnd 為父窗口指針。 創(chuàng)建文件對話框可以使用DoModal(),在返回后可以利用下面的函數(shù)得到用戶選擇: CString C( ) 得到完整的文件名,包括目錄名和擴(kuò)展名如:c:testtest1.txt CString C( ) 得到完整的文件名,包括擴(kuò)展名如:test1.txt CString C( ) 得到完整的文件擴(kuò)展名,如:txt CString C ( ) 得到完整的文件名,不包括目錄名和擴(kuò)展名如:test1 POSITION C( ) 對于選擇了多個(gè)文件的情況得到第一個(gè)文件位置。 CString
51、 C( POSITION& pos ) 對于選擇了多個(gè)文件的情況得到下一個(gè)文件位置,并同時(shí)返回當(dāng)前文件名。但必須已經(jīng)調(diào)用過POSITION C( )來得到最初的POSITION變量。 CColorDialog顏色選擇對話框的使用:首先通過CColorDialog:CColorDialog( COLORREF clrInit = 0, DWORD dwFlags = 0, CWnd* pParentWnd = NULL )構(gòu)造一個(gè)對象,其中clrInit為初始顏色。通過調(diào)用DoModal()創(chuàng)建對話框,在返回后調(diào)用COLORREF CColorDialog:GetColor( )得到用戶選擇的顏
52、色值。 CFontDialog字體選擇對話框的使用:首先構(gòu)造一個(gè)對象并提供相應(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)造一個(gè)對象,其中參數(shù)lplfInitial指向一個(gè)LOGFONG結(jié)構(gòu)(該結(jié)構(gòu)介紹請見2.2 在窗口中輸出文字),如果該參數(shù)設(shè)置為NULL表示不設(shè)置初始字體。pdcPrinter指向一個(gè)代表打印
53、機(jī)設(shè)備環(huán)境的DC對象,若設(shè)置該參數(shù)則選擇的字體就為打印機(jī)所用。pParentWnd用于指定父窗口。通過調(diào)用DoModal()創(chuàng)建對話框,在返回后通過調(diào)用以下函數(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è)象素為單位)。
54、 COLORREF CFontDialog:GetColor( ) 得到所選字體的顏色。 BOOL CFontDialog:IsStrikeOut( )BOOL CFontDialog:IsUnderline( )BOOL CFontDialog:IsBold( )BOOL CFontDialog:IsItalic( )得到所選字體的其他屬性,是否有刪除線,是否有下劃線,是否為粗體,是否為斜體。 5.8 建立以對話框?yàn)榛A(chǔ)的應(yīng)用我認(rèn)為初學(xué)者使用以對話框?yàn)榛A(chǔ)的應(yīng)用是一個(gè)比較好的選擇,因?yàn)檫@樣一來可以擺脫一些開發(fā)界面的麻煩,此外也可以利用ClassWizard自動(dòng)的添加消息映射。在VC中提供了生成“以對話框?yàn)榛A(chǔ)的應(yīng)用”的功能,你所需要選擇的是在使用AppWizard的第一步選擇“對話框?yàn)榛A(chǔ)的應(yīng)用”,如圖。VC會(huì)生成包含有應(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)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 道路運(yùn)輸掛靠合作協(xié)議
- 鎂基脫硫劑企業(yè)數(shù)字化轉(zhuǎn)型與智慧升級戰(zhàn)略研究報(bào)告
- 2025年醫(yī)療社會(huì)保障服務(wù)合作協(xié)議書
- 健康生活中心藥品采購協(xié)議
- 電信業(yè)務(wù)合作經(jīng)營合同
- 2025-2030年中國靜力水準(zhǔn)儀行業(yè)運(yùn)行狀況及發(fā)展趨勢分析報(bào)告
- 2025-2030年中國除草劑市場運(yùn)營狀況發(fā)展趨勢分析報(bào)告
- 2025-2030年中國鋁板帶箔行業(yè)運(yùn)營狀況與發(fā)展?jié)摿Ψ治鰣?bào)告
- 軟件開發(fā)外包服務(wù)免責(zé)合同協(xié)議
- 塔式起重機(jī)司機(jī)操作證過關(guān)監(jiān)控模擬題帶答案
- 新修訂《中小學(xué)教師職業(yè)道德規(guī)范》解讀
- 品質(zhì)月工作總結(jié)
- 江西省南昌市2024屆高三一模語文試題及答案解析
- 第一章村集體經(jīng)濟(jì)組織會(huì)計(jì)制度講解
- 2024年濟(jì)南護(hù)理職業(yè)學(xué)院高職單招(英語/數(shù)學(xué)/語文)筆試歷年參考題庫含答案解析
- -藝術(shù)博覽會(huì)與藝術(shù)品拍賣
- 2024年貴州水投水務(wù)集團(tuán)有限公司招聘筆試參考題庫含答案解析
- (完整版)ERP流程及操作手冊
- 接上童氣:小學(xué)《道德與法治》統(tǒng)編教材研究
- 武器講解課件
- 關(guān)于魯迅簡介
評論
0/150
提交評論