在MFC中,图形设备被封装在几个设备环境类中。CDC是所有这些图形设备的父类,其中几个重要的图形设备类有CDC,CWindowDC,CClientDC,CPaintDC等,其中,CWindowDC和CClientDC是显示器环境类,区别是CClientDC不包含非客户区(非客户区就是菜单,工具条等用户不能改变其显示方式的区域),CDC作为CView类的重载函数OnDraw的一个参数, CPaintDC在重载CView类的OnPaint()函数时需要.
Exp1:
{
CwindowDC dc(this); //传一个窗口句柄给设备
dc.TextOut(100,100,”hello”); //在窗口的100,100处显示”hello”
}
及时删除设备环境类是很重要的,系统限制了可用的设备环境的数量.由于上述代码定义的是一个局部的临时栈变量,出了括号后会自动释放,所有不必显示删除.
在用设备环境类作图之前,需要填充其状态(当然它有默认状态,Exp1就是用的默认状态),状态包括如下内容:
1. 相关的GDI绘图对象,如画笔,字体等
2. 绘图时的映射模式(控制缩放尺寸的)
3. 其他细节,如文本对齐参数等
设备类通过重载函数SelectObject()选择其状态对象
GDI对象
Windows GDI对象从CGdiObject对象派生,比如:
CBitmap类,CPen类,CBrush类,CFont类,CPalette类,CRgn类等.
其中向CPen,CBrush可以通过构造函数一步生成,其他的首先需要用默认的构造函数创建C++对象,然后调用一个创建函数,例如CreateFont等.
如果构造了GDI对象,必须在退出程序之前删除它.而要删除GDI对象,必须首先把它同设备环境分开.
Exp2:
Func(CDC* pDC)
{
CPen newPen(PS_DASHDOTDOT,2,(COLORREF)0); // 创建黑色画笔GDI对象
PDC->SetMapMode(MM_TEXT ); //选择映射模式(以像素为单位)
Cpen *oldpen = pDC->SelectObject(&newPen); //保存旧状态
pDC->MoveTo(10,10);
pDC->LineTo(100,10);
pDC->SelectObject(oldpen); //恢复旧的状态,新的状态出了括号自动删除
}
系统包括了大量的库存GDI对象,库存对象不必删除,因为它是系统的一部分,你可以用库存对象作图,如
pDC->SelectObject(BLACK_PEN); // BLACK_PEN为库存对象
每一次得到的设备,都是一个”新鲜的”设备,也就是设备不会保存它的环境,你必须每次从头开始设置设备的环境,如果确实要保存某一个设备的环境(如保存一个CPen对象),就必须用GDI对象的GetSafeHandle成员函数,把它转换成一个Windows句柄(唯一能够永久存在的GDI标示符)如下.
Exp3:
HFONT m_holdfont;
func(CDC* pDC)
{
font->CreateFont(30,10,0,0,400,FALSE,FALSE,0,……); //创建font对象
Cfont* oldfont= pDC->SelectObject(font);
m_holdfont = (HFONT)oldfont->GetSafeHandle(); //保存GDI对象句柄,使其在别的地方可
用, m_holdfont为类成员变量
不能简单的保存oldfont指针
}
func2(CDC* pDC)
{
if(m_holdfont)
{ pDC->SelectObject(CFont::FromHandle(m_holdfont); ) //重新获得保存的对象
}
本文详细介绍了MFC中的绘图机制,包括图形设备环境类CDC及其派生类的功能与使用方法,GDI对象的选择与状态保存技巧,并提供了具体的代码示例。
95

被折叠的 条评论
为什么被折叠?



