浅谈Lesson 07-08图形设备接口(doc 16页)
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
CWin dowD C 可以提供在整个窗口(包括客户区和非客户区)中画图的设备环境
CPain tDC 这是创建响应WM_PAINT消息的设备环境,应用程序可以使用此类更新Windows显示,通常在MFC应用程序的OnPaint()函数中使用
CMeta FileD C 这个设备环境代表Windows元文件,包含一系列命令以重新产生图像。
要创建独立于设备的文件时可使用这种DC,用户可以回放这种文件来创建图像
①CWindowDC类与CPaintDC和CClientDC类的区别
■绘图区域不同:CWindowDC类与CPaintDC和CClientDC类的区别的一个方面就是绘图区域不同。
用CPaintDC类和CClientDC 类的对象绘制图形时,绘制区只能是客户区,而不能在非客户区,而CWindowDC可以在非客户区进行图形绘制。
■绘图坐标系不同:在CWindowDC绘图类下,坐标系是建立在整个屏幕上的,在像素坐标
方式下,坐标原点在屏幕的左上角,而在CPaintDC和CClientDC绘图类下,坐标系是建立在客户区上的,在像素坐标方式下,坐标原点在客户区的左上角。
②CPaintDC类与CClientDC类的区别
■绘图机制不同:CPaintDC类与CClientDC类都是在窗口的客户区内绘制图形,但两者在绘制机制上有着本质的区别。
CPaintDC类应用在OnPaint函数中,以响应Windows的WM_PAINT消息,而CClientDC应用在非响应WM_PAINT消息的情况下。
CPaintDC类响应WM_PAINT消息,自动完成绘制,这对维护图形的完整性有着重要的作用。
例如在一个窗口中,已经绘制了n条直线,这个窗口的完整性可能会被破坏(如被对话框覆盖),当破坏完整性的程序结束时,即覆盖取消,这个窗口就会接收到一个WM_PAINT消息,得到此消息后,激活消息处理函数(如OnPaint)进行窗口绘制。
CPaintDC类对象就担负着此时的绘制工作。
如果现在想在屏幕上再绘制一条直线(如用鼠标实时绘制,当第二次单击鼠标左键时完成绘制),就要用到CClinetDC类,这个类可以实时
的将图形绘制在屏幕上。
如果用CPaintDC完成同样的工作,只能发出指令让包含要绘制这条直线的屏幕部分重画,把这条直线绘制到屏幕上。
当然,这个重画区域内的其他图形元素同时也会重画。
■适用范围不同:CPaintDC类只能支持屏幕显示,而CClientDC类除了支持屏幕显示以外,还支持打印。
` CDC类中的函数除了绘制图形的函数以外,还有以Get开头的获取绘图属性的函数,以Set
开头的设置绘图属性的函数。
3.常用绘图函数示例
CDC类中封装了一大批用来绘图的函数,除了文本输出函数TextOut以外,介绍几个常用的绘图函数,函数的原型以及更多的绘图函数用法查阅MSDN。
①画点
//绘制一个彩色点
pDC->TextOut(20, 20, "点");
pDC->SetPixel(100, 40, RGB(255,0,0));
上面的代码表示用红色画一个点。
RGB是一个宏,可以将颜色的三个R(Red)、
G(Green)、B(Blue)分量值转换为Windows
的颜色数据类型COLORREF(格式为0x00bbggrr),三个分量分别表示红、绿、蓝颜色的多少,取值范围为0~255。
常用的8种颜色如下表所示:
常用的8种纯色
RGB 颜
色
RGB值颜色
RGB(0,0,0)黑
色
RGB(255,
255,255)
白色
RGB(255,0,0)红
色
RGB(0,255,
0)
绿色
RGB(0,0,255)蓝
色
RGB(255,
255,0)
黄色
RGB(0,255,255)青
色
RGB(255,0,
255)
品红
②画线段
//绘制线段
pDC->TextOut(320, 20,"线段");
pDC->MoveTo(400, 40);
pDC->LineTo(500, 40);
上面的代码画线,MoveTo函数移动画笔到一
点,LineTo函数画线。
③画折线(多义线)
//绘制折线
pDC->TextOut(20, 170, "折线");
POINT
polyline[4]={{240,240},{80,120},{240,120} ,{80,240}};
pDC->Polyline(polyline,4);
上面的代码将给定的4个点顺序连成折线,函数中第一个参数为折线顶点数组名,第二个参数表示一共有几个点构成折线(最小必须为2)。
POINT是Windows的一种结构,用来标识一个点,它有两个成员变量,分别用来表示点的X和Y 坐标;在MFC类库中,CPoint封装了这种结构。
④画矩形
//绘制矩形
pDC->TextOut(320, 170, "矩形");
pDC->Rectangle(390, 110, 600, 230);
此函数只能画平行于屏幕的矩形,前两个参数分别为矩形的左上角点的X和Y坐标,第三、四个参数分别为矩形的右下角点的X和Y坐标。
⑤画椭圆
//绘制椭圆
pDC->TextOut(20, 320, "椭圆");
pDC->Ellipse(80, 260, 280, 380);
此函数画一个由4个参数表示的矩形的内切椭圆。
CDC里没专门画圆的函数,画圆仍然使用Ellipse函数。
使X和Y方向的长度相等,这时画出来的就是一个圆。
⑥画多边形
//绘制多边形
pDC->TextOut(320, 320, "多边形"); POINT
polygon[3]={{380,330},{530,260},{500,360} };
pDC->Polygon(polygon,3);
上面的代码将给定三个点顺序首尾连成封闭的多边形,函数中第一个参数为多边形顶点数组名,第二个参数表示多边形顶点的数目。
新建一个Graph单文档工程,并在CGraphView类的OnDraw函数中加入上述代码:编译并运行程序,可见输出的图形。
4.获取设备环境
在窗口中绘图,必须首先取得窗口的设备环
境,如果不在CDC类中进行绘制,就必须首先想办法获取对应的设备环境(或者一个指向设备环境的指针)。
①使用GetDC函数
GetDC函数用于获取指定窗口工作区的显示器设备环境,其原型声明如下:
CDC* CWnd::GetDC( );
函数不带任何参数,如果函数调用成功,则返回标识CWnd客户区的设备环境,否则返回NULL。
返回指针可能是临时性的,所以应该把它保存下来供以后使用。
对于公用的设备环境,GetDC成员函数为每一次被获取的设备环境指定默认属性。
对于私有的设备环境GetDC成员函数保持它先前所具有的属性不变。
设备环境可以用于图形设备接口(GDI)函数在客户区中绘图。
一般完成作图之后,用GetDC成员函数获取的设备环境必须通过调用ReleaseDC成员函数来释放。
因为在一个给定的时刻,系统只有五个公共的设备环境是可用的,如果使用了设备环境后不释放,有可能会妨碍其他的应用程序访问设备环境。
ReleaseDC用于释放一个设备环境,以便该设备环境可以被其他应用程序申请使用。
其原型声明如下:
int ReleaseDC( CDC* pDC );
其中pDC为待释放的设备环境的指针。
如果释放成功,函数返回非零值,否则,函数返回零。
下面的代码表示在单击某个菜单时画一个
椭圆:
void CGraphView::OnDrawEllipse()
{
CDC * pDC;
//调用CGraphView::GetDC()获取设备环境
pDC = GetDC();
pDC->Ellipse(0, 0, 100, 100);
//使用完后调用CGraphView::ReleaseDC()释放设备环境
ReleaseDC(pDC);
}
②直接构造CDC对象
声明一个CDC类或者其派生类对象,获取设备
环境,方法如下:
CClientDC dc(CWnd* );
构造一个对象,间接使用了GetDC成员函数。
当用一个C++的类声明一个对象时,系统会自动调用该类的构造函数,而在CClientDC类的构造函数中就调用GetDC函数。
当对象被释放时,又会自动调用该类的析构函数,而在其析构函数中,则调用了ReleaseDC函数来释放设备环境。
因此,前面的代码可以改为:
void CGraphView::OnDrawEllipse()
{
CClientDC dc(this);
dc.Ellipse(0, 0, 100, 100);
}
这样不用用户自己去释放设备环境,在CClinetDC对象被折构时会自动释放。
二、GDI对象
Windows的GDI对象类型是通过MFC库中的类来表示的,其中CGdiObject类是所有GDI 对象的抽象基类,其派生类包括CBitmap类、CBrush类、CFont类、CPen类、CRgn类和CPalette类,继承关系如下图所示。
这些派生类对于绘制图形和图像都是非常重要的,经常要使用这些类来创建绘图工具,而很少直接使用基类
CGdiObject。
设备环境和图形设备接口是实现计算机绘图的两个重要的组成部分,设备环境主要定义了绘图的状态和方式,而图形设备接口则主要定义了用来绘图的工具。
设备环境中包含有默认的GDI 对象。
■CBitmap:位图是一种位矩阵,每一个显示像素都对应于其中的一个或多个位。
用户可以利用位图来表示图像,也可以利用它来创建画刷。
■CBrush:画刷定义了一种位图形式的像素,利用它可对区域内部填充颜色。
■CFont:字体是一种具有某种风格和尺寸的所有字符的完整集合,它常常被当作资源存于磁盘中,其中有一些还依赖于某种设备。
■CPen:画笔是一种用来画线及绘制有形边框的工具,用户可以指定它的颜色及厚度,并且可以指定它画实线、点线和虚线。
■CRgn:区域是由多边形、椭圆或二者组合形成的一种范围,可以利用它来进行填充、裁剪以及鼠标点中测试。
■CPalette:调色板是一种颜色映射接口,它
允许应用程序在不干扰其他应用程序的前提下,充分利用输出设备的颜色描绘能力。
为了使用某种GDI对象,一般需要首先构造一个GDI对象,然后将这个GDI对象放入设备环境中,进行绘制工作。
绘制完毕后,还必须将GDI对象释放。
三、使用画笔
画笔是一种用来画线及绘制有形边框的工具。
在MFC中,用CPen类封装了GDI的画笔对象。
用户可以通过画笔来选择线条的形状、粗细和颜色三种属性。
系统默认的画笔是黑色,线宽为1个像素、并且是实线。
1.构造一支画笔
MFC中CPen类的构造函数:
CPen类一共重载了三个构造函数:
CPen(); //没有参数;
CPen( int nPenStyle,//线条类型
Int nWidth, //线条宽度
COLORREF crColor); //线
条颜色
CPen( int nPenStyle,//线条类型
int nWidth, //线条宽度
const LOGBRUSH* pLogBrush, //指向LOGBRUSH结构的指针
int nStyleCount=0, //如果非PS_USERSTYLE,恒为0
const DWORD*
lpStyle=NULL); //如非
PS_USERSTYLE,恒为空第一个构造函数不带任何参数,由于它所构造的只是一个未初使化的CPen对象,构造完成后还必须调用CPen类的其他成员函数初始化之后才可以使用。
另外,该构造函数总是可以被成功调用。
第二个构造函数带有三个参数,分别对画笔的线形、线宽和颜色进行了初始化:
参数nPenStyle:指定画笔的风格(样式),也就是画笔的线形,该参数在构造函数中可以为如下所列值:
参数nPenStyle
参数值注释示例PS_SOLID 创建一个实线
画笔
PS_DASH 创建一个虚线
画笔,该值只
有当画笔宽度
小于1个设备
单位或更小时
才有效
PS_DOT 创建一个点线
画笔,该值只
有当画笔宽度
小于1个设备
单位或更小时
才有效
PS_DASHDOT 创建一个点划
线画笔,该值
只有当画笔宽
度小于1个设
备单位或更小
时才有效
PS_DASHDOTDOT 创建一个双点
划线画笔,该
值只有当画笔
宽度小于1个
设备单位或更
小时才有效
PS_NULL 创建一个空线
画笔
PS_INSIDEFRAME 创建一个内框
线画笔,该画
笔可以在
WindowsGDI
输出函数定义
的矩形边界所
生成的封闭形
状的边框内绘
制直线
参数nWidth:指定画笔的宽度。
对于该构造函数,如果该值为0,那么无论是什么映射模式,设备单位的宽度总1个像素。
注意:如果nWidth大于1,则第一个参数中
的PS_DSDH(虚线)、PD_DOT(点线)、PD_SASHDOT(点划线)、PS_DASHDOTDOT (双点划线)风格不可用。
参数crColor:包含了一个画笔所具有的RGB 颜色。
使用了32位的COLORREF类型值来确定图形颜色值,其结构为0x00bbggrr(十六进制),各部分的数值分别说明如下:
bb代表蓝色值,范围从00到FF(即从0到255)。
gg代表绿色值,范围从00到FF(即从0到255)
r r代表红色值,范围从00到FF(即从0到255)
在程序中还可以使用RGB宏来完成相同的功能。
第三个构造函数带有5个参数。
如果需要直接构造一支画笔,只需要一句代码就可以。
2.使用(选择)画笔
在绘图中使用画笔,要把新的画笔选入到设备环境中去。
使用CDC类的成员函数SelectObject
来把新的GDI对象选入到设备环境中,同时这个函数将会把设备环境以前的GDI对象作为函数的返回值返回。
CDC类中一共重载了5个SelectObject()函数:
CPen* SelectObject( CPen* pPen );
CBrush* SelectObject( CBrush* pBrush ); virtual CFont* SelectObject( CFont* pFont ); CBitmap* SelectObject( CBitmap* pBitmap ); int SelectObject( CRgn* pRgn );//选择区域
函数的参数就是将要使用的新GDI对象,而函数的返回值(除最后一个函数以外)就是设备环境原来使用的GDI对象。
一般情况下,需要把旧的GDI对象保存起来,在画完图以后再把旧的GDI对象用SelectObject函数选回去,以勉资源的浪费。
3.画笔使用实例
如TestPen工程,改写视图类的OnDraw函数。
改变线宽参数,使它大于1,观察结果:
注意:当线宽大于1的时候,虚线、点线、点划线、双点划线风格都被忽略,仍然采用实线画笔。
因此,是不可能用构造函数创建线宽为4的
虚线画笔的。
可以看到,使用一支画笔绘图一般为分三步:创建、选择、落选。
其他的GDI对象的使用方法也基本相同。
GDI对象的使用方法一般为下面3大步骤:第1步:创建GDI对象(可以直接构造,或者用Greate函数);
第2步:用CDC::SelectObject函数将GDI 对象选入设备环境(DC)中;
第3步:使用完之后,再用CDC::SelectObject 函数将GDI对象落选(即选回来),最后释放GDI对象。
注意:有些GDI对象可以一步由构造函数直接创建,如CPen和CBrush,而另外一些类如CFont和CRgn等则必须要两步:首先构造对象,其次进一步调用相应的创建函数。
四、使用画刷
画刷(Brush)用来对封闭区域内部进行填充。
例如用Ellipse函数画一个封闭的圆,此圆并不是空心的,圆的中间会用设备环境中默认的画刷来填充(由于默认的画刷为白色,因此在白色背景中,这个圆仿佛就是空心了,实际上是一个白
色的实心圆)。
MFC类库中,画刷被封装在CBrush类中。
通过该类构造的CBrush对象可以传递给任何一个需要画刷的CDC成员函数。
画刷可以是实线、阴影线或某种图案。
1.创建画刷
CBrush类有4个重载的构造函数:
CBrhsh();//无参数的构造函数
CBrhsh(COLORREF crColor); //构造实体画刷
CBrush(int nIndex,COLORREF crColor); //构造阴影线模式画刷
CBrush(CBitmap* pBitmap); //构造位图画刷
第一个构造函数构造了一支未被初始化的画刷,如果用户使用了该构造函数,类似CPen的无参数构造函数一样,必须调用其他成员函数对所得到的CBrush 对象进行初始化。
其他重载的构造函数分别使用指定的颜色、阴影线模式和颜色或位图指针来构造一支已经被初始化的画刷。
参数crColor:以RGB颜色指定画刷的前景色。
如果是表示阴影线模式的画刷,则该参数指定的是阴影线的颜色。
参数nIndex:指定了画刷的阴影线的风格,如下所示:
画刷阴影线的样式
阴影线参数值注释
HS_BDIAGONAL 从左到右向下成
45°的对角线
HS_CROSS 水平线和垂直线相
交的十字交叉线HS_DIAGCROSS 夹角为45°的斜十
字交叉线
HS_FDIAGONAL 从左到右向上成
45°的对角线
HS_HORIZONTAL 水平阴影线
HS_VERTICAL 垂直阴影线
参数pBitmap:指向一个CBitmap对象,该对象指定了一幅用作画刷的位图。
和画笔一样,
要直接构造一支画刷,只需要一句代码就可以。
2.使用(选择)画刷
使用画刷,和CPen一样,要分三步走:创建、选择、落选。
创建名为TestBrush单文档工程,其他设置使用默认选项,修改视图类的OnDraw 函数创建并使用画刷。
五、输出文本
要使用不同的字体输出文本,需要使用到GDI 对象字体。
MFC类库中,Windows的图形设备接口字体和操纵字体的函数都被封装在CFont 类中。
1.用CreateFont创建字体
创建一个CFont对象相对比较复杂,在使用字体对象之前,必须调用CFont类的其他成员函数(如CreateFont、CreateFontIndirect、CreatePointFont或CreatePointFontIndirect等)对字体对象进行初始化,以便确定字体对象的参数。
调用CerateFont函数来选择一种字体时,需要很多的参数,该成员函数的原型声明如下:BOOL CreateFont(int nHeight,
int nWidth, //字体平均宽度
int nEscapement, //字体标注行旋转角度
int nOrientation,//字符基线角度
int nWeight, //字体粗细程度
BYTE bItalic, //是否斜体
BYTE bUnderline, //是否下划线
BYTE cStrikeOut, //是否着重号
BYTE nCharSet, //字体的字体集
BYTE nOutPrecision, //输出精度
BYTE nClipPrecision, //载剪精度
BYTE nQuality,
BYTE nPitchAndFamily, //字体的间距和所属的族
LPCTSTR lpszFacename); //字体的名字
很多参数一般情况下都不用(除非编写专门的排版软件),而且都有默认的设置。
其中参数nWeight:定义了字体的浓度即字体的粗细程序(像素数/1000)。
如下列出了该参数的通用常量值:
字体的浓度值—粗细程度
常量值常量值
FW_DONTCARE 0 FW_SEMIBOL
D 60 0
FW_THIN 10
0 FW_DEMIBOL
D
60
FW_EXTRALIG HT 20
FW_BOLD 70
FW_ULTRALIG HT 20
FW_EXTRABO
LD
80
FW_LIGHT 30
0 FW_ULTRABO
LD
80
FW_NORMAL 40
0 FW_BLACK 90
FW_REGUNAL 40
0 FW_HEA VY 90
FW_MEDIUM 50
参数cCharSet:指出了字体的字体集。
如下列出了预定义的字符集常量的值:
预定义的字符集常量
常量值
ANSI_CHARSET 0
DEFAULT_CHARSET 1
SYMBOL_CHARSET 2
SHIFTJIS_CHARSET 128
OEM_CHARSET 255
参数nOutputPrecision:指出所要求的输出精度,该精度确定输出与所要求的字体高度、宽度、控制、字符方位及间距的匹配和接近程度。
一般取下列值之一:OUT_CHARACTER_PRECIS,OUT_DEFAUL T_PRECIS,OUT_DEVICE_PRECIS,OUT_RAS
TER_PRECIS,OUT_STRING_PRECIS,OUT_STROKE_PRECIS和OUT_TT_PRECIS。
参数nPitchAndFamily:确定了字体的间距和所属的族。
这个8位参数的低4位确定了字体的间距,可以是DEFAULT_PITCH,FIXED_PITCH或V ARIABLE_PITCH。
高4位指定了字体族。
参数lpszFacename:是一个指向ASCII字符串的指针。
确定了目标字体的字形名(如“Times New Roman”、“宋体”等等)。
参数值一定不能超过30个字符,这个名称可由用户自行定义。
2.使用字体
创建一个字体比创建画笔和画刷的参数要多,但使用方法却和画笔、画刷没有差别:使用时选入设备环境中,使用完毕再选出来。
创建TestFont单文档工程,在视图类的OnDraw函数编写代码。
六、坐标系和映射模式
无论在平面上或是在空间内绘图,都离不开坐标系,VC++涉及两种坐标系:逻辑坐标系和设备坐标系及其相互之间的转换。
所谓坐标映射方
式就是指这两种坐标系在相互转换时,逻辑单位和设备单位之间存在的某种比例关系。
Windows映射模式就是在Windows方式下的屏幕坐标方式。
一个实际的物理屏幕是由像素组成的,通常所说的640×480,800×600,1024×768等分辨率指的就是物理屏幕的实际宽度和高度的像素数目。
1.逻辑坐标和设备坐标
如下面的画线代码:
pDC->MoveTo(100,200);
pDC->LineTo(500,200);
这里坐标(100,200)和(500,200)是逻辑坐标,而Windows系统自动使用默认的映射模式把坐标转换为屏幕上的(100像素,200像素),(500像素,200像素),后者就是设备坐标(这里设备是显示器)。
注意:逻辑坐标可以理解为不带单位的数值,当要在具体的设备上画图时,系统根据相应的映射射模式为这些数值加上单位(1像素、1毫米还是1英寸等等),加上单位后就变成了设备坐标。
设备环境中的所有绘图成员函数使用的都是
逻辑坐标。
因此,同样的代码在不同的映射模式下绘制出来的图形不一样。
Windows默认的映射模式是一个逻辑单位映射成为屏幕上的一个像素。
2.几种映射模式
Windows提供了几种映射模式(或称为坐标系),可以通过它们来和设备坐标相联系。
如下为Windows的8种映射模式:
Windows的8种映射模式
映射模式映
射
识
别
码逻辑单位X
轴
正
向
Y
轴
正
向
MM_TEXT 1 pixels 右下MM_LOMETRIC 2 0.1mm 右上MM_HIMETRIC 3 0.01mm 右上MM_LOENGLISH 4 0.01inch 右上MM_HIENGLISH 5 0.001inch 右上MM_TWIPS 6 1/1440inch 右上
MM_ISOTROPIC 7 可变(x等
于y)可
变
可
变
的的
MM_ANISOTROPIC 8 可变(x不
等于y)可
变
的
可
变
的
■MM_TEXT映射模式允许应用程序利用设备像素工作,因此用它来表示设备坐标系是再合适不过了。
屏幕(窗口)的原点约定在左上角,而X和Y方向向右向下方增长。
MM_TEXT是Windows默认的映射模式。
■MM_LOMETRIC,MM_HIMETRIC,MM_LOENGLISH,MM_HIENGLISH,MM_TWIPS被称为“固定比例”映射模式。
所有固定比例的映射模式的X值向右是递增的,Y值向下是递减的(即正常的笛卡儿坐标系)。
它们之间的区别就是在于设备坐标到逻辑坐标转换的实际比例因子不同。
MM_TWIPS映射模式常常用于打印机,一个“twip”单位相当于1/20磅(磅是一种度量单位,在Windows中1磅等于1/72英寸)。
■MM_ISOTROPIC和MM_ANISOTROPIC两种映射模式被称为“可
变比例”映射模式。
在这些模式下,用户可以改变它们的比例因子和坐标原点。
借助于这两种映射模式,当用户改变了窗口尺寸时,绘制的图形大小也会发生相应的变化;同样,如果改变某个轴的方向,那么所绘制的图形也会随着该轴的变化发生改变,并且还可以定义任意的比例因子。
在MM_ISOTROPIC模式下,X方向与Y方向上的比例因子总是相等的(即纵横比为1∶1);而在MM_ANISOTROPIC模式下,X方向与Y 方向上的比例因子可以不相等(即纵横比任意)。
3.设置映射模式
调用CDC类的成员函数SetMapMode可设置映射模式,函数的声明如下:
virtual int SetMapMode( int nMapMode );
nMapMode是映射模式,返回值是设备环境以前的映射模式。
举例如:TextMapMode:
当没有设置映射模式时,系统使用默认的映射模式MM_TEXT,一个逻辑坐标对应于一个屏幕像素。
七、绘图混和模式
绘图混和模式指定了画笔颜色和被填充物体
内部颜色是如何与显示平面的颜色相混合的。
绘图混合模式描述了两个变量的所有可能的布尔组合(操作符包括AND、OR和XOR)和单变量布尔操作(操作符为NOT)。
设置绘图混和模式使用成员函数SetROP2,函数的原型声明如下:
int CDC::SetROP2( int nDrawMode );
函数返回先前的绘图混和模式,参数nDrawMode指定新的绘图混和模式,其值如下所示:
绘图混和模式
参数值说明
R2_BLACK 像素总是黑的
R2_WHITE 像素总是白的
R2_NOP 像素颜色保持不变(像素
颜色=屏幕颜色)
R2_NOT 像素为屏幕颜色的反色
(像素颜色=NOT屏幕
颜色)
R2_COPYPEN 像素为画笔的颜色
(像素颜色=画笔颜色,
此参数为系统的默认设
置)
R2_NOTCOPYPEN 像素为画笔颜色的反色
(像素颜色=NOT画笔
颜色)
R2_MERGEPENNOT 像素颜色是画笔的颜色
和屏幕颜色的反色的组
合
(像素颜色=(NOT屏幕
颜色)OR画笔颜色)
R2_MASKPENNOT 像素颜色是画笔的颜色
和屏幕颜色的反色中共
有颜色的组合
(像素颜色=(NOT屏幕
颜色)AND画笔颜色)R2_MERGENOTPEN 像素颜色是屏幕颜色和
画笔颜色的反色的组合
(像素颜色=(NOT画笔
颜色)OR屏幕颜色)
R2_MASKNOTPEN 像素颜色是屏幕颜色和
画笔颜色的反色中共有
颜色的组合
(像素颜色=(NOT画笔
颜色)AND屏幕颜色)R2_MERGEPEN 像素颜色是屏幕颜色和
画笔颜色的组合
(像素颜色=画笔颜色
OR屏幕颜色)
R2_NOTMERGEPEN 像素颜色是屏幕颜色和
画笔颜色的组合颜色的
反色
(像素颜色=NOT(画笔
颜色OR屏幕颜色)
R2_MASKPEN 像素颜色是画笔颜色和
屏幕颜色中共有的颜色
的组合
(像素颜色=画笔颜色
AND屏幕颜色)
R2_NOTMASKPEN 像素颜色是画笔颜色和
屏幕颜色中共有的颜色
的组合颜色的反色
(像素颜色=NOT(画笔
颜色AND屏幕颜色)
R2_XORPEN 像素颜色既是属于画笔
颜色又属于屏幕颜色,但
并不是两种颜色的公部
分的组合颜色
(像素颜色=画笔颜色
XOR屏幕颜色)“XOR”
代表“异或”
R2_NOTXORPEN 像素颜色是既属于画笔
颜色又属于屏幕颜色,但
并不是两种颜色的公共
部分的组合颜色的反色
(像素颜色=NOT(画笔
“XOR”
颜色XOR颜色))
代表“异或”
绘图混和模式设置方法:
第1步:创建一个名位TestROP2的单文档程。
第2步:在工程的资源中添加一个菜单项(ID_TEST_ROP2)。
第3步:用ClassWizard在视图类中为新增加的菜单项添加消息处理函数。
第4步:在该函数中添加代码,设置绘图混合模式:
注意:由于绘图混和模式的作用,红色的画刷
变成了奇怪的黑绿色,并交替出现图形;去掉绘图混合模式,不出现交替情况。
可以通过成员函数GetROP2来获取当前设置环境的绘图混和模式,函数的完整定义如下:int CDC::GetROP2( ) const;
八、显示位图
显示位图,必须首先创建一个位图,然后把它选进设置环境中,使用完后再从设备环境中选出来,最后删除掉。
由于显示器的“位图”就是显示器的映像,因此不能直接选入,必须利用CDC的成员函数CreateCompatibleDC,为位图创建一个特殊的内存设备环境,然后利用CDC的BitBlt或者StretchBlt函数,把内存设备环境中的各个位复制到真正的设备环境中去。
1.从资源中加载位图
创建位图要分为两步进行,首先声明一个CBitmap的对象,然后使用LoadBitmap函数将位图资源加载到CBitmap对象中去。
因此,还得先准备好位图资源。
创建好位图对象以后,才能够将位图显示出来。
在应用程序的视图中显示一幅真彩色的位图,具体步骤如下:
第1步:创建一个TestBitmap单文档工程。
第2步:插入位图资源到TestBitmap工程中。
准备好将要插入的位图,可以任意找一幅位图,位图既可以是256色的,也可以是真彩色的,但超过256色的位图不能在资源编辑器中打开编辑。
将准备好的位图文件复制到当前工程目录(如:TestBitmap)下。
在工程Resource View中的任意一个资源项上单击鼠标右键,从弹出的右键菜单中选择Import 菜单项,此时就会弹出导入资源对话框,在文件类型中选择“所有文件“(*.*)”,在文件列表中选择刚刚复制进来的位图,然后单击对话框中的Import按钮,就可以将选中的位图文件导入到当前工程中。
如果文件超过256色,Visual C++6.0会弹出一个消息框,告知用户插入的资源不能被打开编辑。
在工程的Resource View中就多了一个Bitmap文件夹,下面有一项IDB_BITMAP1的位图资源。
第3步:加载位图资源到CBitmap类的对象
中。
声明一个CBitmap类的对象,然后使用其成员函数LoadBitmap将位图装入。
LoadBitmap 函数原型有两个:
BOOL LoadBitmap( LPCTSTR lpszResourceName );
BOOL LoadBitmap( UINT nIDResource );
函数从资源中载入一幅位图,若载入成功则返回TRUE。
参数可以是位图资源的ID,也可以是位图资源的名字。
第4步:创建一个视图窗口设备环境的兼容内存设备环境。
用CDC类的成员函数CreateCompatibleDC 创建一个与显示设备环境相兼容的内存设备环境对象。
CreateCompatibleDC的函数原型如下:virtual BOOL CreateCompatibleDC(CDC* pDC);
如果产生成功就返回TRUE。
第5步:用CDC::SelectObject函数将位图对象选入到创建的兼容内存设备环境中。
第6步:用CDC::BitBlt函数显示位图。
显示一个在资源中的位图可分为如下4步进。