分享
 
 
 

自绘按钮补遗

王朝vc·作者佚名  2006-01-17
窄屏简体版  字體: |||超大  

自绘按钮补遗

作者:杜修杏

下载本文配套源代码

(包括:改进后的CXPButton类、练习程序、练习程序答案)

《自绘按钮的实现》一文中所示范的CXPButton按钮从形状上看可以说是一个不规则按钮。我们把MFC中提供的控件成为标准控件,而其中的按钮控件则可称为规则按钮,因为它是的形状是一个规则的矩形。但是随着流线型设计在界面设计中被广泛采用,越来越多的程序设计者都乐意在自己的作品中加入一些非规则形状的控件。以按钮为例,最简单的就到有圆形按钮,三角按钮等。下图是一组定义好的圆形按钮:

但是这些在我们眼中似乎呈现出不规则形状的按钮,有时候的表现却不近乎人意。以之前设计的CXPButton为例,下面我们就来找找它的缺陷。我们把对话框的背景色改为其它颜色,看看会有什么效果。修改背景色的方法如下:为对话框类添加WM_ERASEBKGND消息,如果你在类向导中找不到该消息,请参考《自绘按钮的实现》中介绍的方法,注意在添加对话框中要把Filter

for messages available to设为Child Window才能在列表中看到WM_ERASEBKGND消息。我们在函数中添加绘制背景色的代码:

BOOL CXPButtonDemoDlg::OnEraseBkgnd(CDC* pDC)

{

BOOL retValue= CDialog::OnEraseBkgnd(pDC);

CRect rc;

GetClientRect(&rc);

pDC-FillSolidRect(&rc,RGB(0,0,255));

return retValue;

}

编译后运行程序,可以看到下面的效果,在按钮的四个角上出现了难看的边角,这就是我所说的缺陷了:

既然发现了问题,下面当然就是动手来解决问题的时间了。在《自绘按钮的实现》一文中曾经讲过,按钮的绘制主要在DrawItem()函数中完成。这里要补充一点就是DrawItem()是MFC所提供的系统函数,所以可以通过下图的方法添加。选择Add

Virtual Function…之后在弹出对话框左边的列表中找到DrawItem,选择Add and Edit即可。

好了,我们接着上面的话题。要解决按钮显示的“残角”问题,在这里需要使用一个叫做CRgn的类,这个类在创建不规则控件的时候经常要用到,我们可以通过CRgn类来设置控件的有效区域。那么什么是有效区域呢?以圆形按钮为例,MFC默认的按钮形状是矩形的,为了实现圆形按钮的效果,我们希望能够把原来矩形的四角裁剪掉,只保留中间的圆形区域。这种关系可以用下图来表示:

图中的A是原来的矩形区域,B是需要裁剪的区域,而C是有效区域。我们希望程序不要把B看作按钮的一部分,当鼠标在B上面点击的时候不要产生任何效果。设置按钮的有效区域一般是在PreSubclassWindow()函数里面实现的:

void CXPButton::PreSubclassWindow()

{

CButton::PreSubclassWindow();

ModifyStyle(0, BS_OWNERDRAW);

//设置按钮的有效区域

CRgn rgn;

CRect rc;

GetClientRect(&rc);

//有效区域为一个角半径为5的圆角矩形

rgn.CreateRoundRectRgn(rc.left,rc.top,rc.right,rc.bottom,5,5);

SetWindowRgn(rgn,TRUE);

rgn.DeleteObject();

}

编译后运行程序,我们发现尽管已经设置了按钮的有效区域,但是问题还是没有解决,这是为什么呢?前面我们曾经通过对话框的WM_ERASEBKGND消息函数来改变对话框的底色,其实按钮也有它的WM_ERASEBKGND消息函数,它会使用系统颜色根据控件的默认形状来绘制控件的底色。所以我们要重载按钮的WM_ERASEBKGND消息函数,让它什么都不做:

BOOL CXPButton::OnEraseBkgnd(CDC* pDC)

{

//禁止绘制底色

return TRUE;

}

再编译一次,运行后发现,难看的"残角"不见了:

《自绘按钮的实现》一文中还讲过在DrawItem()函数中应该先画底色,其实这是有前提的,前提就是你已经知道了按钮所在对话框所使用的背景色,你可以使用这个颜色作为按钮的底色来进行填充。这样即使程序会在WM_ERASEBKGND消息函数中使用系统颜色来绘制控件的底色,但是等到它执行DrawItem()的时候,马上又会把之前的矩形底色覆盖,从而不留痕迹地把“残角”掩盖掉。

在本篇开头列举的圆形按钮中也有类似的问题,大家不防把它作为练习,看看是否能够解决圆形按钮中的“残角”问题。我在本篇提供的练习程序中需要修改的地方会表明“提示”的字眼,大家可以先把源程序中有“提示”字眼的地方找出来,再根据提示的内容进行修改。

最后还要补充的是各位对CRgn类的关注。在VC中,要创建出各种复杂形状的控件、窗口经常要依靠CRgn类的强大功能来实现。如果你想在界面设计这个环节更进一步的话,建议你抽点时间仔细研究一下Msdn中关于CRgn类的使用说明。如果你有什么好的使用经验和心得,不防把相关资料发到我的邮箱。以后有机会的话我会专门写一篇文章探讨一下CRgn类的使用技巧的。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有