《VC MFC 编程实例4.pdf》由会员分享,可在线阅读,更多相关《VC MFC 编程实例4.pdf(15页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、 本文由s d h e x u 贡献 p d f 1。下载 第4章 绘 图 在前面几章中,Wi n d o w s 为我们做了所有的绘图工作 从绘制一个窗口的非客户区到绘 制通用控件.本章将讨论怎样用 MFC的CDC类绘制控件和视图,我们将讨论:Wi n d o w s 和M F C支持的绘图工具类型.Wi n d o w s 和M F C支持的绘图模式和特性.两种存储为将来显示用的绘图命令的方法:元文件 怎样在抖动色(d i t h e r e d (Me t a f i l e)和路径(Pa t h).c o l o r)和未经抖动色(n o n d i t h e r e d c o l
2、 o r)中绘图.什么时候Wi n d o w s 绘制它的窗口.4.1 设备环境 若自己编写一个函数在屏幕上画一条直线,将需要以下类型的调用变量:直线坐标(起点x,线条颜色.线条粗细.y,终点x,y).若要使功能更复杂些,还必须添加:在(像素,英寸或厘米)中指定进行绘图的度量单位的能力.在打印机或一个图形文件中绘制直线的能力.为了方便,还希望将直线绘制在任何显示器或者任何打印机上,而不必考虑显示卡或打 印机的类型.如果考虑所有这些属性,该函数的结构如下:Dr a w Li n e (x 1,y 1,x 2,y 2,c o l o r,w i d t h,d e v i c e,l i m i
3、 t s,u n i t s)虽然相当直观,但该函数有一个隐含的费用 每当画一条直线,所有这些参数将必须压 入堆栈中.同时,该函数也没有保留扩展功能的余地.要添加变量,将必须对旧函数编辑任 何引用.因此,怎样才能减少需要的调用变量的数目并预留扩展空间呢?一种方法是写一个包含 函数所需的大多数变量的 C+类,并将该类作为一个变量进行传输.甚至可以使该类用一些 合法的默认值构造自己,以便在特殊场合中使用.Wi n d o w s使用一个称为设备环境(De v i c e Co n t e x t)的对象的方法 但该对象的创建没有 一个C+类,因为 Wi n d o w s 早于并存在于 C+之外.
4、设备环境对象用一些默认值创建,可以用 它们创建默认的设备环境.应用 Wi n d o w s 绘制一直线,所需的是一个设备环境对象的指针和 直线坐标,设备环境对象的指针叫做设备环境句柄(HDC).:Mo v e To(HDC h d c,i n t x,i n t y);:Li n e To(HDC h d c,i n t x,i n t y);要绘制一个完整的形状,:M o v e To()函数只被调用一次.然后,:L i n e To()函数被调用,没有一个多余的变量被压进堆栈(见图 4-1).52 第一部分 基 础 知 识 下载 使用设备环境以前 设备环境 使用设备环境以后 图4-1 设
5、备环境减少调用变量的数目并预留扩展空间 注意 因为设备环境在内存中创建,而内存经常受到扰动,它的地址可能是经常变化的.因此,一个设备环境句柄不是直接指向设备环境对象,而是指向另外一个跟踪设备环 境地址的指针.设备无关 设备环境是设备无关的,它允许你编写软件而不必指定一个设备.这些软件必须知道的 是:它是编写一个设备环境的,而不管该设备环境是屏幕还是 Ep s o n 打印机.之后,设备环境 可以被分配给一个打印机,屏幕,位图或一个文件.4.2 在MFC环境中创建一个设备环境 M F C用C D C类封装了一个设备环境对象,C D C的成员变量 m _ h d c 指向它所拥有的设备环 境,用户
6、可以创建四种类型的设备环境:屏幕.打印机.只有打印机的信息部分.位图.4.2.1 屏幕 创建一个屏幕设备环境,可以用:p a g e 1 CDC*p DC=Ge t DC();这里的Ge t DC()是C W n d 类的成员函数,它返回一个允许用户绘制它的窗口客户区的设备 环境;如果还希望绘制非客户区,则使用:CDC*p DC=Ge t Wi n d o w DC();如果需要绘制整个屏幕,如编写一个屏幕保护程序或游戏程序时,可能需要对整屏进行 绘制,这时使用:下载 CDC*p DC=CDC:Fr o m Ha n d l e (:Ge t DC(NULL);第4章 绘 图 53 屏幕设备环
7、境来自三种资源之一:私有设备环境,类设备环境和通用设备环境.1.私有设备环境 创建窗口时,私有设备环境便创建了,并在窗口存在期间一直存在.要使窗口创建一个 私有设备环境,必须在目标窗口的窗口类中设置 C S _ O W N D C标志,这时Ge t DC()返回一个私 有设备环境的指针,而不创建一个设备环境.在窗口存在期间,为私有设备环境所作的任何 变化都被保存.私有设备环境主要在以图形为中心的应用程序中使用,在那里经常地分配一 个设备环境,这样会占用非常多的 CPU时间.2.类设备环境 类设备环境在注册一个窗口类时创建,并在窗口类的存在期间一直存在.要使窗口类创 建它自己的类设备环境,必须设
8、置 C S _ C L A S S D C标志,Ge t DC()只返回指向该类设备环境的 指针.此外,在窗口类的存在期间,设备环境一直保留它的值.然而,在第 1章中已提及,必 须注意不要让两个由相同的窗口类创建的窗口在同一时间绘图;还应注意 M i c r o s o f t 认为一个 类设备环境是旧用法.3.通用设备环境 在一个通用资源堆中使用 Ge t DC()时,一个通用设备环境便创建了.要获得一个通用设 备环境,不要在窗口类中设置 CS_OWNDC或CS_CLASSDC.对于更早版本的 Wi nd o w s,操作 系统本身只有五个预分配的通用设备环境,因此取名 Ge t DC()与
9、Cr e a t e DC()相对应.必须保证在用完设备环境后释放它,否则系统将发生冲突并导致异常终止.虽然设备环 境是被创建的,但内存资源还是有限的,因此在使用一个通用设备环境后,仍需用下面语句 释放它:Re l e a s e DC(p DC);注意 私有设备环境和类设备环境不必释放.用户最有可能用通用设备环境来做绘图工作.每次释放一个通用设备环境时,为它们设 置的值都被丢失.但是,可以用下面两个 CDC成员函数保存和恢复一个设备环境的设置值:S a v e D C()保存设备环境的当前状态.Re s t o r e DC()将设备环境恢复到用 Sa v e DC()保存的状态.4.2.2
10、 打印机 要为打印机创建一个设备环境,必须先创建一个 C D C类对象,然后使用它的 Cr e a t e DC()成员函数:CDC d c;d c.Cr e a t e DC(LPCTSTR l p s z Dr i v e r Na m e,LPCTSTR l p s z De v i c e Na m e,LPCTSTR l p s z Ou t p u t,c o n s t v o i d*l p In i t Da t a)l p s z D r i v e r N a m e 是打印机所用的设备驱动程序(如H P D RV).l p s z D e v i c e N a m e
11、 是进行打印的打印机设备的名字 (如HP La s e r j e t III),设备驱动程 序可以支持多种类型设备.54 第一部分 基 础 知 识 下载 l p s z Ou t p u t 指定设备的串口名(如,PT1:).L l p In i t Da t a 是任何设备专用的初始化数据.使用打印机设备环境之后,必须用 C D C类的D e l e t e D C()成员函数销毁它.但是,若在堆 栈中创建CDC类,则程序返回时,设备环境自动被删除.CMy Cl a s s:Dr a w i n g()CDC d c;d c.Cr e a t e DC();/CDC o b j e c t
12、 a nd De v i c e Co n t e x t d e s t r o y e dp a g e 2 4.2.3 内存 要创建一个可以直接绘制位图的设备环境,必须先用 C D C的Cr e a te Co m p a t i b l e DC()成员 函数创建一个CDC类对象.CDC d c;d c.Cr e a t e Co m p a t i b l e DC(HDC h d c);Cr e a t e Co m p a t i b l e DC()用设备环境的设置值初始化它所创建的设备环境对象,因此,取 名兼容DC.应该从显示被创建的位图的设备(如屏幕,打印机)传递一个设备环
13、境.要真实地绘制一个位图,还必须创建一个空位图对象,并使该设备环境与该位图相关联.CDC d c;/c r e a t e CDC o b j e c t CBi t m a p b i t m a p;/c r e a t e CBi t m a p o b j e c t d c.Cr e a t e Co m p a t i b l e DC(p DC);/c r e a t e De v i c e Co n t e x t o b j e c t b i t m a p.Cr e a t eCo m p a t i b l e Bi t m a p(p DC,ICON_WIDTH,I
14、CON_HEIGHT);/c r e a t e Bi t m a p o b j e c t d c.Se l e c t Ob j e c t(&b i t m a p);/p o i n t m e m o r y De v i c e Co n t e x t /t o t h i s b i t m a p 绘制位图以后,必须用下列语句删除设备环境:d c.De l e t e DC();有关例子参见例 58.4.2.4 信息 CDC提供的最后一种设备环境类型是打印机的信息部分.CDC d c;d c.Cr e a t e IC();这里的调用变量与 Cr e a t e DC()中
15、一样.信息设备环境只包含一台打印机或其他非屏幕设备的特性,如颜色支持等.创建信息设 备环境的速度比创建一个常规的打印机设备环境速度快,因为它只包含设备的特性.信息使 用后应当删除,与前面描述的一样.注意 正如CWn d 类和它控制的窗口一样,CDC类可以用At t a c h()把自己捆绑到一个已 有的设备环境上,并可用 De t a c h()解开自己.创建一个封装已有的设备环境的临时 CDC对象,可以用Fr o m Ha n d l e().但是,当应用程序进入空闲循环时,这一临时类对 象将被删除.下载 4.3 绘图例程 第4章 绘 图 55 CDC类还在它的成员函数中封装了全部 Wi n
16、 d o w s 图形API,这些成员函数包括:画点的函数.画线的函数.画形状的函数.填充和翻转形状的函数.滚动屏幕的函数.绘制文本的函数.绘制位图和图标的函数.4.3.1 画点 像素点的绘制不过是改变单个像素点的颜色.Se t Pi x e l()Se t Pi x e l V()试图用指定的颜色画一个像素,返回绘制时使用的实际颜色 与上面的基本相同,但不用返回绘制时使用的实际颜色,因而速度更快 4.3.2 画线 画线即改变屏幕上一系列像素点的颜色.Mo v e To()Li n e To()Ar c()Ar c To()An g l e Ar c()Po l y Dr a w()Po l
17、y Li n e()Po l y Po l y Li n e()开始画线,弧和多边形时,把光标移动到一个初始位置 画一条从初始位置到另一个点的直线 画一段弧 画一段弧,并更新初始位置 画一条线,然后画一段弧,并更新初始位置 画一系列线段和 Be z i e r 样条 画一系列线段 画多个系列线条 4.3.3 画形状 这里的形状是一系列封闭线条.Re c t a n g l e()Ro u n d Re c t()Po l y g o n()Po l y Po l y g o n()El l i p s e()画一个矩形 画一个圆角矩形 画一个多边形 创建一个或多个多边形 画一个椭圆 Pi e(
18、)Dra w 3d Re c t()Dr a w Ed g e()Dr a w Fr a m e Co n t r o l()画一个饼状楔形 画一个三维矩形 画一个矩形的边缘 画一个框架控件 4.3.4 形状填充和翻转 填充和翻转改变一个形状内的所有像素点颜色.Fi l l Re c t()In v e r t Re c t()填充一个矩形 反转一个矩形的颜色 Fi l l So l i d Rec t()Ex t Fl o o d Fi l l()用用一单色填充一个矩形 用用当前画刷填充一个区域,提供比 Fl o o d Fi l l()成员函数更 多的灵活性 Fr a m e Re c t
19、()画一个矩形的边框 56p a g e 3 Fi l l Rg n()第一部分 基 础 知 识 下载 下面三个函数包括一个区域对象,它实际上是一个线条列表,形成一个由设备环境维护 的形状.有关区域的详细讨论参见 4.4.8节剪裁属性.填充一个区域 画一个特定区域的边框 In v e r t Rg n()反转一个区域的颜色 Fr a m e Rg n()4.3.5 滚动 通过滚动,可移动屏幕周围像素颜色.Sc r o l l DC()4.3.6 绘制文本 我们可能会认为文本是打印的,不是画的;但在一个图形用户界面中,甚至一个文本字 符都是由像素构成的一幅图.Te x t Ou t()Ex t
20、Te x t Ou t()Ta b b e d Te x t Ou t()Dr a w Te x t()在在一个指定的位置,输出一个字符串 在在一个矩形区域里输出一个字符串 在基于用该函数传输的一个表,在指定位置输出一个字符串,并将字符串中的 任何制表符转换为空格 在在指定的矩形域里绘制文本,但比 Te x t Ou t()有更多的选项,如把文本居中和 显示多行文本 左,右,上,下移动屏幕图像.4.3.7 绘制位图和图标 一个位图或图标只是大量像素的颜色阵列.通常有一个标题,用来指示在一行中有多少 像素点,以便一个画图例程知道什么时候开始下一行.通常,位图绘制例程只是把像素阵列 拷贝到视频内存
21、中.图标具有透明色这一附加的能力,换句话说,当一个图标被绘制在屏幕 上时,它的每一点的颜色都可被屏幕上原有的颜色代替.Dr a w Ic o n()Bi t Bl t()St r e t c h Bl t()Pa t Bl t()在在指定的位置画一个图标 在从指定的设备环境中拷贝一个位图,通常是从磁盘中装入或在内存中创建,如 前面所述 在与Bi t Bl t()基本相同,但它试图伸展或压缩一个位图以适应目标 在创建一个位模式 有关绘图的例子参见第 11章.4.4 绘图属性 前面所讨论的所有函数都使用设备环境对象来简化它们的调用变量;因为所有的绘图函 数只有一个设备环境,因此,每个函数可能只使用
22、存储在设备环境中 20%的属性.一个设备环境既可以自身包含一种特定的绘图属性,也可以指向另一个包含某种特定属 性的对象.例如,画一条线的属性(如宽度或颜色)可存储在一个单独的 P e n 对象中,而由设备 环境指向该对象.有关设备环境指向的其他对象,以及封装它们的 MFC类(见图4-2).创建这些附加的图形对象,与创建一个窗口对象的方法一样,先创建 M F C类对象,然后 下载 第4章 绘 图 57 调用那个类的成员函数 Cr e a t e().附加的图形对象一旦被创建,需要告诉设备环境运用 Se l e c t Ob j e c t()使用该新对象,Se l e c t Ob j e c
23、t()只是把设备环境指向新的图形对象.CDC 类 CPe n 类 画笔 对象 字体 对象 设备环境对象 画刷 对象 区域 对象 CBr u s h 类 CRg n 类 CFo n t 类 CPa l e t t e 类 调色板 对象 位图 对象 CBi t m a p 类 图4-2 一个设备环境可以指向包含附加绘图属性的辅助设备环境对象p a g e 4 CPe n p e n;p e n.Cr e a t e Pe n();CPe n *p Ol d Pe n=d c.Se l e c t Ob j e c t(&p e n);/p o i n t s t h e DC t o y o u
24、r n e w o b j e c t /r e t u r n s a p o i n t e r t o o l d p e n o b j e c t /c r e a t e MFC o b j e c t /c r e a t e Pe n o b j e c t 虽然设备环境指向五个不同的图形对象,但只使用一个 Se l e c t Ob j e c t().设备环境基于对 象本身的一个特征字决定替换哪个指针.用新对象绘图后,必须从内存中删除该对象.因为设备环境仍指向该对象,所以,必须 先把它指向另一个对象 通常是原先的对象.d c.Se l e c t Ob j e c t(p
25、Ol d Pe n);p e n.De l e t e Ob j e c t();/s e l e c t a n o t h e r o b j e ct /d e l e t e s Pe n o b j e c t (r e t u r n i n g /d e s t r o y s t h e CPe n o b j e c t)4.4.1 设备环境属性 下面的绘图属性可以在设备环境和它的辅助对象中找到:画线属性 文本属性 映像属性 控制画线函数怎样画线(如颜色和粗细).这些属性的大部分包含在 Pe n 对象中.控制文本是怎样绘制的.字体属性保存在 F o n t 对象中,颜色和对齐
26、方式(如左 控制x,y 坐标在绘图操作中表示什么.换句话说,坐标是以像素还是以英寸为 填充属性 控制绘制形状的函数怎样填充形状.这些属性的大多数保存在 Br u s h 对象中.或中央)保存在设备环境中.单位的,以及应采取哪一种方式.没有附加映像对象,因为所有信息都保存在设备环境本身中.调色板属性 可以用来控制线条和形状的颜色.图形应用程序,尤其那些视频内存有限的 系统,用调色板控制颜色.所有调色板属性保存在 Pa l e t t e 对象中.混合属性 控制线条怎样与背景互相作用.例如,是只想覆盖背景色,还是想与背景色进 行XOR操作,以便以后可以用重画该线来删除它呢?剪裁属性 创建一个区域,
27、不能在该区域外绘图.这些属性保存在 Re g i o n 对象中.58 第一部分 基 础 知 识 下载 位图属性 包含在位图绘制函数中使用的位图.4.4.2 画线属性 画线属性控制怎样画线条.设备环境用一个包含大多数画线属性的 H P E N句柄指向一个 Pe n 对象.在MFC中创建一个 Pe n 对象,必须先创建一个 CPe n 类对象,然后,调用 CPe n 的两个 成员函数之一.Cr e a t e Pe n()Cr e a t e Pe n In d i r e c t()用用指定的颜色,宽度和模式创建一个 Pe n 对象,模式可以是从实线到虚线的任何 一种,由用户指定长线和空格的长
28、度 用用LPLOGPEN结构创建一个 Pe n 对象 不必创建用户自己的 P e n 对象,有一些预定义的 P e n 对象可用,可以用 S e l e c t S t o c k O b j e c t ()直接把它们选进设备环境中.可以用下面这些标志识别选择了哪一个存储对象.BLACK_PEN WHITE_PEN NULL_PEN 用包含黑画笔的属性 用包含白画笔的属性 用使绘图函数不能画线,例如:用一个矩形画一条线,然后填充该矩形.选择该 Pe n 对象将不能画线.4.4.3 形状填充属性 B r u s h 对象控制怎样填充形状.设备环境用一个 H B R U S H句柄指向一个画刷对
29、象.若用 M F C创建一个 B r u s h 对象,首先要创建一个 C B r u s h 类对象,然后调用下面 C B r u s h 的六个成员 函数之一:Cr e a t e So l i d Br u s h()Cr e a t e Ha t c h Br u s h()Cr e a t e Br u s h In d i r e c t()Cr e a t ePa t t e r n Br u s h()Cr e a t e DIBPa t t e r n Br u s h()Cr e a t e Sy s Co l o r Br u s h()创建一个单色 Br u s h 对
30、象 创建一个指定阴影模式和颜色的画刷 用LOGBRUSH结构中的设置值创建 CBr u s h 对象 创建一个用位图指定模式的 Br u s h 对象 创建一个用设备无关位图指定模式的 CBr u s h 对象 创建一个具有默认系统颜色的 Br u s h 对象 若不想创建用户自己的 B r u s h 对象,系统有一些预定义的对象可以使用.可以用 S e l e c t St o c k Ob j e c t()和相应的标志值,直接把这些预定义对象选进设备环境.BLACK_BRUSH WHITE_BRUSH DKGRAY_BRUSH GRAY_BRUSH LTGRAY_BRUSH NULL_
31、BRUSH 或HOLLOW_BRUSH 标标识Br u s h 对象,包含用黑色填充一个形状所需的属性 标包含用白色填充形状的属性 标包含用深灰色填充形状的属性 标包含用灰色填充形状的属性 标包含用浅灰色填充形状的属性 标使绘图函数不能对形状进行填充,例如,用一个矩形绘制一条线,然后填充矩形.选择该 Br u s h 对象将导致不能填充矩形p a g e 5 4.4.4 文本绘制属性 文本属性控制怎样绘制文本.有三种类型的文本属性:颜色,对齐方式和字体.1.文本颜色 下载 两个成员函数为绘制文本设定前景色和背景色.Se t Te x t Co l o r()Se t Bk Co l o r()
32、设定前景色(即文本色)设置输出文本处的背景色.第4章 绘 图 59 2.文本对齐方式 对齐方式属性决定文本怎样排列(如:左对齐,右对齐,中央对齐).确切地说,Te x t Ou t()函数中的 x,y 变量可以表示文本的左边,右边或者底部.使用默认的对齐方式,x,y 代表文 本的左上角,但还有其他一些方式.要改变设备环境的文本对齐属性,可以用 Se t Te x t Al i g n()函数和下面的标志值之一:TA_LEFT TA _ TO P TA_RIGHT TA_CENTER TA_BASELINE TA_BOTTOM 儿Te x t Ou t()中的x 变量表示文本的左边.TA_LEF
33、T是默认设置值 儿Te x t Ou t()中的y 变量表示文本的顶部.TA _ TO P是默认设置值 儿Te x t Ou t()中的y 变量表示文本的右边.计算文本的边界矩形,用以决 定从哪儿开始绘制文本 儿Te x t Ou t()中的y 变量表示文本的中部 儿Te x t Ou t()中的y 变量表示文本的基线 儿Te x t Ou t()中的y 变量指示文本的底部 注意这些属性可以合在一起使用.例如,TA_CENTER和TA_BOTTOM表示x,y 指向文本 串的中部和底部.3.文本字体 字体属性包括字体类型,大小和文本外观的其他方面.这些属性不是定义一个可以使用 的字体,而是告诉系
34、统需要使用什么类型的字体.然后系统在它可用字体列表中搜索与指定 属性最匹配的字体并使用它.字体属性包括在 F o n t 对象中,设备环境用 H F O N T句柄指向该对象.若用 M F C创建一个 Fo n t 对象,首先创建一个 CFo n t 类对象,然后调用下面 CFo n t 的四个成员函数之一:Cr e a t e Fo n t()Cr e a t e Fo n t In d i r e c t()Cr e a t e Po i n t Fo n t()Cr e a t e Po i n t Fo nt In d i r e c t()儿创建一个字体对象,并指定一些需要的特性,包
35、括点大小,粗细(正常 或粗体),斜体或非斜体 儿基本与上面相同,但使用 LOGFONT结构 儿Cr e a t e Fo n t()的简化版 只需指定点大小和字体 儿Cr e a t e Fo n t In d i r e c t()的简化版 只需指定点大小和字体 若不想创建自己的 Fo n t 对象,则有一些预定义的对象可用,可以用 Se l e c t St o c kOb j e c t()直 接把它们选进设备环境.通过选择这些标志值,指定选择哪个存储对象.SYSTEM_FONT SYSTEM_FIXED_FONT ANSI_FIXED_FONT ANSI_VAR_FONT DEVICE
36、_DEFAULT_FONT OEM_FIXED_FONT 这这是Wi n d o w s 在窗口中绘制菜单,任务栏等时使用的默认字体 这Wi n d o w s 在3.0版以前使用的默认字体 这字体是非成比例间隔的 C o u r i e r (每个字符在行中占据相同的空间).特 殊字符集(除A-Z外的字符)是ANSI标准 这字体是均匀成比例间隔的 MS Sa n s Se r i f(字母I在一条线上占据的空间 比W少).特殊字符集是 ANSI标准 这设备优先选取的字体 这基本与ANSI_FIXED_FONT相同,但其特殊字符集是 OEM-s p e c i f i c 4.4.5 映像模式
37、 Wi n d o w s 有一些映像模式允许用户以像素,英寸或毫米为单位进行绘制.然而,对于大 60 第一部分 基 础 知 识 下载 x 和y 为像素值.多数应用程序,永远也不必考虑映像模式.默认模式以像素为单位,这时的 1.逻辑单位与设备单位的比较 但是,若确实需要 x 和y 为英寸值,则必须要注意逻辑单位和设备单位之间的不同.逻辑单位是传递给绘图函数的 x 和y 值,它们可以表示英寸或毫米;而设备单位是 x 和y 值 在屏幕上的像素数,或者是在打印机上的点阵数.鼠标单击以设备单位返回.如果想知道用 户单击在位图上的什么位置,需要将设备单位转换为逻辑单位.当以逻辑单位方式工作时,是工作在逻
38、辑坐标系统中;而以设备单位方式工作时,则是设备坐标系统(p a g e 6也称为物理坐标系 统或客户坐标系统).映像模式用 Se t Ma p Mo d e()存储在设备环境中,可以使用下面的标志值:MM_TEXT MM_HIENGLISH MM_LOENGLISH MM_HIMETRIC MM_LOMETRIC MM_TWIPS 这这是默认的映像模式,x 和y 值等于一个屏幕像素或打印机点阵.在屏幕或打印页 中,正的y 值向下递减 这X和y 值相当于屏幕上或打印页上的 1/1000i n,Wi n d o w s 决定当前屏幕设备的多少 个像素等同于 1/1000i n.在屏幕或打印页中,正
39、的 y 值向上递增 这X和y 值相当于设备上的 1/1000i n,并且y 值向上递增 这X和y 值相当于设备上的 1/100m m,并且y 值向上递增 这X和y 值相当于设备上的 1/10m m,并且y 值向上递增 这X和y 值相当于设备上的 1/1 4 4 0 i n,并且y 值向上递增这通常在文本绘制中使用,一个缇(t w i p)单位相当于 1/20点 另有两个映像模式允许设置多少个逻辑单位相当于一个设备单位:M M _ A N I S O T R O P I C 和M M _ I S O T R O P I C.I s o t r o p i c 模式(各向同性模式)确定x 方向的一
40、个单位等同于 y 方向的一个 单位,而An i s o t r o p i c 模式(各向异性模式)则不同.根据自己的习惯定义两个矩形,设置从逻辑环境到设备环境的 Wi n d o w s 转换.第一个矩 形以逻辑单位表示进行绘制的范围大小;第二个矩形以设备单位(即像素)表示第一个矩形范围 代表的设备范围大小.根据 Wi n d o w 用语,第一个矩形称为窗口,而第二个矩形称为视口(见 图4-3).逻辑环境 设备环境 把窗口的初始位置设置在想 在逻辑环境中看到的地 方;s e t Wi n d o w Or g(100,100);设置视口到视图的客户区,并可 设置窗口范围,使它成为想在逻辑
41、环境中看到的大小.Se t Wi n d o w Ex t 忘记它.Se t Vi e w p o r t Or g(0,0);(300100,200100);Se tVi e w p o r t Ex t(100,50)要缩小图形,只要缩小窗口的范围.要 扫视图形,只要增大窗口范围.要滚动 图形,只要改变窗口的初始位置 图4-3 设置窗口和视口矩形定义窗口怎样从逻辑环境转换到设备环境 下载 要设置窗口和视口矩形,使用下面这些 CDC的成员函数:Se t Wi n d o w Or g()Se t Wi n d o w Ex t()Se t Vi e w p o r t Or g()Se t
42、Vi e w p o r t Ex t()第4章 绘 图 61 设置表示逻辑环境的矩形的左上角值 设置表示逻辑环境的矩形的大小 设置表示设备环境的矩形的左上角值 设置表示设备环境的矩形的大小 注意 如果用各向同性映像模式,则在设置视口值前必须设置窗口值.2.翻转(In v e r t i n g),缩放(Zo o m i n g)和平移(Pa n n i n g)一旦工作在各向异性模式或各向同性模式,便可以获得一些强烈的图形效果.翻转 只要通过翻转视口值就可以翻转在屏幕上绘制的图像(见图4-4).p DC-Se t Wi n d o w Or g(0,0);/0,0 i n l o g i c
43、 a l w o r l d e q u a l s p DC-Se t Vi e w p or t Or g(0,480);/0,480 i n d e v i c e w o r l d p DC-Se t Vi e w p o r t Ex t(640,480);/t he m a x i m u m i n t h e /d e v i c e w o r l d p DC-Se t Wi n d o w Ex t(640,-480);/e q u a l s t hi s m a x i m u m /i n t h e l o g i c a l CMy Bu t t o n 可能
44、有一个处理 该消息的函数.如果没有,CMy Di a l o g 返回它 如果 CMy Di a l o g 也不 处理它,则最后由对 话窗口进程处理 CMy Bu t t o n 类对象 CMy Di a l o g 类对象 用户创建一个 CMy Bu t t o n 类和一个 CMy Di a l o g 类,以及它们的窗口对 象,并使按钮控件成为对话窗口的 一个子窗口 CMy Di a l o g 用子分类截获该消 息,查明它是一个控件通知,进而把它发送到控制该窗口的 MFC类,即CMy Bu t t o n 按钮窗口 进程 对话窗口 进程 按钮窗口进程发送一个 控件通知到它的父窗 口,
45、如BN_CLICKEDp a g e 7 图4-4 通过翻转视口值,翻转屏幕上的图像 缩放 只要通过变大或变小视口值就可以放大或缩小一个图像.使用 C D C:S c a l e Vi e -w p o r t Ex t()进行百分比放大.平移 初始绘制的整幅图像可能不适应屏幕,这时,可以在逻辑环境里创建整幅图像,但 在设备环境里只有部分可见.只要通过移动视口矩形就可以移动图像在屏幕上的可视部分.62 注意 第一部分 基 础 知 识 下载 使用CDC:Of f s e t Vi e w p o r t Or g()进行帮助.可以用Se t Vi e w p o r t Or g()和Se t
46、Win d o w Or g()在任何绘图模式下进行平移,但是,Se t Vi e w p o r t Ex t()和Se t Wi n d o w Ex t()是为各向同性和各向异性模式预留的.3.转换 CDC类还提供了两个从一个环境向另一个环境转换的函数.DPt o LP()LPt o DP()将设备单位转换为逻辑单位 将逻辑单位转换为设备单位 4.对话框单位与像素 对话框单位是有关映像模式的边缘主题,在用对话框编辑器创建的对话模板中,布满了 以对话框单位表示的大小和坐标,对应于像素的大小和座标.对话框单位允许一个对话框模 板按比例调整自己以适应不同的字型和字体大小.要把对话框单位转换到像
47、素单位,可以用 下面的CDi a l o g 成员函数:Ma p Di a l o g Re c t(LPRECT&r e c t);这里的r e c t 包含一个对话框单位集,以及为该对话框实例将那些对话框单位转换到像素的 函数.如果不能事先创建一个对话框实例,可以用 CDi a l o g Te m p l a t e 类的一个静态函数.s t a t i c v o i d CDi a l o g Te m p l a t e:Co n v e r t Di a l o g Un i t s To Pi x e l s(LPCSTR t y p e f ac e,i n t p o i
48、n t,i n t x,i n t y,SIZE*p Si z e)t y p e f a c e 和p o i n t 是对话框当前默认的字形和字体大小,x 和y 以对话框单位表示,函数返回 的像素值放在p Si z e 中.4.4.6 调色板属性 调色板属性维护应用程序要求的颜色,以便在应用程序运行时把这些颜色装载到系统的 调色板中.对于大多数应用程序,将使用应用程序的调色板,因为只需使用少数由系统提供 的颜色;然而在一些以图形为主的应用程序中,要求使用大量不同的纯色,这时,有必要考 虑一块最多能支持 256色的显卡能否满足要求.调色板属性包含在 P a l e t t e 对象中,设备环
49、境使用一个 H PA L L E T E句柄指向该对象.使用 MFC创建一个Pa l e t t e 对象,首先创建一个 CPa l e t t e 类对象,然后调用 Cr e a t e Pa l e t t e()成员函数.若不想创建自己的 Pa l e t t e 对象,可以使用下面的函数直接将一个预定义的 Pa l e t t e 对象选到 设备环境中.Se l e c t St o c k Ob j e c t(DEFAULT_PALETTE).这是默认的调色板,用它初始化一个新的设备环境.该调色板的目的不是提供一个新的 颜色集,而是把颜色调色板重置为初始设置.有关调色板的详细内容,
50、参见 4.6节颜色和调色板.4.4.7 混合属性 混合属性控制绘制的线条或文本怎样与它们的背景进行相互作用.对于大多数应用程序,永远不必考虑与背景的作用,默认的混合模式只是覆盖背景上的内容.然而,对于一些需要 下载 响.第4章 绘 图 63 在一幅图像上面绘制另一幅图像的应用程序,则有必要考虑每个增加的图像对原图像有何影 设备环境包含了混合所需的所有属性,不要求另外的对象.用户可以在以下两个方面改 变混合的属性:线条怎样与它们的背景色进行混合.在绘制文本时,是否使用文本背景色.p a g e 8 注意 也能改变一个位图与它的背景进行混合的属性.然而,该属性包含在它自己的绘 图函数中,而不是在设