版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、第五章對(duì)話框5.1 使用資源編輯器編輯對(duì)話框在Win dows開發(fā)中彈出對(duì)話框是一種常用的輸入/輸出手段,同時(shí)編輯好的對(duì)話框可以保存在資源文件中。Visual C+提供了對(duì)話框編輯工具,利用編輯工具可以方便的添加各種控件 到對(duì)話框中,而且利用 ClassWizard 可以方便的生成新的對(duì)話框類和映射消息。首先資源列表中按下右鍵,可以在彈出菜單中選擇“插入對(duì)話框”,如圖1。然后再打開該對(duì)話框進(jìn)行編輯,你會(huì)在屏幕上看到一個(gè)控件板,如圖2。你可以將所需要添加的控件拖到對(duì)話框上,或是先選中后再在對(duì)話框上用鼠標(biāo)畫出所占的區(qū)域。接下來(lái)我們?cè)趯?duì)話框上產(chǎn)生一個(gè)輸入框,和一個(gè)用于顯示圖標(biāo)的圖片框。 之后我們使用
2、鼠標(biāo)右鍵單擊產(chǎn)生的控件并選擇其屬性,如圖3。我們可以在屬性對(duì)話框中編輯控件的屬性同時(shí)也需要指定控件ID,如圖4,如果在選擇對(duì)話框本身的屬性那么你可以選擇對(duì)話框的一些屬 性,包括字體,外觀,是否有系統(tǒng)菜單等等。最后我們編輯圖片控件的屬性,如圖5,我們?cè)O(shè)置控件的屬性為顯示圖標(biāo)并指明一個(gè)圖標(biāo) ID。接下來(lái)我們添加一些其他的控件,最后的效果如圖6。按下 CtrlT可以測(cè)試該對(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來(lái)確定焦點(diǎn)移動(dòng)順序,如圖 7。使用鼠標(biāo)依此點(diǎn)擊控件就可以重新規(guī)定焦點(diǎn)移動(dòng)次序。最后 按下 CtrlT進(jìn)行測(cè)試。最后我們需要為對(duì)話框產(chǎn)生新的類, ClassWizard 可以替我們完成大部分的工作, 我們只需 要填寫幾個(gè)參數(shù)就可以了。 在編輯好的對(duì)話框上雙擊, 然后系統(tǒng)回詢問是否添加新的對(duì)話框, 選擇是并在接下來(lái)的對(duì)話框中輸入類名就可以了。 ClassWizard 會(huì)為你產(chǎn)生所需要的頭文件 和CPP文件。然后在需要使用的地方包含相應(yīng)的頭文件,對(duì)于有模式對(duì)話框使用DoModal()產(chǎn)生,對(duì)于無(wú)模式對(duì)話框使用 Create() 產(chǎn)生。相關(guān)代碼
4、如下;void CMy51_s1View:OnCreateDlg()/ 產(chǎn)生無(wú)模式對(duì)話框CTestDlg *dlg=new CTestDlg ?dlg> Create(IDD_TEST_DLG)?dlg>ShowWindow(SW_SHO?W)void CMy51_s1View:OnDoModal()/ 產(chǎn)生有模式對(duì)話框CTestDlg dlg ?int iRet=dlg.DoModal() ?TRACE("dlg return %dn",iRet) ?下載例子。 如果你在調(diào)試這個(gè)程序時(shí)你會(huì)發(fā)現(xiàn)程序在退出后會(huì)有內(nèi)存泄漏,這是因?yàn)槲覜]有釋放無(wú)模式對(duì)話框所使用的內(nèi)存
5、, 這一問題會(huì)在以后的章節(jié) 5.3 創(chuàng)建無(wú)模式對(duì)話框中專門講 述。關(guān)于在使用對(duì)話框時(shí) Enter 鍵和 Escape 鍵的處理:在使用對(duì)話框是你會(huì)發(fā)現(xiàn)當(dāng)你按下 Enter 鍵或 Escape 鍵都會(huì)退出對(duì)話框,這是因?yàn)?Enter 鍵會(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
6、() 。相關(guān)代碼如下;void CTestDlg:OnOK()AfxMessageBox(" 你選擇確定 ") ?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:DoModa
7、l() 。下面的代碼演 示了這種用法:CYourView:OnOpenDlg()CYourDlg dlg ?int iRet=dlg.DoModal() ?CDialog:DoModal() 的返回值為IDOK, IDCANCEL表明操作者在對(duì)話框上選擇“確認(rèn)” 或是“取消”。由于在對(duì)話框銷毀前 DoModal 不會(huì)返回,所以可以使用局部變量來(lái)引用對(duì) 象。在退出函數(shù)體后對(duì)象同時(shí)也會(huì)被銷毀。 而對(duì)于無(wú)模式對(duì)話框則不能這樣使用, 下節(jié) 5.3 創(chuàng) 建無(wú)模式對(duì)話框中會(huì)詳細(xì)講解。你需要根據(jù) DoModal() 的返回值來(lái)決定你下一步的動(dòng)作,而得到返回值也是使用有模式對(duì)話 框的一個(gè)很大原因。使用有模式對(duì)
8、話框需要注意一些問題, 比如說不要在一些反復(fù)出現(xiàn)的事件處理過程中生成有 模式對(duì)話框, 比如說在定時(shí)器中產(chǎn)生有模式對(duì)話框, 因?yàn)樵谏弦粋€(gè)對(duì)話框還未退出時(shí), 定時(shí) 器消息又會(huì)引起下一個(gè)對(duì)話框的彈出。同樣的在你的對(duì)話框類中為了向調(diào)用者返回不同的值可以調(diào)用 CDialog:OnOK() 或是 CDialog:OnCancel()以返回IDOK或IDCANCEL如果你希望返回其他的值,你需要調(diào)用CDialog:EndDialog( int nResult )?其中 nResult 會(huì)作為 DoModal() 調(diào)用的返回值。下面的代碼演示了如何使用自己的函數(shù)來(lái)退出對(duì)話框:下載例子void CMy52_s1
9、View:OnLButtonDown(UINT nFlags, CPoint point)/ 創(chuàng)建對(duì)話框并得到返回值CView:OnLButtonDown(nFlags, point) ?CTestDlg dlg ?int iRet=dlg.DoModal() ?CString szOut ?szOut.Format("return value %d",iRet) ?AfxMessageBox(szOut) ?/ 重載 OnOK,OnCancelvoid CTestDlg:OnOK()/ 什么也不做void CTestDlg:OnCancel()/ 什么也不做/ 在對(duì)話框中
10、對(duì)三個(gè)按鈕消息進(jìn)行映射void CTestDlg:OnExit1()CDialog:OnOK() ?void CTestDlg:OnExit2()CDialog:OnCancel() ?void CTestDlg:OnExit3()CDialog:EndDialog(0XFF) ?由于重載了 On OK和On Ca ncel所以在對(duì)話框中按下 En ter鍵或Escape鍵時(shí)都不會(huì)退出,只 有按下三個(gè)按鈕中的其中一個(gè)才會(huì)返回。此外在對(duì)話框被生成是會(huì)自動(dòng)調(diào)用 BOOLCDialog:OnInitDialog() ,你如果需要在對(duì)話框顯 示前對(duì)其中的控件進(jìn)行初始化, 你需要重載這個(gè)函數(shù), 并在其中
11、填入相關(guān)的初始化代碼。 利 用ClassWizard 可以方便的產(chǎn)生一些默認(rèn)代碼,首先打開 ClassWizard,選擇相應(yīng)的對(duì)話框 類,在右邊的消息列表中選擇 WMNITDIALOG并雙擊,ClassWizard會(huì)自動(dòng)產(chǎn)生相關(guān)代碼,代 碼如下:BOOL CTestDlg: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)建無(wú)模式對(duì)話框 無(wú)模式對(duì)話框與有模式對(duì)話框不同的是在創(chuàng)建后其他窗口都
12、可以繼續(xù)接收用戶輸入,因此無(wú)模式對(duì)話框有些類似一個(gè)彈出窗口。創(chuàng)建無(wú)模式對(duì)話框需要調(diào)用BOOL CDialog:Create( UINT nIDTemplate, CWnd* pParentWnd = NULL )?之后還需要調(diào)用BOOL CDialog:ShowWi ndow( SW_SH OW?進(jìn)行顯示,否則無(wú)模式對(duì)話框?qū)⑹遣豢梢姷?。?關(guān)代碼如下:void CYourView:OnOpenDlg(void)/*假設(shè)IDD_TEST_DLG為已經(jīng)定義的對(duì)話框資源的ID號(hào)*/CTestDlg *dlg=new CTestDlg ?dlg>Create(IDD_TEST_DLG,NULL)
13、?dlg>ShowWindows(SW_SHOW? )/* 不要調(diào)用 delete dlg ?*/在上面的代碼中我們新生成了一個(gè)對(duì)話框?qū)ο螅?而且在退出函數(shù)時(shí)并沒有銷毀該對(duì)象。 因?yàn)?如果此時(shí)銷毀該對(duì)象 (對(duì)象被銷毀時(shí)窗口同時(shí)被銷毀) ,而此時(shí)對(duì)話框還在顯示就會(huì)出現(xiàn)錯(cuò) 誤。那么這就提出了一個(gè)問題:什么時(shí)候銷毀該對(duì)象。我時(shí)常使用的方法有兩個(gè):在對(duì)話框退出時(shí)銷毀自己:在對(duì)話框中重載 On OK與On Ca ncel在函數(shù)中調(diào)用父類的同名函 數(shù),然后調(diào)用DestroyWindow()強(qiáng)制銷毀窗口,在對(duì)話框中映射 WM_DESTROY息,在消 息處理函數(shù)中調(diào)用 delete this ?強(qiáng)行刪除
14、自身對(duì)象。相關(guān)代碼如下:void CTestDlg1:OnOK()CDialog:OnOK() ?DestroyWindow() ?void CTestDlg1:OnCancel()CDialog:OnCancel() ?DestroyWindow() ?void CTestDlg1:OnDestroy()CDialog:OnDestroy() ?AfxMessageBox("call delete this")?delete this ? 這種方法的要點(diǎn)是在窗口被銷毀的時(shí)候,刪除自身對(duì)象。所以你可以在任何時(shí)候調(diào)用DestroyWindow() 以達(dá)到徹底銷毀自身對(duì)象的作用
15、。( DestroyWindow() 的調(diào)用會(huì)引起 OnDestroy() 的調(diào)用)通過向父親窗口發(fā)送消息, 要求其他窗口對(duì)其進(jìn)行銷毀: 首先需要定義一個(gè)消息用于進(jìn)行通 知,然后在對(duì)話框中映射 WM_DESTRO消息,在消息處理函數(shù)中調(diào)用消息發(fā)送函數(shù)通知 其他窗口。在接收消息的窗口中利用ON_MESSAG映射處理消息的函數(shù),并在消息處理函數(shù)中刪除對(duì)話框?qū)ο?。相關(guān)代碼如下:/* 更改對(duì)話框的有關(guān)文件 */CTestDlg2:CTestDlg2(CWnd* pParent /*=NULL*/): CDialog(CTestDlg2:IDD, pParent)個(gè)臨時(shí)指針/*m_pParent 為一成
16、員變量,用于保存通知窗口的指針,所以該指針不能是 */ASSERT(pParent) ?m_pParent=pParent ?/AFX_DATA_INIT(CTestDlg2)/ NOTE: the ClassWizard will add member initialization here /AFX_DATA_INITvoid CTestDlg2:OnOK()CDialog:OnOK() ?DestroyWindow() ?void CTestDlg2:OnCancel()CDialog:OnCancel() ?DestroyWindow() ?void CTestDlg2:OnDestr
17、oy()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(WM_DELETE_DLG,OnDelDlgMsg)END_MESSAGE_MAP()/* 實(shí)現(xiàn)消息處理函數(shù) */LONG CMy53_s1View:OnDelDlgM
18、sg(WPARAM wP,LPARAM lP) delete (CTestDlg2*)wP ?return 0 ?/* 創(chuàng)建對(duì)話框 */void CMy53_s1View:OnTest2()CTestDlg2 *dlg=new CTestDlg2(this) ?dlg>Create(IDD_TEST_DLG_2) ?dlg>ShowWindow(SW_SHO?W)在這種方法中我們利用消息來(lái)進(jìn)行通知,在 Window 系統(tǒng)中利用消息進(jìn)行通知和傳遞數(shù)據(jù)的 用法是很多的。同樣無(wú)模式對(duì)話框的另一個(gè)作用還可以用來(lái)在用戶在對(duì)話框中的輸入改變時(shí)可以及時(shí)的反 映到其他窗口。 下面的代碼演示了在對(duì)話
19、框中輸入一段文字, 然后將其更新到視圖的顯示區(qū) 域中,這同樣也是利用了消息進(jìn)行通知和數(shù)據(jù)傳遞。/* 在對(duì)話框中取出數(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,(WPARAM)szO?ut)/* 在消息接收窗口中 */* 映射消息處理函數(shù) */ON_MESSAGE(WM_DLG_NOTIFY,OnDlgNotifyMsg)/* 在視圖中繪制出字符串
20、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:OnDlgNotifyMsg(WPARAM wP,LPARAM lP) m_szOu
21、t=(char*)wP ?Invalidate() ?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è) 例 子來(lái)講解如何在對(duì)話框中對(duì)子窗口消息進(jìn)行映射同時(shí)還講解如何對(duì)對(duì)話框中的子窗口進(jìn)行 初始化。ID 類型IDC_RADI0_TEST_1 圓形按鈕IDC_RADI0_TEST_2 圓形按鈕IDC_BUTTON_T
22、ES按鈕IDC_CHECK_TES1檢查按鈕IDC_TREE_TEST樹形控件IDC_LIST_CTRL List CtrlIDC_TAB_CTRL Tab CtrlIDC_LIST_TEST 列表框IDC_COMBO_TES組合框IDC_EDIT_TEST 輸入框首先我們產(chǎn)生編輯好一個(gè)對(duì)話框,如圖,在對(duì)話框中使用的控件和ID 號(hào)如下表:首先我們需要在對(duì)話框的 OnInitDialog() 函數(shù)中對(duì)各個(gè)控件進(jìn)行初始化,這里我們使用CWnd* GetDlgltem( int nID ) 來(lái)通過ID號(hào)得到子窗口指針。( 類似的函數(shù)還有 UINT GetDIgltemlnt( int nID, BO
23、OL* 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 edit box")?/ 初始化列
24、表框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("i
25、tem 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*)GetDlg
26、Item(IDC_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
27、("Node1",0,0)?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 接下來(lái)我們需要利用 Clas
28、sWizard 對(duì)控件所產(chǎn)生的消息進(jìn)行映射,打開 ClassWizard 對(duì)話 框,選中相關(guān)控件的 ID ,在右邊的列表中就會(huì)顯示出可用的消息。如我們對(duì)按鈕的消息進(jìn)行映射,在選中按鈕ID (IDC_BUTTON_TEST后,會(huì)看到兩個(gè)消息,如圖,一個(gè)是BN_CLICKED一個(gè)是BN_DOUBLECLICKEDZ擊BN_CLICKED后在彈出的對(duì)話框中輸入函數(shù)名,ClassWizard 會(huì)產(chǎn)生按鈕被按的消息映射。然后我們看看對(duì)TabCtrl的TCN_SELCHANG消息進(jìn)行映射,如圖,在 TabCtrl的當(dāng)前頁(yè)選 擇發(fā)生改變時(shí)這個(gè)消息會(huì)被發(fā)送,所以通過映射該消息可以在當(dāng)前頁(yè)改變時(shí)及時(shí)得到通知。
29、最后我們對(duì)輸入框的EN_CHANG消息進(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_MSG5.5 在對(duì)話框中進(jìn)行數(shù)據(jù)交換和數(shù)據(jù)檢查MFC 提供兩種方法在對(duì)話框中進(jìn)行數(shù)據(jù)交換和數(shù)據(jù)檢查(Dialog data exchange/Dialogdatavalidation ),數(shù)
30、據(jù)交換和數(shù)據(jù)檢查的思想是將某一變量和對(duì)話框中的一個(gè)子窗口進(jìn)行關(guān)聯(lián), 然后通過調(diào)用 BOOL UpdateData( BOOL bSaveAndValidate = TRUE )來(lái)指示 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,OnChang
31、eEditTest)/AFX_MSG_MAPEND_MESSAGE_MAP()/ 消息處理函數(shù)void CMy54_s1Dlg:OnButtonTest()AfxMessageBox("you pressed a button") ?void CMy54_s1Dlg:OnSelchangeTabTest(NMHDR* pNMHDR, LRESULT* pResult)TRACE("Tab Select changedn")?*pResult = 0 ?void CMy54_s1Dlg:OnChangeEditTest()TRACE("edit_
32、box text changedn") ? 對(duì)于其他的控件都可以采取類似的方法進(jìn)行消息映射, 下載例子。 此外如果你對(duì)各種控件可 以使用的消息不熟悉, 你可以通過使用對(duì)話框, 然后利用 ClassWizard 產(chǎn)生相關(guān)代碼的方法 來(lái)進(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é)中
33、講的一樣使用GetDlgltem(IDC_CONTROL_ID)來(lái)得到窗口指針;一種是內(nèi)容對(duì)象,比如說輸入框可以和一個(gè) CString 對(duì)象關(guān)聯(lián),也可以和一個(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ì)象的最長(zhǎng) / 最小長(zhǎng)度,當(dāng)輸入框和一個(gè) UINT 變量相關(guān)聯(lián)時(shí)你可以設(shè)置檢查 UINT 變量的最大 / 最小值。在BOOL UpdateData( BOOL bSaveAndValidate
34、= TRUE ) 被調(diào)用后,合法性檢查會(huì)自動(dòng)進(jìn)行, 如果無(wú)法通過檢查MFC會(huì)彈出消息框進(jìn)行提示,并返回 FALSE設(shè)置DDX/DDV在VC中非常簡(jiǎn)單,ClassWizard可以替你完成所有的工作,你只需要打開 ClassWizard 并選中 Member Variables 頁(yè),如圖,你可以看到所有可以進(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_CHE
35、CK_TEST BOOL m_fChec 檢查框是否被選中IDC_RADOI_TEST_1 int m_iSel 當(dāng)前選擇的圓形按鈕的索引IDC_COMBO_TEST CStri ng m_szCombo組合框中選中的文本或是輸入的文本IDC_EDIT_TESTCString m_szEdit 輸入框中輸入的文本,最大長(zhǎng)度為 5 IDC_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)用 Upda
36、teData(FALSE) ,即 會(huì)將變量中的數(shù)據(jù)放入窗口中。相關(guān)代碼如下:/ 頭文件中的變量定義, 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_s1
37、Dlg:IDD, pParent)/AFX_DATA_INIT(CMy55_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
38、_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, 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
39、()CDialog:OnInitDialog() ?/ TODO: Add extra initialization here/ 設(shè)置列表框中數(shù)據(jù)m_lbTest.AddString("String1")?m_lbTest.AddString("String2")?m_lbTest.AddString("String3")?m_lbTest.AddString("String4")?return TRUE ? / return TRUE unless you set the focus to a control/
40、對(duì)兩個(gè)按鈕消息處理/ 通過 UpdateData(TRUE) 得到窗口中數(shù)據(jù)void CMy55_s1Dlg:OnGet()if(UpdateData(TRUE)/ 數(shù)據(jù)合法性檢查通過,可以使用變量中存放的數(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)
41、 將數(shù)據(jù)放入窗口void CMy55_s1Dlg:OnPut()m_szEdit="onPut test" ?m_szCombo="onPut test" ?UpdateData(FALSE) ?在上面的例子中我們看到利用DDX/DDV和UpdateData(BOOL)調(diào)用我們可以很方便的存取 數(shù)據(jù),而且也可以同時(shí)進(jìn)行合法性檢查。下載例子代碼5.6 使用屬性對(duì)話框 屬性對(duì)話框不同于普通對(duì)話框的是它能同時(shí)提供多個(gè)選項(xiàng)頁(yè), 而每頁(yè)都可以由資源編輯器以 編輯對(duì)話框的方式進(jìn)行編輯, 這樣給界面開發(fā)帶來(lái)了方便。 同時(shí)使用上也遵守普通對(duì)話框的 規(guī)則,所以學(xué)習(xí)起來(lái)很方
42、便。屬性對(duì)話框由兩部分構(gòu)成:多個(gè)屬性頁(yè)( CPropertyPage )和 屬性對(duì)話框( CPropertySheet )。首先需要編輯屬性頁(yè), 在資源編輯器中選擇插入, 并且選擇屬性對(duì)話框后就可以插入一個(gè)屬 性頁(yè),如圖,或者選擇插入一個(gè)對(duì)話框, 然后將其屬性中的 Style 設(shè)置為 Child ,Border 設(shè) 置為Thin也可以,如圖。然后根據(jù)這個(gè)對(duì)話框資源生成一個(gè)新類,在選擇基類時(shí)選擇CPropertyPage , ClassWizard 會(huì)自動(dòng)生成相關(guān)的代碼。而對(duì)于 CPropertySheet 也需要生成新類,并且將所有需要加入的屬性頁(yè)對(duì)象都作為成員變 量。屬性對(duì)話框也分為有模式和
43、無(wú)模式兩種,有模式屬性對(duì)話框使用DoModal() 創(chuàng)建,無(wú)模式屬性對(duì)話框使用 Create() 創(chuàng)建。下面的代碼演示了如何創(chuàng)建屬性對(duì)話框并添加屬性頁(yè): / 修改 CPropertySheet 派生類的構(gòu)造函數(shù)為如下形式CSheet:CSheet():CPropertySheet("test sheet", NULL, 0) m_page1.Construct(IDD_PAGE_1) ? m_page2.Construct(IDD_PAGE_2) ?AddPage(&m_page1)?AddPage(&m_page2)?/ 創(chuàng)建有模式屬性對(duì)話框void CM
44、y56_s1Dlg:OnMod()CSheet sheet ?sheet.DoModal() ?/ 創(chuàng)建無(wú)模式屬性對(duì)話框void CMy56_s1Dlg:OnUnm()CSheet *sheet=new CSheet ?sheet>Create() ? 對(duì)于屬性對(duì)話框可以使用下面的一些成員函數(shù): CPropertyPage* CPropertySheet:GetActivePage( )得到當(dāng)前活動(dòng)頁(yè)的指針。BOOL CPropertySheet:SetActivePage( int nPage )用于設(shè)置當(dāng)前活動(dòng)頁(yè)。int CPropertySheet:GetPageCount() 用
45、于得到當(dāng)前頁(yè)總數(shù)。void CPropertySheet:RemovePage( int nPage ) 用于刪除一頁(yè)。 而對(duì)于屬性頁(yè)來(lái)將主要通過重載一些函數(shù)來(lái)達(dá)到控制的目的:void CPropertyPage:OnOK() 在屬性對(duì)話框上按下“確定”按鈕后被調(diào)用void CPropertyPage:OnCancel() 在屬性對(duì)話框上按下“取消”按鈕后被調(diào)用 void CPropertyPage:OnApply() 在屬性對(duì)話框上按下“應(yīng)用”按鈕后被調(diào)用 void CPropertyPage:SetModified( BOOL bChanged = TRUE ) 設(shè)置當(dāng)前頁(yè)面上的數(shù)據(jù)被修
46、改 標(biāo)記,這個(gè)調(diào)用可以使“應(yīng)用”按鈕為允許狀態(tài)。 此外利用屬性對(duì)話框你可以生成向?qū)?duì)話框, 向?qū)?duì)話框同樣擁有多個(gè)屬性頁(yè), 但同時(shí)只有 一頁(yè)被顯示,而且對(duì)話框上顯示的按鈕為“上一步”,“下一步” / “完成”,向?qū)?duì)話框 會(huì)按照你添加頁(yè)面的順序依次顯示所有的頁(yè)。在顯示屬性對(duì)話框前你需要調(diào)用 void CPropertySheet:SetWizardMode() 。使用向?qū)?duì)話框時(shí)需要對(duì)屬性頁(yè)的 BOOL CPropertyPage:OnSetActive( ) 進(jìn)行重載, 并在其中調(diào)用 void CPropertySheet:SetWizardButtons( DWORD dwFlags )
47、來(lái)設(shè)置向?qū)?duì)話框上顯示的按鈕。 dwFlags 的取值可為以下值的“或”操作:PSWIZB_BAC區(qū)示“上一步”按鈕 PSWIZB_NEX顯示“下一步”按鈕 PSWIZB_FINISH 顯示“完成”按鈕 PSWIZB_DISABLEDFINISH顯示禁止的“完成”按鈕void CPropertySheet:SetWizardButtons( DWORD dwFlags ) 也可以在其他地方調(diào)用,比如 說在顯示最后一頁(yè)時(shí)先顯示禁止的 “完成” 按鈕, 在完成某些操作后再顯示允許的 “完成” 按鈕。 在使用向?qū)?duì)話框時(shí)可以通過重載一些函數(shù)來(lái)達(dá)到控制的目的:void CPropertyPage:On
48、WizardBack() 按下了“上一步”按鈕。返回 0 表示有系統(tǒng)決定需 要顯示的頁(yè)面, 1 表示禁止頁(yè)面轉(zhuǎn)換,如果希望顯示一個(gè)特定的頁(yè)面需要返回該頁(yè)面的ID 號(hào)。void CPropertyPage:OnOnWizardNext()按下了“ 下一步” 按鈕。返回值含義與 voidCPropertyPage:OnWizardBack() 相同。void CPropertyPage:OnWizardFinish()按下了“完成”按鈕。返回 FALSE 表示不允許繼續(xù),否則返回TRUE向?qū)?duì)話框?qū)⒈唤Y(jié)束。在向?qū)?duì)話框的DoModal()返回值為ID_WIZFINISH或IDCANCEL下面的代碼
49、演示了如 何創(chuàng)建并使用向?qū)?duì)話框:/ 創(chuàng)建有模式向?qū)?duì)話框 void CMy56_s1Dlg:OnWiz()CSheet sheet ? sheet.SetWizardMode() ?int iRet=sheet.DoModal()?/ 返回 ID_WIZFINISH 或 IDCANCEL/ 重載 BOOL CPropertyPage:OnSetActive( ) 來(lái)控制顯示的按鈕BOOL CPage1:OnSetActive()(CPropertySheet*)GetParent()> SetWizardButtons(PSWIZB_BACK|PSWIZB_NEXT)? return
50、CPropertyPage:OnSetActive() ?BOOL CPage2:OnSetActive()(CPropertySheet*)GetParent()>SetWizardButtons(PSWIZB_BACK|PSWIZB_FINISH) ? return CPropertyPage:OnSetActive() ? 下載本節(jié)例子。5.7 使用通用對(duì)話框在Win dows系統(tǒng)中提供了一些通用對(duì)話框如:文件選擇對(duì)話框如圖,顏色選擇對(duì)話框如圖,字體選擇對(duì)話框如圖。在 MFC中使用CFileDialog ,CColorDialog ,CFontDialog 來(lái)表示。般來(lái)講你不需要派
51、生新的類, 因?yàn)榛愐呀?jīng)提供了常用的功能。 而且在創(chuàng)建并等待對(duì)話框結(jié) 束后你可以通過成員函數(shù)得到用戶在對(duì)話框中的選擇。CFileDialog 文件選擇對(duì)話框的使用: 首先構(gòu)造一個(gè)對(duì)象并提供相應(yīng)的參數(shù), 構(gòu)造函數(shù)原型 如下:CFileDialog:CFileDialog( BOOLbOpenFileDialog, LPCTSTRlpszDefExt = NULL, LPCTSTR lpszFileName = NULL, DWORD dwFlags = OFN_HIDEREADONLY |OFN_OVERWRITEPROMPT, LPCTSTR lpszFilter = NULL, CWnd*
52、pParentWnd = NULL )?參數(shù)意義如下:bOpe nF ileDialog為TRUE則顯示打開對(duì)話框,為 FALSE則顯示保存對(duì)話文件對(duì)話框。lpszDefExt 指定默認(rèn)的文件擴(kuò)展名。lpszFileName 指定默認(rèn)的文件名。dwFlags 指明一些特定風(fēng)格。lpszFilter 是最重要的一個(gè)參數(shù),它指明可供選擇的文件類型和相應(yīng)的擴(kuò)展名。參數(shù)格式種文件類型間用 | 分隔,末尾用 | pParentWnd 為父窗口指針。 創(chuàng)建文件對(duì)話框可以使用CString CFileDialog:GetPathName( ) c:testtest1.txtCString CFileDial
53、og:GetFileName( )CString CFileDialog:GetExtName( )CString CFileDialog:GetFileTitle ( ) test1POSITIONCFileDialog:GetStartPosition( 位置。CString CFileDialog:GetNextPathName(DoModal() ,在返回后可以利用下面的函數(shù)得到用戶選擇:得到完整的文件名,如:*.xls)|*.xlc(*.*)|*.*|"? *.xls|All Files?文件類型說明和擴(kuò)展名間用 | 分隔,同種類型文件的擴(kuò)展名間可以用 ? 分割,"
54、;Chart Files (*.xlc)|*.xlc|Worksheet Files (*.xls)|*.xls|Data Files (*.xlc每指明。包括目錄名和擴(kuò)展名如:得到完整的文件名,包括擴(kuò)展名如: test1.txt 得到完整的文件擴(kuò)展名,如: txt 得到完整的文件名,不包括目錄名和擴(kuò)展名如:) 對(duì)于選擇了多個(gè)文件的情況得到第一個(gè)文件POSITION& pos ) 對(duì)于選擇了多個(gè)文件的情況得 下一個(gè)文件位置, 并同時(shí)返回當(dāng)前文件名。但必須已經(jīng)調(diào)用過 POSITION CFileDialog:GetStartPosition( ) 來(lái)得到最初的 POSITION 變量。C
55、ColorDialog 顏色選擇對(duì)話框的使用:首先通過 CColorDialog:CColorDialog( COLORREF clrInit = 0, DWORDdwFlags = 0, CWnd*pParentWnd = NULL ) 構(gòu)造一個(gè)對(duì)象,其中 clrInit 為初始顏色。通過調(diào)用 DoModal() 創(chuàng)建對(duì)話框, 在返回后調(diào)用 COLORREF CColorDialog:GetColor( ) 得到用戶選擇的顏色值。CFontDialog 字體選擇對(duì)話框的使用: 首先構(gòu)造一個(gè)對(duì)象并提供相應(yīng)的參數(shù), 構(gòu)造函數(shù)原型 如下:CFontDialog:CFontDialog( LPLOG
56、FONT lplfInitial = NULL, DWORD dwFlags =CF_EFFECTS | CF_SCREENFONTS, CDC* pdcPrinter = NULL, CWnd* pParentWnd = NULL)?構(gòu)造一個(gè)對(duì)象,其中參數(shù)Iplflnitial指向一個(gè)LOGFONG吉構(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)
57、用以下函數(shù)來(lái)得到用戶選 擇:void CFontDialog:GetCurrentFont( LPLOGFONT lplf )?用來(lái)獲得所選字體的屬性。該函數(shù)有一個(gè)參數(shù),該參數(shù)是指向LOGFONT吉構(gòu)的指針,函數(shù)將所選字體的各種屬性寫入這個(gè)LOGFO NT吉構(gòu)中。CString CFontDialog:GetFaceName( ) 得到所選字體名字。int CFontDialog:GetSize( ) 得到所選字體的尺寸(以 10 個(gè)象素為單位)。COLORREF CFontDialog:GetColor( ) 得到所選字體的顏色。BOOL CFontDialog:lsStrikeOut( )BOOL CFontDialog:lsUnde
溫馨提示
- 1. 本站所有資源如無(wú)特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(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ì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 打印報(bào)表課程設(shè)計(jì)
- 吉林省四平市第三高級(jí)中學(xué)2024-2025學(xué)年高一上學(xué)期第二次質(zhì)量檢測(cè)歷史試題
- 甜品糖水教學(xué)課程設(shè)計(jì)
- 茶藝插畫課程設(shè)計(jì)案例
- 物理有沒有進(jìn)展課程設(shè)計(jì)
- 2024年演員聘用合同
- 電子商務(wù)行業(yè)客服工作回顧
- 外科部門手術(shù)治療工作年度總結(jié)
- 2024年社區(qū)工作者測(cè)試題庫(kù)
- 生物教育的熱點(diǎn)與趨勢(shì)研究計(jì)劃
- 公交車站臺(tái)服務(wù)規(guī)范與安全意識(shí)
- 2024電商消費(fèi)趨勢(shì)年度報(bào)告-flywheel飛未-202412
- 慢阻肺護(hù)理個(gè)案病例范文
- 《農(nóng)機(jī)安全》課件
- 公共廁所清潔保養(yǎng)協(xié)議
- 浙江省溫州市2023-2024學(xué)年六年級(jí)上學(xué)期期末科學(xué)試卷(含答案)3
- 深圳大學(xué)《激光原理與技術(shù)》2023-2024學(xué)年第一學(xué)期期末試卷
- 西安市高新第一中學(xué)八年級(jí)上冊(cè)地理期末試卷(含答案)
- 中國(guó)普通食物營(yíng)養(yǎng)成分表(修正版)
- 駕駛證學(xué)法減分(學(xué)法免分)試題和答案(50題完整版)1650
- 期末測(cè)試卷(試題)-2024-2025學(xué)年人教PEP版(2024)英語(yǔ)三年級(jí)上冊(cè)
評(píng)論
0/150
提交評(píng)論