用MFC创建个性的对话框

来源:互联网 发布:水准测量平差软件 编辑:程序博客网 时间:2024/05/06 15:17

本文涉及以下几个疑难问题:
1. 改正对话框的背景颜色
2. 用位图作为对话框的背景
3. 改变静态控件文字和背景颜色
4. 改变编辑框文字和背景颜色
5. 改变CheckBox的文字和背景颜色
6. 改变RadioBox的文字和背景颜色
7. 改变按钮的背景颜色和文字颜色
8. 在对话框中应用Picture控件
9. 改正Picture控件呈现的位图
10.应用LoadImage从资源装入位图
想使自个的热门软件与众不同就要给热门软件加点“色”,一个颜色搭配协调的窗口要比windows千篇一律的灰底黑字更能吸取更多人的眼球。设想假如html浏览器呈现的网页都是白底黑字,还会有那么多的人喜爱上网吗?估计互联网的人气将降低一半。做个出色的界面对于老手来说估计不在话下,但是对于新手来说还那样无从下手,应用BCGControlBar和Xtreme Toolkit是个很好的选取,不过对于一个小程式应用这么大的库未免有头重脚轻的感觉。其实不应用这一些庞然大物同样能够做个很“色”的界面,本文就结合CSDN论坛上经常被问起的疑难问题,介绍几个给对话框上色的窍门。本文的窍门都是针对MFC程式的,更多有联系窍门请参看“创建有个性的对话框之ATL/WTL篇”。
NO·1步:改变对话框的背景颜色
改变对话框的背景颜色那个疑难问题常常呈目前论坛上,可见大部份人对Windows默认的灰色对话框是多么不满。MFC程式改正对话框的背景和文字颜色最简单的窍门就是调用SetDialogBkColor参数,SetDialogBkColor是CWinApp类的成员参数,以下是该参数的原型:


请留意,SetDialogBkColor参数并非对Windows的某个API的封装,他是MFC框架的一部份,所以不应用MFC的程式也就享受不到这种方便。那个参数的应用很简单,在程式的CWinApp派生类的InitInstance参数中添加一行代码Code就行了:


图.1 就是运行效果:

图.1 SetDialogBkColor效果图
应用SetDialogBkColor也有局限的地方,那就是所有的控件文字颜色都相同,不能针对不相同的控件设置不相同的文字颜色,还有就是不能设置Edit控件的颜色。不应用SetDialogBkColor参数,直接编写代码Code控制对话框的背景颜色和控件文字颜色也不是很困难的事件,并且这种窍门能够帮助更灵活的颜色设置方案,比如对不相同类别的控件应用不相同的文字颜色,应用高亮度的背景颜色突出某个控件等等,最重要的是能够控制Edit控件的文字和背景颜色,下面就介绍这种窍门。
首先是改变对话框的背景颜色。当Windows操作系统需求重画某个窗口客户区的背景的时候,就会向该窗口发送WM_ERASEBKGND 消息,窗口的处理过程响应那个消息重新画窗口的背景,那个过程称之为“自画”。改变对话框的背景颜色的思想很简单,就是响应那个消息,用自定义的颜色填充对话框的客户区背景,代替对话框窗口默认的背景填充动作。许多新手经常问:“为啥在class wizard中找不到对话框的WM_ERASEBKGND消息,是否是对话框没有那个消息”?其实对话框也是窗口,它也有WM_ERASEBKGND消息,只是MFC的class wizard应用的dialog滤掉器将其滤掉掉了(只是在message窗口的呈现中滤掉了,并否则真的不响应那个消息),为的是代码Code编写过程中突出对话框专有的消息和控件事件。如图.2 所示,只要在class wizard中的“class info” table标签下将消息滤掉器改成Windows就能够在对话框的消息列表中看到WM_ERASEBKGND了。

图.2 改正消息滤掉器
目前经过class wizard添加WM_ERASEBKGND的消息响应参数,并如下所示改正那个参数:


m_brBkgnd是个CBrush,在此之前已经初始化过了,关键代码Code是最后返回TRUE,否则默认的调用基类参数,返回TRUE意在告诉Windows:“我已经画过背景了,你不能再画了”。目前来看看运行的效果:

图.3 重画背景的效果
应用位图作为对话框的背景也不难,就在整个客户区画唯一位图背景


第二步:改变控件的颜色
看起来不如刚才效果好,控件文字的颜色和背景色都没有改变,这是由于咱们还没有处理WM_CTLCOLOR消息。WM_CTLCOLOR是Windows的控件向其父窗口发送最频繁的通知消息之一,例如,许多控件发送WM_CTLCOLOR消息给父窗口,让父窗口帮助画刷来画自个的背景。MFC的窗口类对那个通知消息特殊对待,假如父窗口没有处理那个通知消息,MFC的窗口类就根据WM_CTLCOLOR通知消息的来源将那个WM_CTLCOLOR消息发送回控件,让控件自个处理,这就所谓的“消息反射”,不仅是WM_CTLCOLOR,MFC对很多通知消息都做了反射,不过咱们今天的例子没有应用“消息反射”,咱们在控件的父窗口,也就对话框窗口处理那个通知消息。还有一点需求说明的是,WM_CTLCOLOR消息是16位的Windows平台的消息,在32位的Windows平台上取而代之的是一些更明确的通知消息:
WM_CTLCOLORBTN 按钮控件
WM_CTLCOLORDLG 对话框
WM_CTLCOLOREDIT 编辑控件
WM_CTLCOLORLISTBOX 列表框控件
WM_CTLCOLORSCROLLBAR 滚动条控件
WM_CTLCOLORSTATIC 静态文档控件
MFC为了兼容性考虑,仍旧应用OnCtlColor响应这一部份消息,但是经过参数parameternCtlColor来具体的区分她们。在那个参数中,咱们能够经过改变pDC参数parameter的属性来改变控件的绘制,并返回相应的画刷句柄给控件,控件应用那个画刷画自个的背景。下面是咱们改正后的OnCtlColor参数:


图.4 就这段代码Code的效果,在那里咱们不分“青红皂白”,向所有的控件返回咱们自个的画刷,看起来不错,Edit控件的文字颜色也改了,但是好像多行Edit控件有了麻烦,看来需求对多行Edit控件特殊对待。

图.4 重载OnCtlColor之后的效果
对于多行Edit控件特殊处理,如下所示,上面的疑难问题解决了:


上面的代码Code解决了IDC_EDIT_MULTI_LINE的疑难问题,但是对每个多行Edit控件都要判断ID,下面的窍门能够一劳永逸地解决多行编辑控件的疑难问题:


下面咱们针对每个控件设置特殊的颜色,区分控件能够经过控件的ID,改正控件背景也很简单,直接返回相应的画刷就能够了,下面就是颜色设置的完整代码Code:

目前看看效果:

图.5 改正OnCtlColor之后的效果
上面的代码Code是根据控件ID来设置颜色,还能够根据控件的类别统一设置某种控件的颜色,这就要用到nCtlColor参数parameter,nCtlColor参数parameter用来指明发送那个通知消息的控件的类别,nCtlColor能够是以下取值:
CTLCOLOR_BTN
CTLCOLOR_DLG
CTLCOLOR_EDIT
CTLCOLOR_LISTBOX
CTLCOLOR_MSGBOX
CTLCOLOR_SCROLLBAR
CTLCOLOR_STATIC

第三步:应用位图作对话框的背景
应用位图作为对话框的背景也很简单,就在OnEraseBkgnd中用位图填充客户区,只是在OnCtlColor中需求留意返回空画刷代替原来的画刷,返回空画刷是为了阻止控件绘制自个的背景,从而破坏位图背景的完整性,但是有时候返回空画刷会对更多有联系控件产生不良效果,所以咱们只处理了CTLCOLOR_BTN和CTLCOLOR_STATIC两种类别的消息:


下面是应用位图背景和空画刷的效果:

图.6 应用位图背景的效果

第四步:单独处理按钮控件
目前看来按钮控件还是影响整体效果,WM_CTLCOLORBTN好像对于push button类别的按钮控件没有效果,不过push button也是支持自画的,在应用自画按钮之前,咱们先来看看控件自画的思想。Windows的控件都有默认的外观,但是许多控件有支持“自画”,也就让用户定制控件的外观,当给唯一控件指定自画的样式之后,控件在重画自个的时候向父窗口发送WM_MEASUREITEM和WM_DRAWITEM消息,父窗口响应这两个消息,得到控件的大小并绘制控件,从而使控件有定制的外观。但是每个控件的自画都由父窗口完成加重了父窗口的负担,也不利于代码Code重用,所以,MFC对这一部份消息停止了反射处理,就将消息发还位控件,由控件响应消息,自个绘制,那样将自画代码Code封装在控件类中,升高了代码Code的重用性。很多MFC的控件类都自个处理这两个消息,派生类能够重载MeasureItem和DrawItem自个画控件的外观,CButton就那样的控件类。
目前就来做唯一自画的按钮类,首先从CButton派生出一类,咱们命名为CSMButton,然后重载DrawItem和PreSubclassWindow,重载PreSubclassWindow的理由是在CSMButton子类化按钮控件之前先给按钮添加BS_OWNERDRAW样式,否则按钮就不会向父窗口发送WM_DRAWITEM消息,MFC的消息反射就不会作用了,咱们的DrawItem就不会被调用,嗯,后果很重大。当然也能够让CSMButton的应用者自个给按钮添加BS_OWNERDRAW样式,但是会让人觉得没水平,嗯,后果也很重大。接下来添加对WM_CAPTURECHANGED、WM_MOUSEMOVE、WM_SETCURSOR和WM_KILLFOCUS四个消息的响应参数,对这四个消息的响应是为了给按钮渐增更多的功能,比如使按钮看起来象道具栏的按钮,改变鼠标的形状等等。
涉及CSMButton类的应用就像CButton相同,为按钮添加变量就行了,演示代码Code中包含了那个类的源代码Code以及应用办法,那里不在赘述。CSMButton类的功能很简单,但是完成了唯一自画按钮的框架,大部份人能够改正代码Code呈现自个的风格,网上也有很多那样的类,功能更强大,比如STButton等。目前看看CSMButton的效果:

图.7 应用自画按钮后的效果

第五步:应用Picture Box控件
想要在对话框上呈现位图,能够应用很复杂的控件或CxImage之类的库,也能够很简单地应用Picture Box。Picture Box默认的样式使Frame,需要手工改成Bitmap,如下图所示:

图.8 应用位图
VC6的集成环境不支持24位位图的浏览和编辑,但是并不效果应用,本例应用的位图都是24位的,为的是省去调色板的处理,自己较量懒。应用如下代码Code就能够更改Picture Box中的位图:


装载位图还能够那样:


这是最终的效果:

图.9 对话框的最终效果
 

原创粉丝点击