在
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
); ) //
重新获得保存的对象
}