用CmetaFileDC保存绘图时不支持Poly3dmax bezierr吗

君,已阅读到文档的结尾了呢~~
Vc中画图VC中,vc8,vc吧
扫扫二维码,随身浏览文档
手机或平板扫扫即可继续访问
举报该文档为侵权文档。
举报该文档含有违规或不良信息。
反馈该文档无法正常浏览。
举报该文档为重复文档。
推荐理由:
将文档分享至:
分享完整地址
文档地址:
粘贴到BBS或博客
flash地址:
支持嵌入FLASH地址的网站使用
html代码:
&embed src='/DocinViewer-4.swf' width='100%' height='600' type=application/x-shockwave-flash ALLOWFULLSCREEN='true' ALLOWSCRIPTACCESS='always'&&/embed&
450px*300px480px*400px650px*490px
支持嵌入HTML代码的网站使用
您的内容已经提交成功
您所提交的内容需要审核后才能发布,请您等待!
3秒自动关闭窗口MFC Window程序设计(第二版)精华浓缩笔记(二) - 王朝网络 -
分享&&&&&当前位置: &&&&&&&&MFC Window程序设计(第二版)精华浓缩笔记(二)&&&  各位,看一看,瞧一瞧,新出炉的...大拍卖喽!  第二章、在窗口中画图  精华浓缩:  
Windows中负责图形输出的是GDI(即Graphic Device Interface,图形设备接口)。这是Windows与硬件无关的图形输出模式的体现。GDI建立在硬件抽象层(HAL)之上,屏蔽了不同输出设备之间的差异,从而为用户提供了一个统一的“标准输出设备”。但是,与DOS不同,Windows是多任务、进程独立的,每一个窗口都应该有一个独立的输出通道。这样,GDI又使用了一种简单的机制来保证在窗口中画图的不同程序之间能共享“设备”而又互不干扰。这个机制就是DC(Device Context,设备描述表)。  
有人把DC比喻成画家的画室,这里有画布、画刷、画笔等等很多工具。  
就画布而言,画布形式可以不同,是的,我可以在桌上(desktop)的纸上(window)画,也可以就画在桌面上,还可以画在墙上(管的着吗!^_^)。  
为此,Windows MFC提供了四种不同的DC环境(封装为C++类),以标明不同的绘制权限,即:  
CPaintDC, 用于在窗口客户区画图(仅限于在OnPaint处理函数中使用);  
CClientDC, 也用于在窗口客户区画图(限于在OnPaint处理函数之外使用);  
CWindowDC, 用于在窗口内任意地方画图,包括非客户区;  
CMetaFileDC, 用于绘制GDI图元文件。  
这些类都可以直接实例化,如:  
CPaintDC dc(this);//this表示此DC所属窗口为当前窗口  创建了一个CPaintDC对象dc。  
CWindowDC一般不常用,如果想在窗口非客户区画图,可借助OnNcPaint()处理函数捕获WM_NCPAINT消息。  
刚才说了,DC中还有画刷、画笔等。这些都是DC的属性,可通过DC自身(调用其成员函数)获得。  
DC属性包括文本颜色、背景颜色、映射模式、绘图模式、当前位置、当前画笔(刷)和当前字体等。  
画笔(Pen)、画刷(Brush)都是独立的GDI对象,可通过CDC成员函数SelectObject()选入DC。同样操作方式的对象还有字体(Font)、位图(Bitmap)、调色板(Palette)和区域(Region)。  
关于SelectObject():在创建好GDI对象之后,SelectObject()接收该对象指针,其返回值为先前选入DC的相同类型的对象指针(通常用来恢复DC用)。  
Windows也预先定义了一些画笔、画刷、字体以及其他一些GDI对象。这些对象称为备用对象,用CGdiObject::SelectStockObject()选入。CGdiObject是表示GDI对象的CPen、CFont等类的基类。备用对象的属性说明可以查MSDN。  
由CGdiObject派生类创建的画笔、画刷和其他对象都要占用内存资源,因此使用后一定要删除它们。处理方法与其他window对象类似。在栈中创建的对象,当此CGdiObject超出范围时会自动析构。在堆中用new创建的CGdiObject对象,可通过调用CGdiObject::DeleteObject显式删除(这会引起对GDI对象析构函数的调用)或用相应的delete运算符。如果是备用对象,则没必要专门删除,留给windows就可以了。  
VC++有一种简单的方法用来确定是否成功的删除了GDI对象:只要在调试状态下运行应用程序的调试版本即可。在应用程序结束时,没有释放的资源会显示在调试窗口中。  
  一些知识点:  1.绘图模式:GDI将象素点输出到逻辑显示平面上时,并不只是简单的输出象素颜色,而是通过一系列布尔运算将输出象素点的颜色和输出目标位置上象素点的颜色进行合成再显示。所使用的逻辑运算关系就由DC的绘图模式确定。使用CDC:SetROP2()可更改绘图模式(ROP2,Raster Operation To)。默认绘图模式是R2_COPYPEN,直接将象素点输出到显示平面上。常用的还有R2_NOT,用于实现鼠标绘图时的Rubber技术。  2.映射模式:这是DC的属性之一,用于确定从逻辑坐标到设备坐标的转换(或者说mapping,映射)方式。设备坐标是指窗口中相应的象素点位置。单位只有象素一种。而逻辑坐标依映射模式不同而单位各异。如默认的MM_TEXT模式下,一个单位恰恰是一个象素点。MM_LOENGLISH模式下,一个单位则相当于百分之一英寸长。windows支持8种映射模式,其中的MM_ISOTROPIC和MM_ANISOTROPIC是可编程的。这意味着是用户而不是windows确定从逻辑坐标到设备坐标的转换方式。换句话说,就是用户来自行定制逻辑单位的实际大小。这两种模式最常用于根据窗口尺寸按比例自动调节画图输出大小的场合。两者之间的唯一区别在于:前者中X方向和Y方向具有同一缩放比例因子。设置映射模式的函数是CDC::SetMapMode()。  3.坐标系常用技术:  1)坐标变换:调用CDC::LPtoDP可将逻辑坐标值转换为设备坐标值。反之,调用CDC::DPtoLP可将设备坐标值转换为逻辑坐标值。在相应鼠标单击区域命中测试时,将使用这两个函数。因为鼠标单击得到的是设备坐标,而很多GDI函数使用逻辑坐标,必须转换为统一坐标,操作才有意义。  2)原点移动:默认方式下,DC的原点位于相应显示平面的左上角。MFC提供了两个CDC类成员函数,可改变原点位置。CDC::SetWindowOrg()移动窗口原点,CDC::SetViewportOrg()移动视图原点(详见MSDN)。一般只能使用两者之一。原点移动技术在边框滚动条设置时有所体现。  3)用户坐标与屏幕坐标:前者是设立在窗口客户区左上角的设备坐标值,后者是原点位于屏幕左上角的设备坐标值。两者的相互转换用函数是CWnd::ClientToScreen()和CWnd::ScreenToClient()。  4.GDI绘图函数  1)画线:包括MoveTo、LineTo、Polyline、PolylineTo、Arc、ArcTo、PolyBezier等。其中Polyline和PolylineTo都可以一次画多条线,两者的区别是PolylineTo使用DC的当前位置,而Polyline则不需要。ArcTo在win98下未实现。另外,所有GDI画线函数有一个共同特点,就是从不画最后一个象素点。  2)画图形:画封闭图形的GDI函数以外接矩形的坐标为参数。常用函数有Rectangle、Ellipse、RoundRect、Pie、Chord等。  5.画笔与画刷:在MFC中,画笔对象封装为CPen类,画刷对象封装为CBrush类。创建两者都有三种方法。最简单的就是构造一个CPen对象,直接给出所用参数进行初始化。第二种方法是调用一个未初始化的CPen对象,用CreatePen()初始化。还有一种方法是构造一个未初始化的CPen对象,通过向LOGPEN结构中填充描述画笔特性的参数,然后调用CPen::CreatePenIndirect()生成画笔。画刷基本相同。  1)CPen:windows用当前选入DC的画笔绘制线条,并给封闭图形镶制边框。画笔有三个特性,即样式、宽度和颜色。样式有PS_SOLID、PS_INSIDEFRAME、PS_NULL等。PS_NULL一般称其为“NULL画笔”,想画一个没有边框的图形,就用到它了。笔宽以逻辑单位给出,实际意义与当前映射模式相同。颜色是通过RGB宏把三个独立颜色成分的值合成为一个可传递给GDI的COLORREF值来确定的。  2)CBrush:画刷有三种基本类型,即单色、带阴影线和带图案。其中图案画刷允许用位图填充图形内部(这样,窗口背景也就没啥新鲜的了)。常用函数有  CDC::SetBkMode()、CDC::SetBkColor()等。  6.文本与字体:CDC有一打文本处理函数,重要的几个是DrawText、TextOut、GetTextMetrics、SetTextColor和SetTextAlign等。其中GetTextMetrics()传给TEXTMETRIC结构关于字体性质的相关信息。字体是一组具有特定尺寸(高度)和字样的字符;字样指示字体共有属性,如粗细等。字体封装在CFont类中,建立字体对象,要在CFont构造之后,再调用CFont的成员函数CreateFont或CreateFontIndirect等来建立GDI字体资源。针对字体,有一个LOGFONT结构,其中定义了字体的所有特性。也可通过填充它来创建字体。  后记:写这一章的笔记时有一种被作者牵着鼻子走的感觉。知识点太多,写出来有一种罗列或拼凑的嫌疑。我不希望这样,但想一想,技术也就是这样。所以我希望大家看的时候,能够思考着看,而不是记忆着看。思考着看只要求我们知道技术点、怎么用,用熟了,用多了,也就记住了。精华是浓缩的,至于如何把它化开,可要靠你自己了。&&&&&今日推荐
&&&&&老钟家的两个儿子很特别,就是跟其他的人不太一样,魔一般的执着。兄弟俩都到了要结婚的年龄了,不管自家老爹怎么磨破嘴皮子,兄弟俩说不娶就不娶,老父母为兄弟两操碎了心...把牛仔裤磨出有线的破洞
1、具体工具就是磨脚石,下面垫一个硬物,然后用磨脚石一直磨一直磨,到把那块磨薄了,用手撕开就好了。出来的洞啊很自然的。需要猫须的话调几...先来看下敬业福和爱国福
今年春节,支付宝再次推出了“五福红包”活动,表示要“把欠大家的敬业福都还给大家”。
今天该活动正式启动,和去年一样,需要收集“五福”...有时候我们打开冰箱就会闻到一股异味,冰箱里的这种异味是因为一些物质发出的气味的混合体,闻起来让人恶心。 产生这些异味的主要原因有以下几点。
1、很多人有这种习...简介
《极品家丁》讲述了现代白领林晚荣无意回到古代金陵,并追随萧二小姐化名“林三”进入萧府,不料却阴差阳错上演了一出低级家丁拼搏上位的“林三升职记”。...你就是我最爱的宝宝 - 李溪芮
(电视剧《极品家丁》片尾曲)
作词:常馨内
作曲:常馨内
你的眉 又鬼马的挑
你的嘴 又坏坏的笑
上一秒吵闹 下...乌梅,又称春梅,中医认为,乌梅味酸,性温,无毒,具有安心、除热、下气、祛痰、止渴调中、杀虫的功效,治肢体痛、肺痨病。乌梅泡水喝能治伤寒烦热、止吐泻,与干姜一起制...什么是脂肪粒
在我们的脸上总会长一个个像脂肪的小颗粒,弄也弄不掉,而且颜色还是白白的。它既不是粉刺也不是其他的任何痘痘,它就是脂肪粒。
脂肪粒虽然也是由油脂...来源:中国青年报
新的攻击方法不断涌现,黑客几乎永远占据网络攻击的上风,我们不可能通过技术手段杜绝网络攻击。国家安全保障的主要方向是打击犯罪,而不是处置和惩罚...夫妻网络直播“造人”爆红
  1月9日,温岭城北派出所接到南京警方的协查通告,他们近期打掉了一个涉黄直播APP平台。而根据掌握的线索,其中有一对涉案的夫妻主播...如何防止墙纸老化?
(1)选择透气性好的墙纸
市场上墙纸的材质分无纺布的、木纤维的、PVC的、玻璃纤维基材的、布面的等,相对而言,PVC材质的墙纸最不透气...观点一:破日本销售量的“鲜肌之谜” 非日本生产
近一段时间,淘宝上架了一款名为“鲜肌之谜的” 鲑鱼卵巢美容液,号称是最近日本的一款推出的全新护肤品,产品本身所...系腰裙(北宋词人 张先)
惜霜蟾照夜云天,朦胧影、画勾阑。人情纵似长情月,算一年年。又能得、几番圆。
欲寄西江题叶字,流不到、五亭前。东池始有荷新绿,尚小如...关于女人的经典语句1、【做一个独立的女人】
思想独立:有主见、有自己的人生观、价值观。有上进心,永远不放弃自己的理想,做一份自己喜爱的事业,拥有快乐和成就...你想体验机器人性爱吗?你想和性爱机器人结婚吗?如果你想,机器人有拒绝你的权利吗?
近日,第二届“国际人类-机器人性爱研讨会”大会在伦敦金史密斯大学落下帷幕。而...10.土耳其地下洞穴城市
变态指数:★★☆☆☆
这是土耳其卡帕多西亚的一个著名景点,传说是当年基督教徒们为了躲避战争而在此修建。里面曾住着20000人,......据英国《每日快报》报道,一位科学家兼理论家Robert Lanza博士宣称,世界上并不存在人类死亡,死亡的只是身体。他认为我们的意识借助我们体内的能量生存,而且...《我爱狐狸精》 - 刘馨棋
  (电视剧《屏里狐》主题曲)
  作词:金十三&李旦
  作曲:刘嘉
  狐狸精 狐狸仙
  千年修... under pass
自由人非常擅长传球和垫球。
The libero is very go...·&·&·&&&&&&各位,看一看,瞧一瞧,新出炉的...大拍卖喽!
第二章、在窗口中画图
精华浓缩:
Windows中负责图形输出的是GDI(即Graphic Device Interface,图形设备接口)。这是Windows与硬件无关的图形输出模式的体现。GDI建立在硬件抽象层(HAL)之上,屏蔽了不同输出设备之间的差异,从而为用户提供了一个统一的“标准输出设备”。但是,与DOS不同,Windows是多任务、进程独立的,每一个窗口都应该有一个独立的输出通道。这样,GDI又使用了一种简单的机制来保证在窗口中画图的不同程序之间能共享“设备”而又互不干扰。这个机制就是DC(Device Context,设备描述表)。
有人把DC比喻成画家的画室,这里有画布、画刷、画笔等等很多工具。
就画布而言,画布形式可以不同,是的,我可以在桌上(desktop)的纸上(window)画,也可以就画在桌面上,还可以画在墙上(管的着吗!^_^)。
为此,Windows MFC提供了四种不同的DC环境(封装为C++类),以标明不同的绘制权限,即:
CPaintDC, 用于在窗口客户区画图(仅限于在OnPaint处理函数中使用);
CClientDC, 也用于在窗口客户区画图(限于在OnPaint处理函数之外使用);
CWindowDC, 用于在窗口内任意地方画图,包括非客户区;
CMetaFileDC, 用于绘制GDI图元文件。
这些类都可以直接实例化,如:
CPaintDC dc(this);//this表示此DC所属窗口为当前窗口
创建了一个CPaintDC对象dc。
CWindowDC一般不常用,如果想在窗口非客户区画图,可借助OnNcPaint()处理函数捕获WM_NCPAINT消息。
刚才说了,DC中还有画刷、画笔等。这些都是DC的属性,可通过DC自身(调用其成员函数)获得。
DC属性包括文本颜色、背景颜色、映射模式、绘图模式、当前位置、当前画笔(刷)和当前字体等。
画笔(Pen)、画刷(Brush)都是独立的GDI对象,可通过CDC成员函数SelectObject()选入DC。同样操作方式的对象还有字体(Font)、位图(Bitmap)、调色板(Palette)和区域(Region)。
关于SelectObject():在创建好GDI对象之后,SelectObject()接收该对象指针,其返回值为先前选入DC的相同类型的对象指针(通常用来恢复DC用)。
Windows也预先定义了一些画笔、画刷、字体以及其他一些GDI对象。这些对象称为备用对象,用CGdiObject::SelectStockObject()选入。CGdiObject是表示GDI对象的CPen、CFont等类的基类。备用对象的属性说明可以查MSDN。
由CGdiObject派生类创建的画笔、画刷和其他对象都要占用内存资源,因此使用后一定要删除它们。处理方法与其他window对象类似。在栈中创建的对象,当此CGdiObject超出范围时会自动析构。在堆中用new创建的CGdiObject对象,可通过调用CGdiObject::DeleteObject显式删除(这会引起对GDI对象析构函数的调用)或用相应的delete运算符。如果是备用对象,则没必要专门删除,留给windows就可以了。
VC++有一种简单的方法用来确定是否成功的删除了GDI对象:只要在调试状态下运行应用程序的调试版本即可。在应用程序结束时,没有释放的资源会显示在调试窗口中。
一些知识点:
1.绘图模式:GDI将象素点输出到逻辑显示平面上时,并不只是简单的输出象素颜色,而是通过一系列布尔运算将输出象素点的颜色和输出目标位置上象素点的颜色进行合成再显示。所使用的逻辑运算关系就由DC的绘图模式确定。使用CDC:SetROP2()可更改绘图模式(ROP2,Raster Operation To)。默认绘图模式是R2_COPYPEN,直接将象素点输出到显示平面上。常用的还有R2_NOT,用于实现鼠标绘图时的Rubber技术。
2.映射模式:这是DC的属性之一,用于确定从逻辑坐标到设备坐标的转换(或者说mapping,映射)方式。设备坐标是指窗口中相应的象素点位置。单位只有象素一种。而逻辑坐标依映射模式不同而单位各异。如默认的MM_TEXT模式下,一个单位恰恰是一个象素点。MM_LOENGLISH模式下,一个单位则相当于百分之一英寸长。windows支持8种映射模式,其中的MM_ISOTROPIC和MM_ANISOTROPIC是可编程的。这意味着是用户而不是windows确定从逻辑坐标到设备坐标的转换方式。换句话说,就是用户来自行定制逻辑单位的实际大小。这两种模式最常用于根据窗口尺寸按比例自动调节画图输出大小的场合。两者之间的唯一区别在于:前者中X方向和Y方向具有同一缩放比例因子。设置映射模式的函数是CDC::SetMapMode()。
3.坐标系常用技术:
1)坐标变换:调用CDC::LPtoDP可将逻辑坐标值转换为设备坐标值。反之,调用CDC::DPtoLP可将设备坐标值转换为逻辑坐标值。在相应鼠标单击区域命中测试时,将使用这两个函数。因为鼠标单击得到的是设备坐标,而很多GDI函数使用逻辑坐标,必须转换为统一坐标,操作才有意义。
2)原点移动:默认方式下,DC的原点位于相应显示平面的左上角。MFC提供了两个CDC类成员函数,可改变原点位置。CDC::SetWindowOrg()移动窗口原点,CDC::SetViewportOrg()移动视图原点(详见MSDN)。一般只能使用两者之一。原点移动技术在边框滚动条设置时有所体现。
3)用户坐标与屏幕坐标:前者是设立在窗口客户区左上角的设备坐标值,后者是原点位于屏幕左上角的设备坐标值。两者的相互转换用函数是CWnd::ClientToScreen()和CWnd::ScreenToClient()。
4.GDI绘图函数
1)画线:包括MoveTo、LineTo、Polyline、PolylineTo、Arc、ArcTo、PolyBezier等。其中Polyline和PolylineTo都可以一次画多条线,两者的区别是PolylineTo使用DC的当前位置,而Polyline则不需要。ArcTo在win98下未实现。另外,所有GDI画线函数有一个共同特点,就是从不画最后一个象素点。
2)画图形:画封闭图形的GDI函数以外接矩形的坐标为参数。常用函数有Rectangle、Ellipse、RoundRect、Pie、Chord等。
5.画笔与画刷:在MFC中,画笔对象封装为CPen类,画刷对象封装为CBrush类。创建两者都有三种方法。最简单的就是构造一个CPen对象,直接给出所用参数进行初始化。第二种方法是调用一个未初始化的CPen对象,用CreatePen()初始化。还有一种方法是构造一个未初始化的CPen对象,通过向LOGPEN结构中填充描述画笔特性的参数,然后调用CPen::CreatePenIndirect()生成画笔。画刷基本相同。
1)CPen:windows用当前选入DC的画笔绘制线条,并给封闭图形镶制边框。画笔有三个特性,即样式、宽度和颜色。样式有PS_SOLID、PS_INSIDEFRAME、PS_NULL等。PS_NULL一般称其为“NULL画笔”,想画一个没有边框的图形,就用到它了。笔宽以逻辑单位给出,实际意义与当前映射模式相同。颜色是通过RGB宏把三个独立颜色成分的值合成为一个可传递给GDI的COLORREF值来确定的。
2)CBrush:画刷有三种基本类型,即单色、带阴影线和带图案。其中图案画刷允许用位图填充图形内部(这样,窗口背景也就没啥新鲜的了)。常用函数有
CDC::SetBkMode()、CDC::SetBkColor()等。
6.文本与字体:CDC有一打文本处理函数,重要的几个是DrawText、TextOut、GetTextMetrics、SetTextColor和SetTextAlign等。其中GetTextMetrics()传给TEXTMETRIC结构关于字体性质的相关信息。字体是一组具有特定尺寸(高度)和字样的字符;字样指示字体共有属性,如粗细等。字体封装在CFont类中,建立字体对象,要在CFont构造之后,再调用CFont的成员函数CreateFont或CreateFontIndirect等来建立GDI字体资源。针对字体,有一个LOGFONT结构,其中定义了字体的所有特性。也可通过填充它来创建字体。
后记:写这一章的笔记时有一种被作者牵着鼻子走的感觉。知识点太多,写出来有一种罗列或拼凑的嫌疑。我不希望这样,但想一想,技术也就是这样。所以我希望大家看的时候,能够思考着看,而不是记忆着看。思考着看只要求我们知道技术点、怎么用,用熟了,用多了,也就记住了。精华是浓缩的,至于如何把它化开,可要靠你自己了。&&&&&  免责声明:本文仅代表作者个人观点,与王朝网络无关。王朝网络登载此文出于传递更多信息之目的,并不意味着赞同其观点或证实其描述,其原创性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容、文字的真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。&&&&&&为你推荐&&&&&&转载本文&UBB代码&HTML代码复制到剪贴板...&更多内容··········&&&&&&&&&频道精选&&&王朝女性&&|&&|&&|&&|&&|&&|&&|&&|&&|&&|&&|&&|&王朝分栏&&|&&|&&|&&|&&|&&|&&|&&|&&|&&|&王朝编程&&|&&|&&|&&|&&|&&|&&|&&|&&|&&|&王朝导购&&|&&|&&|&&|&&|&&|&&|&&|&&|&&|&王朝其他&&|&&|&&|&&|&&|&&|&&&&2005-&&版权所有&11596人阅读
VC/MFC/Windows(20)
一.关于GDI的基本概念
什么是GDI?
Windows绘图的实质就是利用Windows提供的图形设备接口GDI(Graphics Device Interface)将图形绘制在显示器上。
在Windows操作系统中,动态链接库C:/WINDOWS/system32/gdi32.dll(GDI Client DLL)中定义了GDI函数,实现与设备无关的包括屏幕上输出像素、在打印机上输出硬拷贝以及绘制Windows用户界面功能。在Visual C++6.0中的头文件C:/Program Files/Microsoft Visual Studio/VC98/Include/wingdi.h和Visual Studio 2005中的头文件C:/Program Files/Microsoft Visual Studio 8/VC/PlatformSDK/Include/WinGDI.h是访问gdi32.dll库文件的钥匙。下面我们大致浏览一下wingdi.h(included in Windows.h)头文件:
/* Bitmap Header Definition */定义了BITMAP位图结构
/* Mapping Modes */定义了DC中的坐标映射方式,包括以下常用函数:
SetMapMode、SetViewportExtEx、SetViewportOrgEx、 SetWindowExtEx 、SetWindowOrgEx。
/* Stock Logical Objects */系统预定义的堆(STOCK)对象,包括BRUSH、PEN和FONT对象
/* Brush Styles */定义了画刷格式,包括SOLID、HOLLOW、HATCHED等格式
/* Hatch Styles */定义了画刷阴影格式,包括:
HS_VERTICAL&&& /* ||||| */
HS_FDIAGONAL& /* ///// */
HS_BDIAGONAL& /* ///// */
HS_CROSS&&&&& &/* +++++ */
HS_DIAGCROSS& /* xxxxx */
/* Pen Styles */定义了画笔格式,包括SOLID、DASH、DOT等格式
什么是DC?
设备环境DC(Device Context),也称为设备描述表或设备上下文。
设备环境保存了绘图操作中一些共同需要设置的信息,如当前的画笔、画刷、字体和位图等图形对象及属性,以及坐标映射、颜色和背景等影响图形输出的绘图模式。形象的说,一个设备环境提供了一张画布和一些绘画的工具,我们可以使用不同格式、颜色的绘画工具在上面涂鸦。这里,设备环境中的&设备&是指任何类型的显示器或打印机等输出设备,绘图时,我们不必关心所使用设备的编程的原理和方法,所有的绘制操作必须通过设备环境进行间接的处理,Windows会自动将设备环境所描述的结构映射到相应的物理设备上。
从根本上来说,DC它是Windows内部使用的数据结构,它存储着向设备输出时说需要的信息,应用程序利用它定义图形对象及其属性,并实现应用程序、设备驱动程序和输出设备之间绘图命令的转换。要想调用GDI函数向某个区域输出文字或绘制图形,必须先取得或建立设备环境句柄,应用程序每一次绘图操作均按照设备环境中的设置的绘图属性进行。
设备环境不像其他Windows结构,在程序中不能直接存取设备环境结构,只能通过系统提供的一系列函数或使用设备环境的句柄HDC来间接地获取或设置设备环境结构中的各项属性,这些属性包括显示器高度和宽度、支持的颜色数和分辨率等。
MFC中与GDI有关的类
为了支持GDI绘图,MFC提供了两种重要的类:设备环境DC(Device Context)类,用于设置绘图属性和绘制图形;绘图对象类,封装了各种GDI绘图对象,包括画笔、刷子、字体、位图、调色板和区域。
在MFC中,CDC是设备环境类的基类,除了一般的窗口显示外,还用于基于桌面的全屏幕绘制和非屏幕显示的打印机输出。CDC类封装了所有图形输出函数,包括矢量、光栅和文本输出。CDC的派生类包括CClientDC、CPaintDC、WindowDC、CMetaFileDC。
(1)CPaintDC类是一个来自CDC的设备环境类。它在构造期间执行CWnd::BeginPaint,在析构期间执行CWnd::EndPaint,EndPaint()除了释放设备环境外,还负责从消息队列中清除WM_PAINT消息。一个CPaintDC对象只在响应一个窗口重绘消息(WM_PAINT)的时候被使用,通常是在你的OnPaint消息处理成员函数中。因此,在处理窗口重画时,必须使用CPaintDC,否则WM_PAINT消息无法从消息队列中清除,将引起不断的窗口重画。
CPaintDC类成员:
m_ps:包含了用于画客户区的PAINTSTRUCT&
m_hWnd: CPaintDC对象所附着的HWND&
构造函数CPaintDC:构造一个连接到指定的CWnd上的CPaintDC对象
(2)CClientDC(窗口客户区设备环境)类用于管理窗口用户区对应的显示上下文,它在构造时调用了Windows函数GetDC,在析构时调用了ReleaseDC。这意味着和CClientDC对象相关的设备上下文是窗口的客户区。一般在响应非窗口重画消息(如键盘输入时绘制文本、鼠标绘图)绘图时要用到它。
CClientDC类的成员:
构造函数:构造一个连接到CWnd上的CClientDC对象数据成员
数据成员:所在的有效窗口的HWND
(3)CWindowDC(窗口设备环境)类用于管理与整个窗口对应的显示上下文,包括它的结构和控件。它在构造的时候调用Windows函数GetWindowDC,在销毁的时候调用ReleaseDC。这意味着CWindowDC对象可以访问CWnd的全部屏幕区域(包括客户区和非客户区)。它用于窗口(包括窗口边框、标题栏、控制按钮等)的绘制,除非要自己绘制窗口边框和按钮(如一些CD播放程序等),否则一般不用它。
&CWindowDC类成员:
&Construction CWindowDC:构造一个CWindowDC对象
&Data Members m_hWnd:与这个CWindowDC相关联的HWND句柄
(4)CMetaFileDC专门用于图元文件的绘制。图元文件记录一组GDI命令,可以通过这一组GDI命令重建图形输出。使用CMetaFileDC时,所有的图形输出命令会自动记录到一个与CMetaFileDC相关的图元文件中。
(5)此外我们还可以利用Windows内存DC进行绘图,此时涉及到屏幕DC和内存DC。把所要绘制的一切先在内存DC中进行绘制,之后全部搬到屏幕DC中,从而把所有繁琐的绘制过程都在内存DC中完成了,我们在屏幕上看到的是一幅完整的图画,所以不可能出现闪烁的情况。
二.MFC中GDI绘图
&&& GDI绘图包括以下步骤:获取设备环境,设置坐标映射,创建绘图工具,调用DC绘图函数绘图。
1、获取设备环境
(1)在SDK编程中,获取设备环境的方法有两种:
&1&通过API函数BeginPaint。应用程序响应WM_PAINT消息进行图形刷新时主要通过BeginPaint函数获取设备环境,在消息处理函数返回前调用API函数EndPaint释放设备环境。
函数原型为:WINUSERAPI HDC WINAPI BeginPaint( HWND hWnd,LPPAINTSTRUCT lpPaint);
&&& //以下为Win API示例::BeginPaint(HWND hWnd, LPPAINTSTRUCT lpPaint);
&&&& case WM_PAINT://窗口客户区需要重绘
&&&&&&& &char szText[]="Hello World";
&&&&&&& &PAINTSTRUCT
&&&&&&& &HDC hdc=::BeginPaint(hWnd,&ps);
&&&&&&& &::TextOut(hdc,10,10,szText,strlen(szText));
&&&&&&& &::EndPaint(hWnd,&ps);
&&&&&&& &return 0;
MFC对BeginPaint进行了封装:
CWnd::BeginPaint,CDC* BeginPaint( LPPAINTSTRUCT lpPaint ); 等价于::BeginPaint(CWnd::m_hWnd, LPPAINTSTRUCT lpPaint);
&2&通过API函数GetDC。在非WM_PAINT消息处理函数中,需要调用GetDC来获取设备环境,调用API函数ReleaseDC来释放设备环境。
函数原型为:WINUSERAPI HDC WINAPI GetDC( HWND hWnd);
(2)在MFC中,MFC提供了不同类型的DC类,每一个类都封装了DC句柄,并且它们的构造函数自动调用获取DC的API函数,析构函数自动调用释放DC的API函数。因此,在程序中通过声明一个MFC设备环境类的对象就自动获取了一个DC,而当该对象被销毁时就自动释放了获取的DC。MFC AppWizard应用程序向导创建的OnDraw()函数自动支持所获取的DC。&
&1& CPaintDC构造函数:CPaintDC(CWnd* pWnd); 构造一个CPaintDC对象(pWnd指向一个CPaintDC对象所属的CWnd对象),准备用于绘画的应用程序窗口。
// BeginPaint
void CView::OnPaint()
&&& &&&& CPaintDC dc(this); // device context for painting
&&& &&&& // TODO: Add your message handler code here
&&& &&&& OnPrepareDC(&dc);
&&& &&&& OnDraw(&dc)
当我们改变了窗口尺寸、移动窗口或恢复了先前被覆盖的部分,应用程序窗口就会收到一个Windows系统发送来的WM_PAINT消息,然后调用基类Cview的OnPaint函数或我们自己添加的消息处理函数OnPaint。我们可以在OnPaint函数中重绘窗口中重新可见的部分(),但简单的处理办法是重绘整个窗口。上面的代码中,由于基类Cview的OnPaint函数调用了OnDraw函数,因此应用程序经常在OnDraw函数中绘制视图。
&2&CClientDC构造函数:CClientDC(CWnd* pWnd); 构造一个CClientDC对象,它将存取pWnd指向的CWnd的客户区。
// 鼠标左键事件处理
void CExView::OnLButtonDown(UINT nFlags, CPoint point)
&&& &&&&& // TODO: 在此添加消息处理程序代码和/或调用默认值
&&& &&&&& CClientDC dc(this);//定义客户区设备环境
&&& &&&&& dc.LineTo(point);//绘制线段
CClientDC代表了窗口客户区对应的显示上下文,它在构造时调用了API函数GetDC,并将当前窗口的句柄m_hWnd作为函数参数;在析构时调用了API函数ReleaseDC。当在客户去绘图时,需要利用CClientDC类定义一个客户区设备环境句柄。
有时候需要访问与一个客户设备环境相关联的窗口对象,可以通过Attach函数把这个CClientDC的成员m_hWnd句柄传递给一个窗口对象,该窗口就是与客户区设备环境相关联的窗口。
CWnd::Attach,BOOL Attach( HWND hWndNew );
说明:将一个Windows窗口与CWnd对象相连接。返回值:如果成功,则返回非零值;否则返回0。参数:hWndNew指定了Windows窗口的句柄
&3&CWindowDC构造函数:CWindowDC( CWnd* pWnd );构造一个CWindowDC对象,它可以访问pWnd指向的CWnd对象的整个屏幕区域(包括客户区和非客户区)。比如我们在做屏幕保护程序时,一般以整个屏幕区域作为绘制区域。
2、设置坐标映射
&& (1)Windows坐标系统
Windows坐标系分为逻辑坐标系和设备坐标系两种,GDI支持这两种坐标系。一般而言,GDI的文本和图形输出函数使用逻辑坐标,而在客户区移动或按下鼠标的鼠标位置是采用设备坐标。
&1&逻辑坐标系是面向DC的坐标系,这种坐标不考虑具体的设备类型,在绘图时,Windows会根据当前设置的映射模式将逻辑坐标转换为设备坐标。
&2&设备坐标系是面向物理设备的坐标系,这种坐标以像素或设备所能表示的最小长度单位为单位,X轴方向向右,Y轴方向向下。设备坐标系的原点位置(0, 0)不限定在设备显示区域的左上角。
设备坐标系分为屏幕坐标系、窗口坐标系和客户区坐标系三种相互独立的坐标系。
屏幕坐标系以屏幕左上角为原点,一些与整个屏幕有关的函数均采用屏幕坐标,如GetCursorPos()、SetCursorPos()、CreateWindow()、MoveWindow()。弹出式菜单使用的也是屏幕坐标。
窗口坐标系以窗口左上角为坐标原点,它包括窗口标题栏、菜单栏和工具栏等范围。
客户区坐标系以窗口客户区左上角为原点,主要用于客户区的绘图输出和窗口消息的处理。鼠标消息的坐标参数使用客户区坐标,CDC类绘图成员函数使用与客户区坐标对应的逻辑坐标。
(2)坐标之间的相互转换
编程时,有时需要根据当前的具体情况进行三种设备坐标之间或与逻辑坐标的相互转换。
MFC提供了两个函数CDC::DPtoLP()和CDC::LPtoDP()用于设备坐标与逻辑坐标之间的相互转换。
MFC提供了两个函数CWnd::ScreenToClient()和CWnd::ClientToScreen()用于屏幕坐标与客户区坐标的相互转换。
(3)映射模式
映射模式确定了在绘制图形时所依据的坐标系,它定义了逻辑单位的实际大小、坐标增长方向,所有映射模式的坐标原点均在设备输出区域(如客户区或打印区)的左上角。此外,对于某些映射模式,用户还可以自定义窗口的长度和宽度,设置视图区的物理范围。
Windows定义了8种映射模式,见下表。
映射模式使得程序员可不必考虑输出设备的具体设备坐标系,而在一个统一的逻辑坐标系中进行图形的绘制。
当绘制的图形需要随着窗口的大小改变而自动改变的时候,一般选择MM_ISOTROPIC和MM_ANISOTROPIC映射方式。它们的唯一区别就是前者的X轴和Y轴的逻辑单位的大小是相同的,单词&isotropic&就是各个方向相等的意思,此映射方式适合绘制圆或正方形。而实际应用中,常常给X轴和Y轴取不同的比例,这时候选择MM_ANISOTROPIC映射方式。单词&anisotropic&就是各个方向相异的意思。
(4)自定义映射模式
&窗口&和&视口&的概念:
窗口(Window):对应逻辑坐标系上程序员设定的区域
视口(Viewport):对应实际输出设备上程序员设定的区域
窗口原点是指逻辑窗口坐标系的原点在视口(设备)坐标系中的位置,视口原点是指设备实际输出区域的原点。
除了映射模式,窗口和视口也是决定一个点的逻辑坐标如何转换为设备坐标的一个因素。一个点的逻辑坐标按照如下式子转换为设备坐标:
设备(视口)坐标 = 逻辑坐标 &窗口原点坐标 + 视口原点坐标
//定义坐标映射方式
WINGDIAPI int&& WINAPI SetMapMode(HDC, int);
此API函数在MFC中封装为CDC::virtual int SetMapMode(int nMapMode);
//定义逻辑窗口区域,单位为逻辑单位(Logical)
WINGDIAPI BOOL& WINAPI SetWindowExtEx (HDC, int, int, LPSIZE);
此API函数在MFC中封装为CDC::virtual CSize SetWindowExt(int cx, int cy);
//设置逻辑窗口的原点坐标,缺省原点为(0,0)。
WINGDIAPI BOOL& WINAPI SetWindowOrgEx(HDC, int, int, LPPOINT);
此API函数在MFC中封装为CDC::CPoint SetWindowOrg(int x, int y);
注意:SetWindowOrg(Ex) 只有在映射模式为MM_ANISOTROPIC或MM_ISOTROPIC时才有意义。
//定义视口的坐标轴方向及区域、定义域和值域,单位为像素(Pixel)
WINGDIAPI BOOL& WINAPI SetViewportExtEx(HDC, int, int, LPSIZE);
此API函数在MFC中封装为CDC::virtual CSize SetViewportExt(int cx, int cy);
注意:SetViewportExt(Ex) 只有在映射模式为MM_ANISOTROPIC或MM_ISOTROPIC时才有意义。
//设置视口的原点坐标,缺省原点为(0,0)。
WINGDIAPI BOOL& WINAPI SetViewportOrgEx(HDC, int, int, LPPOINT);
此API函数在MFC中封装为CDC:: virtual CPoint SetViewportOrg(int x, int y);
参考:《GDI中的坐标映射问题》
3、创建绘图工具并选入DC
有了画布,要绘图我们必须有画笔画刷。在Windows中有HPEN、HBRUSH等GDI对象,MFC对GDI对象进行了很好的封装,提供了封装GDI对象的类,如CPen、CBrush、CFont、CBitmap和CPalette等,这些类都是GDI对象类CGdiObject的派生类。
&& &一般先创建画笔(刷),然后调用CDC::SelectObject函数将画笔(刷)选入设备环境最为当前绘图工具,绘图完毕恢复设备环境以前的画笔(刷)对象,最后调用CGdiObject::DeleteObject函数删除画笔(刷)对象。
&& &这里需要注意的是,CGdiObject::DeleteObject函数彻底删除底层GDI对象(CPen和CBrush类的基类)。在MFC中,当对象销毁时会调用对象的析构函数自动删除对象,一般不必调用CGdiObject::DeleteObject删除GDI对象,因为如果设备环境还在使用一个GDI对象时,将引起应用程序崩溃或出现难以理解的运行错误。
&& (1)创建画笔
BOOL CPen::CreatePen( int nPenStyle, int nWidth, COLORREF cfColor );
nPenStyle& 指定画笔的风格。其可能取值的列表,请参见CPen构造函数中的nPenStyle参数。
nWidth 指定画笔的宽度。如果这个值为0,则不管是什么映射模式,以设备单位表示的宽度总是一个像素。
crColor 包含画笔的一个RGB颜色,为COLORREF结构。
此外,可通过CDC::SelectStockObject函数来调用系统预定义的库存笔对应的CGdiObject对象。
pOldPen = (Cpen*)pDC-&SelectStockObject(BLACK_PEN);
(2)创建画刷
BOOL CBrush::CreateSolidBrush ( COLORREF crColor );
BOOL CBrush::CreateHatchBrush( int nIndex, COLORREF crColor );
参数: nIndex 指定画刷的阴影线风格。可取的值如下:
HS_HORIZONTAL&& /* ==== */
HS_VERTICAL&&& /* ||||| */
HS_FDIAGONAL& /* ///// */
HS_BDIAGONAL& /* ///// */
HS_CROSS&&&&&& /* +++++ */
HS_DIAGCROSS& /* xxxxx */
返回值:调用成功时返回非零值,否则为0。
此外,可通过CDC::SelectStockObject函数来调用系统预定义的库存画刷对应的CGdiObject对象。
pOldBrush = (CBrush*)pDC-&SelectStockObject(BLACK_BRUSH);
(3)将画笔(刷)选入设备环境。
以下为MFC中默认映射方式下的GDI绘图的模块:
//先获取设备环境pDC
&&& CPen *pOldPen,newP
&&& CBrush *pOldBrush,newBrush1,newBrush2;
&&& //创建宽度为pixel的白色实线画笔
&&& newPen.CreatePen(PS_SOLID,1,RGB(0,0,0));
&&& //创建红色实线画刷
&&& newBrush1.CreateSolidBrush(RGB(255,0,0));
&&& //创建红色实线度的向下(从右到左)影线的阴影画刷
&&& newBrush2.CreateHatchBrush(HS_BDIAGONAL,RGB(255,0,0));
&&& //将newPen画笔和newBrush1画刷对象选入设备环境
&&& pOldPen = pDC-&SelectObject(&newPen);
&&& pOldBrush = pDC-&SelectObject(&newBrush1);
&&& //调用DC绘图函数绘图
&&& //绘图完毕,恢复原来画笔、画刷
&&& pDC-&SelectObject(pOldPen);
pDC-&SelectObject(pOldBrush);
//删除创建的画笔、画刷
// newPen.DeleteObject();
// newBrush1.DeleteObject();
// newBrush2.DeleteObject();
&& (4)当绘制文本Text时,一般可以通过调用CDC::SetBkColor函数来设置背景颜色,调用CDC::SetTextColor函数来设置文字颜色,调用CDC::SetTextAlign函数设置文本对齐标记。
4、调用DC绘图函数绘图
GDI为提供了绘制基本图形的成员函数,在MFC中这些函数封装在CDC类中。
注意:绘图函数使用的坐标都是逻辑坐标。
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:2744740次
积分:9465
积分:9465
排名:第1493名
原创:118篇
转载:25篇
评论:285条
(1)(2)(1)(3)(2)(1)(1)(3)(1)(3)(2)(1)(2)(2)(1)(6)(1)(1)(5)(3)(12)(3)(1)(4)(1)(1)(4)(1)(5)(9)(3)(2)(4)(1)(1)(1)(50)}

我要回帖

更多关于 3dmax bezier 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信