WEB开发网
开发学院软件开发VC 自绘按钮补遗 阅读

自绘按钮补遗

 2008-01-19 20:25:41 来源:WEB开发网   
核心提示:好了,我们接着上面的话题,自绘按钮补遗(2),要解决按钮显示的“残角”问题,在这里需要使用一个叫做CRgn的类,如果你有什么好的使用经验和心得,不防把相关资料发到我的邮箱,这个类在创建不规则控件的时候经常要用到,我们可以通过CRgn类来设置控件的有效区域

好了,我们接着上面的话题。要解决按钮显示的“残角”问题,在这里需要使用一个叫做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类的使用技巧的。

上一页  1 2 

Tags:按钮 补遗

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接