CGdiObject::DeleteObject的说法

CGdiObject说明
CGdiObject类是一个为各种windows图形设备接口(GDI)对象(比如位图,区域,画刷,画笔,调试板,字体等)提供的基类。
class CGdiObject : public CObject
我们不会直接构造一个CGdiObject对象,而是使用某一个派生类如CPen或CBrush创建。

CGdiObject::DeleteObject

#include <afxwin.h>
BOOL DeleteObject( );

返回值:如果GDI对象被成功删除,则返回非零值,否则为0。
说明:通过释放内部附加的GDI对象占有的系统存储来删除它们。
与CGdiObject对象有关的存储不受此调用的影响,受析构调用的影响。
如果CGdiObject对象正被选入设备上下文中,则应用不可对此对象调用DeleteObject.
当一个模式画刷被删除时,与之先关联的位图不被删除。位图资源对象必须被独立删除。

CGdiObject的子类:
类        句柄类型
CPen      HPEN
CBrush    HBRUSH
CFont     HFONT
CBitmap  HBITMAP
CPalette  HPALETTE
CRgn    HRGN
 
这些类在调用其Create函数来创建的话后必须调用DeleteObject( );

关于上述说法的证据查找:
CObject的析构函数是纯虚函数;virtual ~CObject() = 0;
CGdiObject直接派生于CObject,其中有BOOL CGdiObject::DelectObject()方法用于释放资源。但是为保证资源释放成功GDI对象必须不被DC选中,所以使用GDI对象后应该将其选出DC。
 
有人说:“CBrush,CPen,CFont,CBitmap都是从CGdiObject类派生的,CGdiObject的析构函数中会调用DeleteObject,所以在对象销毁前自己用代码DeleteObject是多余的。”还有人说,“用CPen::CreatePen()来初始化的才需要”??
 
MSDN中相关的的说明:
对于CPen的说明
When an application no longer requires a given pen, it should call the CGdiObject::DeleteObject member function or destroy the CPen object so the resource is no longer in use. An application should not delete a pen when the pen is selected in a device context.

我的理解是:“在程序中,类似CPen这样的对象在不用的时候应该手动调用CGdiObject::DeleteObject来释放资源。”
 
以此,合理的做法如下:

void CRingView::OnDraw(CDC* pDC)
{
   CRingDoc* pDoc = GetDocument();
   ASSERT_VALID(pDoc);
   if (!pDoc)
      return;
 
   // TODO: 在此处为本机数据添加绘制代码
   PointArray& pointArray = pDoc->GetPointArray();
   ColorArray& colorArray = pDoc->GetColorArray();
   int iSize = (int)pointArray.GetSize();
   for (int iIndex = 0; iIndex<iSize; ++iIndex)
   {
      CPoint point = pointArray[iIndex];
      COLORREF color = colorArray[iIndex];
      CPen pen(PS_SOLID,0,BLACK);
      CBrush brush(color);
      //将临时的CPen和CBrush选入DC,通过返回值保存原来的GDI对象
      CPen* pOldPen = pDC->SelectObject(&pen);
      CBrush* pOldBrush = pDC->SelectObject(&brush);
      //使用含有pen和brush的DC进行画图
      pDC->Ellipse(point.x-RADIUS,point.y-RADIUS,point.x+RADIUS,point.y+RADIUS);
      //重新载入原来的GDI对象使得临时GDI对象不再被引用而可以销毁
      pDC->SelectObject(pOldPen);
      pDC->SelectObject(pOldBrush);
      //调用DeleteObject释放pen和brush的资源
      pen.DeleteObject();
      brush.DeleteObject();
   }
}

 最后一点:为了避免临时资源的频繁创建和释放,可以改成全局资源,在程序销毁时统一释放。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值