理解operator HBRUSH( ) const的实现原理

61 篇文章 8 订阅

问题引出


在MFC中有个WM_CTLCOLOR消息,它的消息响应函数是CWnd类的OnCtlColor,其函数声明和注释如下:

afx_msg HBRUSH OnCtlColor( CDC* pDC, CWnd* pWnd, UINT nCtlColor );

返回值:OnCtlColor必须返回一个刷子句柄,该刷子将被用于画出控件的背景。
参数:
pDC       包含了子窗口的显示设备环境的指针。可能是临时的。  
PWnd      包含了要求颜色的控件的指针。可能是临时的。  
NCtlColor 包含了下列值,指定了控件的类型: 
· CTLCOLOR_BTN        按钮控件  
· CTLCOLOR_DLG        对话框  
· CTLCOLOR_EDIT       编辑控件  
· CTLCOLOR_LISTBOX    列表框控件  
· CTLCOLOR_MSGBOX     消息框  
· CTLCOLOR_SCROLLBAR  滚动条控件  
· CTLCOLOR_STATIC     静态控件 

 

该函数的返回值将被用来绘制控件的背景。当一个子控件将要被绘制时,它都要向的的父窗口(通常是一个对话框)发生一个WM_CTLCOLOR消息来准备一个DC,以便使用正确的颜色来绘制该控件。OnCtlColor默认的函数实现如下:

HBRUSH CDrawMainDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
    HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
    
    //如果默认的不是所需画笔,则返回另一个画笔
    //CBrush 对象
    return m_brush;
}
我们注意到,OnCtlColor函数 要求返回HBRUSH类型的句柄,而默认的函数返回的却是CBrush类型的画刷对象。这其中的原因就是 CBrush类重载了HBRUSH操作符。HBRUSH操作符重载声明如下:

operator HBRUSH( ) const;
调用成功时该操作符返回一个指 向Windows GDI对象的句柄,该句柄表示一个CBrush对象,否则返回NULL。

现在的问题就是请说明如何将CBrush对象转换为一个HBRUSH句柄,在回答这个问题之前我们先了解下GDI对象,重载,强制类型转换这个三个知识点。


补充知识


GDI对象

       微软提供了各种Windows图形设备接口(GDI)对象,如位图(CBitmap)、区域(CRgn)、画刷(CBrush)、画笔(CPen)、调色板(CPalette)、字体(CFont)的等类型,这些类类型对象可以用于相关图形的绘制工作,它们都有相同的父类CGdiObject,m_hObject是CGdiObject的数据成员,包含附加给对象的HBITMAP,HPALETTE,HRGN,HBRUSH,HPEN或HFONT的句柄。也就是说CPen、CBrush等对象都各自包含了相对应的句柄。


强制类型转换

     当操作数的类型不同,经常需要将操作数转化为所需要的类型,这个过程即为强制类型转换。强制类型转换具有两种形式:显式强制转换和隐式强制类型转换

显式强制转换

      形如“TYPE b = (TYPE) a”的表达式都是显示强制类型转换,这种转换有明显的转换过程,即括号和类型组合(TYPE)。

隐式类型转换

     这类型转换发生在赋值表达式有返回值的函数调用表达式中。在赋值表达式中,如果赋值符左右两侧的操作数类型不同,则将赋值符右边操作数强制转换为赋值符左侧的类型数值后,赋值给赋值符左侧的变量。在函数调用时,如果return后面表达式的类型与函数返回值类型不同,则在返回值时将return后面表达式的数值强制转换为函数返回值类型后,再将值返回。


操作符重载

操作符重载包含两个要素:operator 和被重载的字符,CBrush类被重载的字符就是"HBRUSH",当在CBrush类中,当遇到HBRUSH类型转换时,被转换的CBrush对象会调用operator HBRUSH()运算符重载函数,在其中的GDI类型中也都有相对应的运算符重载接口,它们的原理也都是一样的。


HBRUSH运算符重载实现


OnCtlColor函数中我们直接返回了CBrush类的对象,由于该函数要求返回的是HBRUSH句柄,两者类型不一致,发生隐式类型转换,即存在这个的过程“HBRUSH hTemp = (HBRUSH)m_brush”->m_brush.operatro HBRUSH()。m_brush对象调用了运算符重载函数,在该函数中返回了对应的句柄,函数大致实现如下:

HBRUSH operator HBRUSH()
{
   return this.m_hObject;//指向CBrush对象的句柄
}

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值