对话框编程•对话框用户界面程序的编写;•如何向对话框控件联接数据成员及其实现机理,•如何向对话框控关联控件类,•如何利用对话框类的成员函数向控件发送消息和获取对话框控件的类指针,•如何直接利用对话框控件类操纵对话框控件(发送消息和直接调用成员函数)。•如何在程序运行时产生和销毁控件。•对话框控件的几种操作方式。对话框及控件对话框及控件•如何实现对话框的部分收缩和展开。•如何制作属性页对话框和向导对话框•如何使用字体对话框•如何改变对话框和控件的背景色•如何改变控件的文本颜色通过本章的学习,•掌握对话框的编程,包括模式对话框、无模式对话框以及属性表和属性页•理解对话框控件和相对应的变量之间的交互,会熟练使用UpdateData函数•掌握各种控件的使用,尤其是编辑框、列表框、组合框、按钮要熟练。•理解TabOrder的含义•会使用位图按钮,以及一些其它的通用控件,如进展控制、动画控制、微调按钮、滑动条控制等对话框编程要在窗口中显示一个对话框,步骤如下:•插入一个对话框资源。对话框本身也是窗口。在MFC中,对资源的操作都是通过相应类来完成的。对话框资源也有相应的一个类,这个类叫CDialog。CDialog是从CWnd派生出来的,是一个窗口。•通过ClassWizard创建一个类来与这个对话框资源相关联•创建对话框窗口:分有模式对话框的创建(DoModal)和非模式对话框的创建(Create)对话框的种类•有模式对话框用于交换一些重要信息,强制用户完成所要求的动作有模式对话框在打开状态时,禁止用户在应用的其它地方进行工作,但多数允许用户切换到其他的应用程序中。•无模式对话框不禁止父窗口,它允许用户不需要关闭该无模式对话框,就可返回到另一任务。Find对话框就是一例无模式对话框当点击OK按钮时,非模态对话框并没有销毁,它只是隐藏了。当我们点击OK按钮时,它是由基类的OnOk虚函数来响应的。它只是不可见,并没有销毁它,这是编写非模态对话框应注意的地方。要在你的类中去覆盖OnOk函数,在函数内去调用DestroyWindow销毁对话框窗口。对话框上动态创建按钮实现功能:在对话框上添加一个按钮,当点击这个按钮时在对话框上动态增加一个按钮。任何从CWnd派生的类都有一个成员m_hWnd,保存了与这个对象相关联的窗口句柄。if(m_btn.m_hWnd!=NULL){m_btn.Create(编程,BS_DEFPUSHBUTTON|WS_VISIBLE|WS_CHILD,CRect(0,0,100,100),this,123);}else{m_btn.DestroyWindow();}【技巧:】如果想放置同样类型的控件,按照Ctrl键,选择对话框上已有的控件拖动就可实现复制粘贴功能。对于静态文本框,它主要是起标记作用,所以它的ID号都是一样的,缺省情况下它不接收点击事件。如果我们要响应文本框的点击事件,要把它的ID值改变一下,然后打开静态文本框的属性对话框,选中Styles的标签页中的Notify复选框对话框上文本框和编辑框的编程对话框控件访问七种方式•GetDlgItem()-Get(Set)WindowText()•GetDlgItemText()/SetDlgItemText()•GetDlgItemInt()/SetDlgItemInt()•将控件和数值型变量相关联•将控件和控件变量相关联•SendMessage()•SendDlgItemMessage()要用到UpdataData函数,这个函数的作用是用来初始化数据,或者用来校验对话框数据。这个函数带一个参数,如果为真,表示数据从控件获取,如果为假,表示控件正在被初始化。框架在一个模态对话框被创建时会自动调用这个函数将参数设为FALSE。改变对话框以及对话框控件的颜色窗口消息WM_CTLCOLOR。OnCtlColor是用来响应WM_CTLCOLOR消息的响应函数,返回值是画刷的句柄,是用来绘制控件的背景色。当控件将要绘制时,框架会调用这个函数,大多数控件会发送这个消息给它的父窗口(通常是对话框)用来准备pDc来绘制控件。要改变控件文本的颜色,通过调用SetTextColor函数。OnCtlColor函数第二个参数是请求颜色的控件的指针,第三个参数是考虑正在绘制的是哪个控件。在对话框中,每个控件的绘制都要发送WM_CTLCOLOR,也就是说,在一个对话框中,WM_CTLCOLOR被调用多次,每一个控件都会准备一个CDC的指针,通过第一个参数传递进来,第二个参数表明请求颜色的是哪个控件,第三个参数是那一种类型的控件。对话框捕获WM_CTLCOLOR消息OnCtlColor(CDC*pDC,CWnd*pWnd,UINTnCtlColor){HBRUSHhbr=CDialog::OnCtlColor(pDC,pWnd,nCtlColor);returnhbr;}要改变背景,只要自定义一个画刷,然后返回这个画刷即可改变对话框以及对话框控件的颜色在对话框中定义CBrushm_brush;在构造函数中m_brush.CreateSolidBrush(RGB(0,0,255));然后直接返回OnCtlColor(CDC*pDC,CWnd*pWnd,UINTnCtlColor){//HBRUSHhbr=CDialog::OnCtlColor(pDC,pWnd,nCtlColor);//returnhbr;returnm_brush;}改变对话框以及对话框控件的颜色只改变某些控件的颜色,要判读当前正在绘制的是哪个控件,而通过第三个参数只能知道当前正在绘制的是哪类控件,要精确控制哪个控件,需要用到GetDlgCtrID。它返回的是子控件的ID号,也可返回子窗口的ID值,if(pWnd-GetDlgCtrlID()==IDC_EDIT1){pDC-SetTextColor(RGB(255,0,0));pDC-SetBkMode(TRANSPARENT);returnm_brush;}只改变某些控件的颜色要改变文字的字体,在绘制控件时,按照指定的字体去绘制控件例:定义CFontm_font;初始化m_font.CreatePointFont(200,华文行楷);if(pWnd-GetDlgCtrlID()==IDC_TEXT){pDC-SelectObject(&m_font);}改变某控件的文字的字体对于按钮,要实现自绘的文本和颜色,应该去编写一个Button类,从CButton类派生,然后重载DrawItem这个函数。框架会调用DrawItem函数实现绘制。自绘按钮必须有BS_OWNERDRAW这个属性改变按钮的外观对话框收缩与展开实现收缩和扩展功能,要用到函数SetWindowPos该函数的第一个参数是Z顺序,什么是Z次序?窗口的Z次序表明了重叠窗口堆中窗口的位置,这个窗口堆是按一个假想的轴定位的,这个轴就是从屏幕向外伸展的Z轴。Z次序最上面的窗口覆盖所有其它的窗口,Z次序最底层的窗口被所有其它的窗口覆盖。应用程序设置窗口在Z次序中的位置是通过把它放在一个给定窗口的后面,或是放在窗口堆的顶部或底部。Ok按钮的消息处理函数如果在编辑框上按回车键,对话框就关闭了。原因是OK按钮是缺省按钮。作为缺省按钮,当你在对话框上按了回车键后,就由你的缺省按钮的处理函数来进行响应。在基类的OnOk函数中,关闭对话框。WM_INITDIALOGWM_INITDIALOG消息,是在对话框创建完成以及它上面的控件创建完成,在显示之前发送的消息。我们可以捕获这个消息。在这个消息处理函数中进行对话框的一些初始化工作。基于对话框应用程序的编程逃跑按钮的简便实现实现:在对话框上设置一个按钮,当你用鼠标点击这个按钮时,这个按钮就自动移到别的位置。也就是说你无法抓到它。思路:在对话框上再添加一个与刚才一模一样的按钮。当点击第一个按钮时,把这个按钮隐藏,第二个按钮显示出来;当点击第二个按钮时,则先隐藏第二个按钮,再把第一个按钮显示出来。因为这2个按钮是一样的,这样实现,给用户的感觉就是你点击按钮时,它跑到另一个位置,当你又点击它时,它又跑走了。给用户的感觉就是你永远抓不到它。定义新类CMyButton要实现这个功能,首先要捕获鼠标移动消息。由谁来捕获这个消息。由对话框来捕获鼠标移动的消息,当鼠标移动到对话框上的时候,这个消息处理函数就开始工作了,即按钮上下移动。这显然不是我们需要的,我们是需要当鼠标移动到这个按钮时,才执行按钮的跑动工作。即按钮上下移动。也就是说我们鼠标移动的消息由按钮来捕获。在MFC中去创建一个新的类,让它从CButton派生出来,将按钮关联一个成员变量,这个变量的类型就是我们新定义的CButton类。这样就将控件与新定义的类关联上了。实现机制可以通过CMyButton类来捕获鼠标移动的消息。在消息响应函数OnMouseMove中让一个控件隐藏,一个控件显示。当鼠标移到这个控件时,OnMouseMove这个函数会响应,在这个函数中让这个控件执行ShowWindow(SW_HIDE)就可隐藏。如何让另外控件显示出来?要是知道这个控件所关联的对象的内存地址,让他调用ShowWindow就可让它显示出来。实现机制如何获取这个控件的指针,最简单的办法就是在CMyButton中定义一个新的指针变量m_pMyBtn,它的类型是CMyButton。当我们用CMyButton这个类去实例化这2个对象的时候,每个对象内部都有这样一个成员变量m_pMyBtn。这2个对象的地址互相交换一下,对于每个对象来说,它的m_pMyBtn里面保存的就是对方的地址。在WM_INITDIALOG消息的响应函数OnInitDialog中,m_btn1.m_pMyBtn=&m_btn2;m_btn2.m_pMyBtn=&m_btn1;完成了这2个对象的地址交换。m_pMyBtn=0088:4400m_pMyBtn=0088:46600088:44000088:4660m_btn1m_btn2CMyButtonm_btn1;CMyButtonm_btn2;实现机制在OnMouseMove中ShowWindow(SW_HIDE);//先隐藏自己m_pBtn-ShowWindow(SW_SHOW);//再显示对方逃跑按钮的其他实现方法可以只创建一个按钮,将这个按钮关联我们新创建的类,然后跟踪鼠标移动消息,通过SetWindowPos或MoveWindow函数来移动按钮实现。GetClientRect(&rect)是得到窗口客户区域的大小,左上角坐标永远是(0,0),右下角坐标是窗口的宽度和高度。GetWindowRect(&rect)是得到整个窗口的大小和位置,左上角坐标和右下角坐标,是相对于屏幕左上角来说的。MoveWindow或SetWindowPos中的x,y坐标,对于对话框来说,是相对于屏幕左上角的,对于对话框上的控件来说,是相对于对话框的客户区的左上角来说的要得到下图中控件在对话框上的位置,即左上角坐标(36,56)。必须这样GetDlgItem(IDC_CONTROL)-GetWindowRect(&rect);此时,rect中的left和top成员分别是(109,186)。然后ScreenToClient(&rect)将rect转换为相对于对话框客户区的坐标,此时rect中的left和top成员分别是(36,56)逃跑按钮的其他实现方法voidCMyButton::OnMouseMove(UINTnFlags,CPointpoint){staticCRectrect;staticintflag=0;staticintheight,width;if(rect.IsRectNull()){GetWindowRect(&rect);GetParent()-ScreenToClient(&rect);height=rect.Height();width=rect.Width();}if(flag==0)MoveWindow(