MFC教程对话框的编辑

上传人:仙*** 文档编号:72352767 上传时间:2022-04-09 格式:DOC 页数:16 大小:120KB
收藏 版权申诉 举报 下载
MFC教程对话框的编辑_第1页
第1页 / 共16页
MFC教程对话框的编辑_第2页
第2页 / 共16页
MFC教程对话框的编辑_第3页
第3页 / 共16页
资源描述:

《MFC教程对话框的编辑》由会员分享,可在线阅读,更多相关《MFC教程对话框的编辑(16页珍藏版)》请在装配图网上搜索。

1、第五章对话框5.1 使用资源编辑器编辑对话框在Win dows开发中弹出对话框是一种常用的输入/输出手段,同时编辑好的对话框可以保存在资源文件中。Visual C+提供了对话框编辑工具,利用编辑工具可以方便的添加各种控件 到对话框中,而且利用 ClassWizard 可以方便的生成新的对话框类和映射消息。首先资源列表中按下右键,可以在弹出菜单中选择“插入对话框”,如图1。然后再打开该对话框进行编辑,你会在屏幕上看到一个控件板,如图2。你可以将所需要添加的控件拖到对话框上,或是先选中后再在对话框上用鼠标画出所占的区域。接下来我们在对话框上产生一个输入框,和一个用于显示图标的图片框。 之后我们使用

2、鼠标右键单击产生的控件并选择其属性,如图3。我们可以在属性对话框中编辑控件的属性同时也需要指定控件ID,如图4,如果在选择对话框本身的属性那么你可以选择对话框的一些属 性,包括字体,外观,是否有系统菜单等等。最后我们编辑图片控件的属性,如图5,我们设置控件的属性为显示图标并指明一个图标 ID。接下来我们添加一些其他的控件,最后的效果如图6。按下 CtrlT可以测试该对话框。此外在对话框中还有一个有用的特性, 就是可以利用 Tab 键让输入焦点在各个控件间移动, 要达 到这一点首先需要为控件设置在Tab键按下时可以接受焦点移动的属性Tab Stop,如果某一个控件不打算利用这一特性,你需要清除这

3、一属性。然后从菜单“Layout ”选择Tab Order来确定焦点移动顺序,如图 7。使用鼠标依此点击控件就可以重新规定焦点移动次序。最后 按下 CtrlT进行测试。最后我们需要为对话框产生新的类, ClassWizard 可以替我们完成大部分的工作, 我们只需 要填写几个参数就可以了。 在编辑好的对话框上双击, 然后系统回询问是否添加新的对话框, 选择是并在接下来的对话框中输入类名就可以了。 ClassWizard 会为你产生所需要的头文件 和CPP文件。然后在需要使用的地方包含相应的头文件,对于有模式对话框使用DoModal()产生,对于无模式对话框使用 Create() 产生。相关代码

4、如下;void CMy51_s1View:OnCreateDlg()/ 产生无模式对话框CTestDlg *dlg=new CTestDlg ?dlg Create(IDD_TEST_DLG)?dlgShowWindow(SW_SHO?W)void CMy51_s1View:OnDoModal()/ 产生有模式对话框CTestDlg dlg ?int iRet=dlg.DoModal() ?TRACE(dlg return %dn,iRet) ?下载例子。 如果你在调试这个程序时你会发现程序在退出后会有内存泄漏,这是因为我没有释放无模式对话框所使用的内存, 这一问题会在以后的章节 5.3 创建

5、无模式对话框中专门讲 述。关于在使用对话框时 Enter 键和 Escape 键的处理:在使用对话框是你会发现当你按下 Enter 键或 Escape 键都会退出对话框,这是因为 Enter 键会引起 CDialog:OnOK() 的调用,而 Escape键会引起 CDialog:OnCancel() 的调用。而这两个调用都会引起对话框的退出。在MFC 中这两个成员函数都是虚拟函数, 所以我们需要进行重载, 如果我们不希望退出对话框那么我们 可以在函数中什么都不做, 如果需要进行检查则可以添加检查代码, 然后调用父类的 OnOK() 或 OnCancel() 。相关代码如下;void CTes

6、tDlg:OnOK()AfxMessageBox( 你选择确定 ) ?CDialog:OnOK() ?void CTestDlg:OnCancel()AfxMessageBox( 你选择取消 ) ?CDialog:OnCancel() ?5.2 创建有模式对话框 使用有模式对话框时在对话框弹出后调用函数不会立即返回, 而是等到对话框销毁后才会返 回(请注意在对话框弹出后其他窗口的消息依然会被传递) 。所以在使用对话框时其他窗口 都不能接收用户输入。 创建有模式对话框的方法是调用 CDialog:DoModal() 。下面的代码演 示了这种用法:CYourView:OnOpenDlg()CYou

7、rDlg dlg ?int iRet=dlg.DoModal() ?CDialog:DoModal() 的返回值为IDOK, IDCANCEL表明操作者在对话框上选择“确认” 或是“取消”。由于在对话框销毁前 DoModal 不会返回,所以可以使用局部变量来引用对 象。在退出函数体后对象同时也会被销毁。 而对于无模式对话框则不能这样使用, 下节 5.3 创 建无模式对话框中会详细讲解。你需要根据 DoModal() 的返回值来决定你下一步的动作,而得到返回值也是使用有模式对话 框的一个很大原因。使用有模式对话框需要注意一些问题, 比如说不要在一些反复出现的事件处理过程中生成有 模式对话框, 比

8、如说在定时器中产生有模式对话框, 因为在上一个对话框还未退出时, 定时 器消息又会引起下一个对话框的弹出。同样的在你的对话框类中为了向调用者返回不同的值可以调用 CDialog:OnOK() 或是 CDialog:OnCancel()以返回IDOK或IDCANCEL如果你希望返回其他的值,你需要调用CDialog:EndDialog( int nResult )?其中 nResult 会作为 DoModal() 调用的返回值。下面的代码演示了如何使用自己的函数来退出对话框:下载例子void CMy52_s1View:OnLButtonDown(UINT nFlags, CPoint point

9、)/ 创建对话框并得到返回值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()/ 什么也不做/ 在对话框中对三个按钮消息进行映射void CTestDlg:OnExit1()CDialog:OnOK() ?void C

10、TestDlg:OnExit2()CDialog:OnCancel() ?void CTestDlg:OnExit3()CDialog:EndDialog(0XFF) ?由于重载了 On OK和On Ca ncel所以在对话框中按下 En ter键或Escape键时都不会退出,只 有按下三个按钮中的其中一个才会返回。此外在对话框被生成是会自动调用 BOOLCDialog:OnInitDialog() ,你如果需要在对话框显 示前对其中的控件进行初始化, 你需要重载这个函数, 并在其中填入相关的初始化代码。 利 用ClassWizard 可以方便的产生一些默认代码,首先打开 ClassWizar

11、d,选择相应的对话框 类,在右边的消息列表中选择 WMNITDIALOG并双击,ClassWizard会自动产生相关代码,代 码如下:BOOL CTestDlg:OnInitDialog()/* 先调用父类的同名函数 */CDialog:OnInitDialog() ?/* 填写你的初始化代码 */return TRUE ? 有关对对话框中控件进行初始化会在 5.4 在对话框中进行消息映射中进行更详细的讲解5.3 创建无模式对话框 无模式对话框与有模式对话框不同的是在创建后其他窗口都可以继续接收用户输入,因此无模式对话框有些类似一个弹出窗口。创建无模式对话框需要调用BOOL CDialog:C

12、reate( UINT nIDTemplate, CWnd* pParentWnd = NULL )?之后还需要调用BOOL CDialog:ShowWi ndow( SW_SH OW?进行显示,否则无模式对话框将是不可见的。相 关代码如下:void CYourView:OnOpenDlg(void)/*假设IDD_TEST_DLG为已经定义的对话框资源的ID号*/CTestDlg *dlg=new CTestDlg ?dlgCreate(IDD_TEST_DLG,NULL)?dlgShowWindows(SW_SHOW? )/* 不要调用 delete dlg ?*/在上面的代码中我们新生成

13、了一个对话框对象, 而且在退出函数时并没有销毁该对象。 因为 如果此时销毁该对象 (对象被销毁时窗口同时被销毁) ,而此时对话框还在显示就会出现错 误。那么这就提出了一个问题:什么时候销毁该对象。我时常使用的方法有两个:在对话框退出时销毁自己:在对话框中重载 On OK与On Ca ncel在函数中调用父类的同名函 数,然后调用DestroyWindow()强制销毁窗口,在对话框中映射 WM_DESTROY息,在消 息处理函数中调用 delete this ?强行删除自身对象。相关代码如下:void CTestDlg1:OnOK()CDialog:OnOK() ?DestroyWindow()

14、 ?void CTestDlg1:OnCancel()CDialog:OnCancel() ?DestroyWindow() ?void CTestDlg1:OnDestroy()CDialog:OnDestroy() ?AfxMessageBox(call delete this)?delete this ? 这种方法的要点是在窗口被销毁的时候,删除自身对象。所以你可以在任何时候调用DestroyWindow() 以达到彻底销毁自身对象的作用。( DestroyWindow() 的调用会引起 OnDestroy() 的调用)通过向父亲窗口发送消息, 要求其他窗口对其进行销毁: 首先需要定义一

15、个消息用于进行通 知,然后在对话框中映射 WM_DESTRO消息,在消息处理函数中调用消息发送函数通知 其他窗口。在接收消息的窗口中利用ON_MESSAG映射处理消息的函数,并在消息处理函数中删除对话框对象。相关代码如下:/* 更改对话框的有关文件 */CTestDlg2:CTestDlg2(CWnd* pParent /*=NULL*/): CDialog(CTestDlg2:IDD, pParent)个临时指针/*m_pParent 为一成员变量,用于保存通知窗口的指针,所以该指针不能是 */ASSERT(pParent) ?m_pParent=pParent ?/AFX_DATA_INI

16、T(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:OnDestroy()CDialog:OnDestroy() ?/* 向其他窗口发送消息,将自身指针作为一个参数发送 */ m_pParentPostMessage(

17、WM_DELETE_DLG,(WPARAM)this?)/* 在消息接收窗口中添加消息映射 */* 在头文件中添加函数定义 */afx_msg LONG OnDelDlgMsg(WPARAM wP,LPARAM lP?)/* 添加消息映射代码 */ ON_MESSAGE(WM_DELETE_DLG,OnDelDlgMsg)END_MESSAGE_MAP()/* 实现消息处理函数 */LONG CMy53_s1View:OnDelDlgMsg(WPARAM wP,LPARAM lP) delete (CTestDlg2*)wP ?return 0 ?/* 创建对话框 */void CMy53_s

18、1View:OnTest2()CTestDlg2 *dlg=new CTestDlg2(this) ?dlgCreate(IDD_TEST_DLG_2) ?dlgShowWindow(SW_SHO?W)在这种方法中我们利用消息来进行通知,在 Window 系统中利用消息进行通知和传递数据的 用法是很多的。同样无模式对话框的另一个作用还可以用来在用户在对话框中的输入改变时可以及时的反 映到其他窗口。 下面的代码演示了在对话框中输入一段文字, 然后将其更新到视图的显示区 域中,这同样也是利用了消息进行通知和数据传递。/* 在对话框中取出数据,并向其他窗口发送消息和数据,将数据指针作为一个参数发送

19、*/ void CTestDlg2:OnCommBtn()char szOut30 ?GetDlgItemText(IDC_OUT,szOut,30) ?m_pParentSendMessage(WM_DLG_NOTIFY,(WPARAM)szO?ut)/* 在消息接收窗口中 */* 映射消息处理函数 */ON_MESSAGE(WM_DLG_NOTIFY,OnDlgNotifyMsg)/* 在视图中绘制出字符串 m_szOut*/ void CMy53_s1View:OnDraw(CDC* pDC)CMy53_s1Doc* pDoc = GetDocument() ?ASSERT_VALID(

20、pDoc)?/ TODO: add draw code for native data herepDCTextOut(0,0,Display String) ?pDCTextOut(0,20,m_szOut) ?/* 处理通知消息,保存信息并更新显示 */LONG CMy53_s1View:OnDlgNotifyMsg(WPARAM wP,LPARAM lP) m_szOut=(char*)wP ?Invalidate() ?return 0 ? 此外这种用法利用消息传递数据的方法对有模式对话框和其他的窗口间通信也一样有效。 下 载本节例子5.4 在对话框中进行消息映射 利用对话框的一个好处是

21、可以利用 ClassWizard 对对话框中各个控件产生的消息进行映射, ClassWizrd 可以列出各种控件可以使用的消息,并能自动产生代码。在本节中我们以一个 例 子来讲解如何在对话框中对子窗口消息进行映射同时还讲解如何对对话框中的子窗口进行 初始化。ID 类型IDC_RADI0_TEST_1 圆形按钮IDC_RADI0_TEST_2 圆形按钮IDC_BUTTON_TES按钮IDC_CHECK_TES1检查按钮IDC_TREE_TEST树形控件IDC_LIST_CTRL List CtrlIDC_TAB_CTRL Tab CtrlIDC_LIST_TEST 列表框IDC_COMBO_TE

22、S组合框IDC_EDIT_TEST 输入框首先我们产生编辑好一个对话框,如图,在对话框中使用的控件和ID 号如下表:首先我们需要在对话框的 OnInitDialog() 函数中对各个控件进行初始化,这里我们使用CWnd* GetDlgltem( int nID ) 来通过ID号得到子窗口指针。( 类似的函数还有 UINT GetDIgltemlnt( int nID, BOOL* lpTrans = NULL, BOOL bSigned = TRUE )通过 ID 号得到子窗口中输入的数字,int GetDlgItemText( int nID, CString& rString )通过 ID

23、 号得到子窗口中输入的文字)。代码如下:BOOL CMy54_s1Dlg:OnInitDialog()CDialog:OnInitDialog() ?/* 添加初始化代码 */ 初始化输入框(CEdit*)GetDlgItem(IDC_EDIT_TEST) SetWindowText(thisis a edit box)?/ 初始化列表框CListBox* pListB=(CListBox*)GetDlgItem(IDC_LIST_TEST)?pListBAddString(item 1)?pListBAddString(item 2)?pListBAddString(item 3)?/ 初始

24、化组合框CComboBox* pCB=(CComboBox*)GetDlgItem(IDC_COMBO_TEST?) pCBAddString(item 1)?pCBAddString(item 2)?pCBAddString(item 3)?/ 初始化 Tab CtrlCTabCtrl* pTab=(CTabCtrl*)GetDlgItem(IDC_TAB_TEST) ?pTab InsertItem(0,TabPage1) ?pTab InsertItem(1,TabPage2) ?pTab InsertItem(2,TabPage3) ?/ 初始化 ListCtrlCListCtrl*

25、pList=(CListCtrl*)GetDlgItem(IDC_LIST_CTRL) pListInsertColumn(0,Column 1,LVCFMT_LEFT,100) ? pListInsertItem(0,Item1) ?pListInsertItem(1,Item2) ?pListInsertItem(2,Item3) ?/ 初始化 TreeCtrlCTreeCtrl* pTree=(CTreeCtrl*)GetDlgItem(IDC_TREE_TEST) ? pTreeInsertItem(Node1,0,0)?HTREEITEMhNode=pTreeInsertItem(N

26、ode2,0,0)?pTreeInsertItem(Node21, 0,0,hNode) ?pTreeInsertItem(Node22, 0,0,hNode) ?pTreeExpand(hNode,TVE_EXPAND?)return TRUE ? / return TRUE unless you set the focus to a control 接下来我们需要利用 ClassWizard 对控件所产生的消息进行映射,打开 ClassWizard 对话 框,选中相关控件的 ID ,在右边的列表中就会显示出可用的消息。如我们对按钮的消息进行映射,在选中按钮ID (IDC_BUTTON_TE

27、ST后,会看到两个消息,如图,一个是BN_CLICKED一个是BN_DOUBLECLICKEDZ击BN_CLICKED后在弹出的对话框中输入函数名,ClassWizard 会产生按钮被按的消息映射。然后我们看看对TabCtrl的TCN_SELCHANG消息进行映射,如图,在 TabCtrl的当前页选 择发生改变时这个消息会被发送,所以通过映射该消息可以在当前页改变时及时得到通知。 最后我们对输入框的EN_CHANG消息进行映射,如图,在输入框中的文本改变后该消息 会被发送。相关的代码如下:/ 头文件中相关的消息处理函数定义afx_msg void OnButtonTest() afx_msg

28、void OnSelchangeTabTest(NMHDR* pNMHDR, LRESULT* pResult) ? afx_msg void OnChangeEditTest() ?/AFX_MSG5.5 在对话框中进行数据交换和数据检查MFC 提供两种方法在对话框中进行数据交换和数据检查(Dialog data exchange/Dialogdatavalidation ),数据交换和数据检查的思想是将某一变量和对话框中的一个子窗口进行关联, 然后通过调用 BOOL UpdateData( BOOL bSaveAndValidate = TRUE )来指示 MFC将变量中数据放入子窗口还是

29、将子窗口中数据取到变量中并进行合法性检查。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()/ 消息处理函数void CMy54_s1Dlg:OnButtonTest()AfxMessageBox(you pressed a bu

30、tton) ?void CMy54_s1Dlg:OnSelchangeTabTest(NMHDR* pNMHDR, LRESULT* pResult)TRACE(Tab Select changedn)?*pResult = 0 ?void CMy54_s1Dlg:OnChangeEditTest()TRACE(edit_box text changedn) ? 对于其他的控件都可以采取类似的方法进行消息映射, 下载例子。 此外如果你对各种控件可 以使用的消息不熟悉, 你可以通过使用对话框, 然后利用 ClassWizard 产生相关代码的方法 来进行学习,你也可以将 ClassWizard

31、产生的代码直接拷贝到其他需要的地方(不瞒你说, 我最开始就是这样学的 :D 这也算一个小窍门)。在进行数据交换时一个子窗口可以和两种类型的变量相关联, 一种是控件 ( Control )对象, 比如说按钮子窗口可以和一个 CButton 对象相关联, 这种情况下你可以通过该对象直接控制 子窗口,而不需要象上节中讲的一样使用GetDlgltem(IDC_CONTROL_ID)来得到窗口指针;一种是内容对象,比如说输入框可以和一个 CString 对象关联,也可以和一个 UINT 类型变 量关联,这种情况下你可以直接设置 /获取窗口中的输入内容。而数据检查是在一个子窗口和一个内容对象相关联时在存取

32、内容时对内容进行合法性检查, 比如说当一个输入框和一个 CString 对象关联时,你可以设置检查 CString 的对象的最长 / 最小长度,当输入框和一个 UINT 变量相关联时你可以设置检查 UINT 变量的最大 / 最小值。在BOOL UpdateData( BOOL bSaveAndValidate = TRUE ) 被调用后,合法性检查会自动进行, 如果无法通过检查MFC会弹出消息框进行提示,并返回 FALSE设置DDX/DDV在VC中非常简单,ClassWizard可以替你完成所有的工作,你只需要打开 ClassWizard 并选中 Member Variables 页,如图,你

33、可以看到所有可以进行关联的子窗口 ID列表,双击一个 ID 会弹出一个添加变量的对话框,如图,填写相关的信息后按下确定按钮 就可以了。然后选中你刚才添加的变量在底部的输入框中输入检查条件,如图。 下面我们看一个例子,对话框上的子窗口如图设置,各子窗口的ID 和关联的变量如下表:ID 关联的变量作用IDC_CHECK_TEST BOOL m_fChec 检查框是否被选中IDC_RADOI_TEST_1 int m_iSel 当前选择的圆形按钮的索引IDC_COMBO_TEST CStri ng m_szCombo组合框中选中的文本或是输入的文本IDC_EDIT_TESTCString m_szE

34、dit 输入框中输入的文本,最大长度为 5 IDC_LIST_TESTCListBox m_lbTest 列表框对象这时候 ClassWizard 会自动生成变量定义和相关代码, 在对话框的构造函数中可以对变量的 初始值进行设置,此外在 BOOL CDialog:OnInitDialog() 中会调用 UpdateData(FALSE) ,即 会将变量中的数据放入窗口中。相关代码如下:/ 头文件中的变量定义, ClassWizard 自动产生/ Dialog Data/AFX_DATA(CMy55_s1Dlg)enum IDD = IDD_MY55_S1_DIALOG ?CListBox m_

35、lbTest ?int m_iSel ?CString m_szEdit ?CString m_szCombo ?BOOL m_fCheck?/AFX_DATA/ 构造函数中赋初值CMy55_s1Dlg:CMy55_s1Dlg(CWnd* pParent /*=NULL*/): CDialog(CMy55_s1Dlg:IDD, pParent)/AFX_DATA_INIT(CMy55_s1Dlg)m_iSel = 1 ?m_szEdit = _T()?m_szCombo = _T() ?m_fCheck = FALSE?/AFX_DATA_INIT/ClassWizard 产生的关联和检查代码

36、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, 5) ?DDX_CBString(pDX, IDC_COMBO_TEST, m

37、_szCombo?) DDX_Check(pDX, IDC_CHECK_TEST, m_fCheck)? /AFX_DATA_MAP/ 在 OnInitDialog 中利用已经关联过的变量 m_lbTestBOOL CMy55_s1Dlg:OnInitDialog()CDialog:OnInitDialog() ?/ TODO: Add extra initialization here/ 设置列表框中数据m_lbTest.AddString(String1)?m_lbTest.AddString(String2)?m_lbTest.AddString(String3)?m_lbTest.Ad

38、dString(String4)?return TRUE ? / return TRUE unless you set the focus to a control/ 对两个按钮消息处理/ 通过 UpdateData(TRUE) 得到窗口中数据void CMy55_s1Dlg:OnGet()if(UpdateData(TRUE)/ 数据合法性检查通过,可以使用变量中存放的数据CString szOut ?szOut.Format(radio =%d ncheck is %dnedit input is %sncomboBox input is %sn, m_iSel,m_fCheck,m_sz

39、Edit,m_szCombo) ?AfxMessageBox(szOut) ?/else 未通过检查/ 通过 UpdateData(FALSE) 将数据放入窗口void CMy55_s1Dlg:OnPut()m_szEdit=onPut test ?m_szCombo=onPut test ?UpdateData(FALSE) ?在上面的例子中我们看到利用DDX/DDV和UpdateData(BOOL)调用我们可以很方便的存取 数据,而且也可以同时进行合法性检查。下载例子代码5.6 使用属性对话框 属性对话框不同于普通对话框的是它能同时提供多个选项页, 而每页都可以由资源编辑器以 编辑对话框的

40、方式进行编辑, 这样给界面开发带来了方便。 同时使用上也遵守普通对话框的 规则,所以学习起来很方便。属性对话框由两部分构成:多个属性页( CPropertyPage )和 属性对话框( CPropertySheet )。首先需要编辑属性页, 在资源编辑器中选择插入, 并且选择属性对话框后就可以插入一个属 性页,如图,或者选择插入一个对话框, 然后将其属性中的 Style 设置为 Child ,Border 设 置为Thin也可以,如图。然后根据这个对话框资源生成一个新类,在选择基类时选择CPropertyPage , ClassWizard 会自动生成相关的代码。而对于 CPropertySh

41、eet 也需要生成新类,并且将所有需要加入的属性页对象都作为成员变 量。属性对话框也分为有模式和无模式两种,有模式属性对话框使用DoModal() 创建,无模式属性对话框使用 Create() 创建。下面的代码演示了如何创建属性对话框并添加属性页: / 修改 CPropertySheet 派生类的构造函数为如下形式CSheet:CSheet():CPropertySheet(test sheet, NULL, 0) m_page1.Construct(IDD_PAGE_1) ? m_page2.Construct(IDD_PAGE_2) ?AddPage(&m_page1)?AddPage(&

42、m_page2)?/ 创建有模式属性对话框void CMy56_s1Dlg:OnMod()CSheet sheet ?sheet.DoModal() ?/ 创建无模式属性对话框void CMy56_s1Dlg:OnUnm()CSheet *sheet=new CSheet ?sheetCreate() ? 对于属性对话框可以使用下面的一些成员函数: CPropertyPage* CPropertySheet:GetActivePage( )得到当前活动页的指针。BOOL CPropertySheet:SetActivePage( int nPage )用于设置当前活动页。int CProper

43、tySheet:GetPageCount() 用于得到当前页总数。void CPropertySheet:RemovePage( int nPage ) 用于删除一页。 而对于属性页来将主要通过重载一些函数来达到控制的目的:void CPropertyPage:OnOK() 在属性对话框上按下“确定”按钮后被调用void CPropertyPage:OnCancel() 在属性对话框上按下“取消”按钮后被调用 void CPropertyPage:OnApply() 在属性对话框上按下“应用”按钮后被调用 void CPropertyPage:SetModified( BOOL bChange

44、d = TRUE ) 设置当前页面上的数据被修 改 标记,这个调用可以使“应用”按钮为允许状态。 此外利用属性对话框你可以生成向导对话框, 向导对话框同样拥有多个属性页, 但同时只有 一页被显示,而且对话框上显示的按钮为“上一步”,“下一步” / “完成”,向导对话框 会按照你添加页面的顺序依次显示所有的页。在显示属性对话框前你需要调用 void CPropertySheet:SetWizardMode() 。使用向导对话框时需要对属性页的 BOOL CPropertyPage:OnSetActive( ) 进行重载, 并在其中调用 void CPropertySheet:SetWizardB

45、uttons( DWORD dwFlags ) 来设置向导对话框上显示的按钮。 dwFlags 的取值可为以下值的“或”操作:PSWIZB_BAC區示“上一步”按钮 PSWIZB_NEX显示“下一步”按钮 PSWIZB_FINISH 显示“完成”按钮 PSWIZB_DISABLEDFINISH显示禁止的“完成”按钮void CPropertySheet:SetWizardButtons( DWORD dwFlags ) 也可以在其他地方调用,比如 说在显示最后一页时先显示禁止的 “完成” 按钮, 在完成某些操作后再显示允许的 “完成” 按钮。 在使用向导对话框时可以通过重载一些函数来达到控制的

46、目的:void CPropertyPage:OnWizardBack() 按下了“上一步”按钮。返回 0 表示有系统决定需 要显示的页面, 1 表示禁止页面转换,如果希望显示一个特定的页面需要返回该页面的ID 号。void CPropertyPage:OnOnWizardNext()按下了“ 下一步” 按钮。返回值含义与 voidCPropertyPage:OnWizardBack() 相同。void CPropertyPage:OnWizardFinish()按下了“完成”按钮。返回 FALSE 表示不允许继续,否则返回TRUE向导对话框将被结束。在向导对话框的DoModal()返回值为ID

47、_WIZFINISH或IDCANCEL下面的代码演示了如 何创建并使用向导对话框:/ 创建有模式向导对话框 void CMy56_s1Dlg:OnWiz()CSheet sheet ? sheet.SetWizardMode() ?int iRet=sheet.DoModal()?/ 返回 ID_WIZFINISH 或 IDCANCEL/ 重载 BOOL CPropertyPage:OnSetActive( ) 来控制显示的按钮BOOL CPage1:OnSetActive()(CPropertySheet*)GetParent() SetWizardButtons(PSWIZB_BACK|P

48、SWIZB_NEXT)? return CPropertyPage:OnSetActive() ?BOOL CPage2:OnSetActive()(CPropertySheet*)GetParent()SetWizardButtons(PSWIZB_BACK|PSWIZB_FINISH) ? return CPropertyPage:OnSetActive() ? 下载本节例子。5.7 使用通用对话框在Win dows系统中提供了一些通用对话框如:文件选择对话框如图,颜色选择对话框如图,字体选择对话框如图。在 MFC中使用CFileDialog ,CColorDialog ,CFontDia

49、log 来表示。般来讲你不需要派生新的类, 因为基类已经提供了常用的功能。 而且在创建并等待对话框结 束后你可以通过成员函数得到用户在对话框中的选择。CFileDialog 文件选择对话框的使用: 首先构造一个对象并提供相应的参数, 构造函数原型 如下:CFileDialog:CFileDialog( BOOLbOpenFileDialog, LPCTSTRlpszDefExt = NULL, LPCTSTR lpszFileName = NULL, DWORD dwFlags = OFN_HIDEREADONLY |OFN_OVERWRITEPROMPT, LPCTSTR lpszFilte

50、r = NULL, CWnd* pParentWnd = NULL )?参数意义如下:bOpe nF ileDialog为TRUE则显示打开对话框,为 FALSE则显示保存对话文件对话框。lpszDefExt 指定默认的文件扩展名。lpszFileName 指定默认的文件名。dwFlags 指明一些特定风格。lpszFilter 是最重要的一个参数,它指明可供选择的文件类型和相应的扩展名。参数格式种文件类型间用 | 分隔,末尾用 | pParentWnd 为父窗口指针。 创建文件对话框可以使用CString CFileDialog:GetPathName( ) c:testtest1.txtC

51、String CFileDialog:GetFileName( )CString CFileDialog:GetExtName( )CString CFileDialog:GetFileTitle ( ) test1POSITIONCFileDialog:GetStartPosition( 位置。CString CFileDialog:GetNextPathName(DoModal() ,在返回后可以利用下面的函数得到用户选择:得到完整的文件名,如:*.xls)|*.xlc(*.*)|*.*|? *.xls|All Files?文件类型说明和扩展名间用 | 分隔,同种类型文件的扩展名间可以用

52、? 分割,Chart Files (*.xlc)|*.xlc|Worksheet Files (*.xls)|*.xls|Data Files (*.xlc每指明。包括目录名和扩展名如:得到完整的文件名,包括扩展名如: test1.txt 得到完整的文件扩展名,如: txt 得到完整的文件名,不包括目录名和扩展名如:) 对于选择了多个文件的情况得到第一个文件POSITION& pos ) 对于选择了多个文件的情况得 下一个文件位置, 并同时返回当前文件名。但必须已经调用过 POSITION CFileDialog:GetStartPosition( ) 来得到最初的 POSITION 变量。C

53、ColorDialog 颜色选择对话框的使用:首先通过 CColorDialog:CColorDialog( COLORREF clrInit = 0, DWORDdwFlags = 0, CWnd*pParentWnd = NULL ) 构造一个对象,其中 clrInit 为初始颜色。通过调用 DoModal() 创建对话框, 在返回后调用 COLORREF CColorDialog:GetColor( ) 得到用户选择的颜色值。CFontDialog 字体选择对话框的使用: 首先构造一个对象并提供相应的参数, 构造函数原型 如下:CFontDialog:CFontDialog( LPLOG

54、FONT lplfInitial = NULL, DWORD dwFlags =CF_EFFECTS | CF_SCREENFONTS, CDC* pdcPrinter = NULL, CWnd* pParentWnd = NULL)?构造一个对象,其中参数Iplflnitial指向一个LOGFONG吉构(该结构介绍请见2.2在窗口中输出文字) ,如果该参数设置为 NULL 表示不设置初始字体。 pdcPrinter 指向一个代表 打印机设备环境的 DC 对象,若设置该参数则选择的字体就为打印机所用。pParentWnd 用于指定父窗口。通过调用 DoModal() 创建对话框,在返回后通过调

55、用以下函数来得到用户选 择:void CFontDialog:GetCurrentFont( LPLOGFONT lplf )?用来获得所选字体的属性。该函数有一个参数,该参数是指向LOGFONT吉构的指针,函数将所选字体的各种属性写入这个LOGFO NT吉构中。CString CFontDialog:GetFaceName( ) 得到所选字体名字。int CFontDialog:GetSize( ) 得到所选字体的尺寸(以 10 个象素为单位)。COLORREF CFontDialog:GetColor( ) 得到所选字体的颜色。BOOL CFontDialog:lsStrikeOut( )

56、BOOL CFontDialog:lsUnderline( )BOOL CFontDialog:lsBold( )BOOL CFontDialog:lsltalic( ) 得到所选字体的其他属性,是否有删除线,是否有下划线,是否为粗体,是否为斜体5.8 建立以对话框为基础的应用 我认为初学者使用以对话框为基础的应用是一个比较好的选择,因为这样一来可以摆脱一些开发界面的麻烦,此外也可以利用 ClassWizard 自动的添加消息映射。在VC中提供了生成“以对话框为基础的应用”的功能,你所需要选择的是在使用AppWizard的第一步选择“对话框为基础的应用”,如图。 VC 会生成包含有应用派生类和

57、对话框派生 类的代码。在应用类的 lnitlnstance() 成员函数中可以看到如下的代码:BOOL CMy58_s1App:lnitlnstance()CMy58_s1Dlg dlg ?m_pMainWnd = &dlg ?int nResponse = dlg.DoModal() ?if (nResponse = lDOK)/ TODO: Place code here to handle when the dialog is/ dismissed with OKelse if (nResponse = IDCANCEL)/ TODO: Place code here to handle

58、 when the dialog is/ dismissed with Cancelreturn FALSE ?这是产生一个有模式对话框并创建它,在对话框返回后通过返回 FALSE 来直接退出。在设 计时通过编辑对话框资源你可以设计好界面, 然后通过 ClassWizard 映射消息来处理客户的 输入,由于前几节已经讲过本节也就不再重复。同样基于对话框的应用也同样可以使用属性对话框做为界面, 或者是通过使用经过派生的通 用对话框作为界面。提示:当你使用有模式对话框时最开始是无法隐藏窗口的,而只能在对话框显示后再隐藏窗口,所以这会造成屏幕的闪烁。 一个解决办法就是采用无模式的对话框, 无模式的对

59、话框在 创建后是隐藏的,直到你调用ShowWi ndow(SW_SHO才会显示。相关代码如下:BOOL CMy58_s1App:InitInstance()/ 必须新生成一个对象,而不能使用局部变量 CMy58_s1Dlg* pdlg=new CMy58_s1Dlg ? m_pMainWnd = pdlg ?pdlgCreate() ? return TRUE ?5.9 使用对话框作为子窗口 使用对话框作为子窗口是一种很常用的技术, 这样可以使界面设计简化而且修改起来更加容 易。简单的说这种技术的关键就在于创建一个无模式的对话框,并在编辑对话框资源时指明Child 风格和无边框风格, 如图。

60、接下来利用产生一个 CDialog 的派生类, 并进行相关的消 息映射。在创建子窗口时需要利用下面的代码:int CMy59_s1View:OnCreate(LPCREATESTRUCT lpCreateStruct)if (CView:OnCreate(lpCreateStruct) = 1)return 1 ?/ 创建子窗口 m_dlgChild.Create(IDD_CHILD_DLG,this) ?/ 重新定位 m_dlgChild.MoveWindow(0,0,400,200) ?/ 显示窗口m_dlgChild.ShowWindow(SW_SHOW?)return 0 ?此外还有一

61、中类似的技术是利用 CFormView 派生类作为子窗口,在编辑对话框资源时也需 要指明 Child 风格和无边框风格。然后利用 ClassWizard 产生以 CFormView 为基类的派生 类, 但是由于该类的成员函数都是受保护的,所以需要对产生的头文件进行如下修改: class CTestForm : public CFormView/ 将构造函数和构析函数改为共有函数public:CTestForm() ?virtual CTestForm() ? DECLARE_DYNCREATE(CTestForm) 有关创建子窗口的代码如下: int CMy59_s1View:OnCreate(LPCREATESTRUCT lpCreateStruct)if (CView:OnCreate(lpCreateStruct) = 1)return 1 ?/ 对于 CFormView 派生类必须新生成对象而不能使用成员对象 m_p

展开阅读全文
温馨提示:
1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
2: 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
3.本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
关于我们 - 网站声明 - 网站地图 - 资源地图 - 友情链接 - 网站客服 - 联系我们

copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!