*************************************************************************
关于本文的字体格式:加粗字体(如:CGDIObject)表示类。
*************************************************************************
先说说GDI的hierarchy chart。
再整体描述关于GDI对象的使用。
最后了解下基类。
*************************************************************************
一、先来看看GDI的继承图:
使用GDI与DC密不可分,他俩的关系:DC(设备上下文)好比画图用的纸,GDI(图形设备接口)就是画图时的工具。
关于GDI对象说三点:
1)You never create aCGDIObject directly.Rather,you create an object from one of its derived classes,such asCPen orCBrush.
2)常用的GDI对象有六种:bitmap、brush、font、palette、pen、region。
3)如图内核对象一样,GDI对象用完后需销毁。
二、GDI对象的使用
1)创建一个GDI对象:
对内核对象、GDI对象和user对象使用都是通过操作其句柄来实现的。使用句柄来标识而非指针,因指针对应着一个数据在内存中的地址,得到了指针就可自由修改该数据;而当windows不希望一般程序修改其内部数据结构时使用指针。
所以使用MFC的类来创建一个GDI对象分为两步:构造一个类对象,再调用该类的create方法将类对象与一个GDI对象关联起来。也正因此,在使用完后需销毁GDI对象。(创建GDI对象失败唯一原因:内存不足)
2)将创建好的GDI对象选入DC中,并保存原来的GDI对象。
SelectObject返回的GDI对象是is “temporary”:意味着它将会在程序空闲时间(OnIdle)被删除。只要你使用SelectObject返回的对象在一个方法中而没有返回控制权到主消息循环就不会错。
如果你想重复使用一个GDI对象,可以allocate它一次,然后每次使用时将它选入DC,不用时确保删除。
3)使用完成后,将原GDI对象选入DC。销毁自己创建的GDI对象。
关于删除:如果用的是上图中的mfc类,则不必调用DeleteObject,因析构函数会调用此函数。当然SelectObject(旧的HGDIOBJ)是必须要调用的。对于系统自定义的GDI对象,任何时候都不必专门删除,也不用selectobject。
补充:栈先进后出,队列先进先出。
三、CGDIObject类
1)Data Members:
m_hObject:A HANDLE containing the HBITMAP,HBRUSH,HFONT,HPEN,HPALETTE,or HRGN attached to this object.
2)Operations:GDI类的方法基本上都在父类CGdiObject中。
BOOL Attach(HGDIOBJ hObject)将一个HGDIOBJ跟一个CGdiObject对象关联。
HGDIOBJ Detach()从CGdiObject分离出HGDIOBJ,并返回HGDIOBJ。
static CGdiObject* PASCAL FromHandle(HGDIOBJ hObject)给CGdiObject对象关联一个windows GDI对象并返回。
BOOL DeleteObject()删除与CGdiObject对象关联的windows GDI对象。并不删除CGdiObject对象(即类对象)。所以类对象如果是new出来的,必须手动删除类对象。
HGDIOBJ:指windows GDI object的句柄。类似的有HPEN,HBRUSH…注意区分类对象和GDI对象。