




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、旋转你的图形-高级内存设备描述表 一个内存设备描述表类(CMemDC) 我最近下载了由Keith Rule发布的CMemDC类(见他在codeguru的文章)它面向下列问题:假如你在一个设备描述表上执行一个相当大的操作(例如在OnPaint()中),你的显示器闪烁相当严重。围绕这个问题,Keith设计了CMemDC,它可以创建一个兼容的“内存”设备描述表用于画图。在你向这个设备描述表完成绘制后(在内存中),就可以向可视的原始文本中粘贴了-只有一个blit操作发生。因此输出的闪烁几乎就再也不会发生了。然而,它的实现假定你总是画整个粘贴区域-甚至在它已经被WM_ERASEBKGND或某些材料填满的
2、情况下 为什么旋转文本不是很容易 此外,最近我设计了一个显示旋转文本的按钮。现在,你能创建一个输出旋转文本的CFont(使用一个LOGFONT并设置lfOrientation和lfEscapement),但它只能在AFAIK的TrueType类型字体下工作-不能使用MS Sans Serif。至少,假如你设定这个字体,CDC文本函数看起来会变得混淆不清-会产生“随机”结果.如果不信可以试一试 因此我看了一下Keith的 CMemDC类和CDC:PlgBlt()函数,决定把CMemDC扩展成一个“可旋转的” 内存文本,例如:它不仅可以向输出设备描述表剪贴内存位图,如果你愿意,甚至可以旋转内存位图
3、 cdxCRot90DC-一个可以旋转的内存设备描述表 cdxCRot90DC 可以解决以下问题。先指定一个“目的设备描述表”(一般是你的输出设备),它甚至允许你提供当前输出设备描述表之外的一个矩形(而CMemDC总是使用当前输出设备描述表的剪贴板)以及一个“方角”注意:“方角”是指一个能被90°整除的角,这就是为什么它叫cdxCRot90DC 而不是cdxCRotDC 。并且注意,我指出的角度x同样适用于x+n*360 和 x-n*360, n是自然数 一个例子可以说明这个设备描述表做什么(使用一个90°角的cdxCRot90DC ) 你可能认为这种旋转对文本没有限制-你
4、能随心所欲向内存设备描述表绘图,而在旋转后的结果会放入你的原始设备描述表-很遗憾,你不能使用这样,不能使用你的原始矩形向cdxCRot90DC绘制-你需要使用自动传送给你的矩形(用GetRotRect()来得到)假如你选择一个0°的“方角”,cdxCRot90DC 基本上如CMemDC一样具有以下优点: 你能随意定义想要操作的的目的设备描述表的矩形区域见constructor/Create() 你能最先拷贝前一个设备描述表的内容到你的内存位图(这样可以阻止任何由WM_ERASEBKGND完成的绘制或由一个自绘控件的DrawItem() 函数完成的绘制)见constructor/Cre
5、ate()你可以放弃所做出的改变 CMemDC 总是把它的位图拷贝回你的原始设备描述表-这也许不合适(例如:你发现一段文本是空的而位图中什么也没有)function Invalidate() 对于旋转输出的特性:透明的角度使用 你的代码不必为不同的角度而改变(通过使用GetRotRect())。自动克隆原始设备描述表的字体,背景色,文本模式和文本颜色(而且使用后恢复它们)。对象能被另一个目的设备描述表矩形重用(没有新的设备描述表对象被创建,旧的位图只要可能就会被重用)见Create() 请注意: 这个设备描述表不支持打印(与CMemDC相反)。假如谁愿意帮助我实现它,我会很高兴的。因为我看来没
6、有一个支持旋转输出的打印机:以下是一个简单的例子 OnPaint(), 可以向设备描述表中绘制旋转的文本:这个例子使用构造器、GetRotRect(), IsCreated() 和调用Finish()的析构器 void MyWnd:OnPaint() / create "destDC" /创建“destDC” CPaintDC destDC(this); / get client rect /获得客户区矩形 CRect rectClient; GetClientRect(rectClient); cdxCRot90DC rotDC(destDC,rectClient,90
7、/*90 degress*/ ); if(!rotDC.IsCreated() return; / get client rect in rotated coordinates /获得在旋转后的坐标系中的客户区矩形 CRect rectRot = dc.GetRotRect(); / example: print programmer's most loved text into the / the center of the dest DC - rotated and centered /例子:打印程序员最爱使用的文本到目的设备描述表的中心-旋转并居中 CString s = _T(
8、"Hello world"); CSize sz = rotDC.GetTextExtent(s); rotDC.TextOut(rectRot.left + (rectRot.Width() - sz.cx) / 2, rectRot.top + (rectRot.Height() - sz.cy) / 2, s); / destructor of rotDC calls rotDC.Finish() /rotDC的析构器调用 rotDC.Finish()一个OnPaint() 的例子,在你旋转后的内容上画出3维的边界(此处我们直接使用Finish() )这个例子使用构造
9、器、GetRotRect(), IsCreated() 和 Finish() void MyWnd:OnPaint() / create "destDC" /创建“destDC” CPaintDC destDC(this); / get entire client area /得到整个客户区域rectClient CRect rectClient; GetClientRect(rectClient); / get rectangle you want to draw to except borders /得到除了边界外你想要画的矩形rectInner CRect rectI
10、nner = rectClient; rectInner.DeflateRect(:GetSystemMetrics(SM_CXEDGE),:GetSystemMetrics(SM_CYEDGE); / constuct rotated device context /构造旋转后的设备描述表rotDC cdxCRot90DC rotDC(origDC,rectInner,90/*90 degress*/); / check whether there is a non-empty visible rectangle /检查是否有一个非空的可视矩形 if(rotDC.IsCreated() /
11、get the rectangle rectReal of rotDC that matchs rectRotated in destDC /得到rotDC中的用于配合目的设备描述表中旋转后的矩形的矩形rectRotClient CRect rectRotClient = rotDC.GetRotRect(); / draw nice things into my device context using rectRotClient /使用rectRotClient向你的设备描述表中绘制 . rotDC.TextOut(rectRotClient.left,rectRotClient.top,
12、"Left-top text"); . / now copy bitmap back to destDC /向目的设备描述表中拷贝绘制后的位图 rotDC.Finish(); / and draw a border around rectRotated /在rectRotated周围画边界 destDC.DrawEdge(rectClient,EDGE_RAISED,BF_RECT);函数参考注意:以下只包括最重要的函数cdxCRot90DC();cdxCRot90DC(CDC & destDC, const CRect & rectDC, int iAng
13、le, bool bCopy = false);cdxCRot90DC(CDC *pdestDC, const CRect & rectDC, int iAngle, bool bCopy = false);cdxCRot90DC(CDC & destDC, int iAngle, bool bCopy = false);cdxCRot90DC(CDC *pdestDC, int iAngle, bool bCopy = false);构造一个新对象 在下面的四个构造器立即调用Create(),创建一个新的设备描述表假如使用它们,就应该使用IsCreated()检查是否设备描述
14、表被成功的创建了(否则,假如Create()失败,cdxCRot90DC:m_hDC (从CDC继承)就不会被成功的建立,运行中就会有许多ASSERTs.)。更多的信息见Create() 注意:假如设备描述表正确的建立,析构器中会自动调用Finish() bool Create(CDC & destDC, const CRect & rectDC, int iAngle, bool bCopy = false);bool Create(CDC * pdestDC, const CRect & rectDC, int iAngle, bool bCopy = false)
15、;bool Create(CDC & destDC, int iAngle, bool bCopy = false);bool Create(CDC * pdestDC, int iAngle, bool bCopy = false);创建设备描述表 假如这个函数成功的返回,你就可以向其中绘制了。调用Finish()把旋转后的设备描述表中的位图拷贝回你的目的设备描述表(析构器将自动完成这件事)详细内容见Finish() 注意1: 因为你的矩形(见下面的参数)可能被转动了,就不能使用rectDC的坐标来绘制你的数据(它们可能会显示在旋转后的矩形之外)。因此,使用GetRotRect()来
16、获得配合你的rectDC的设备描述表矩形。注意2: 你能调用Create()多次-每次调用都会创建一个“新的”cdxCRot90DC(假如有了前一个调用,它就不会分配新的位图)然而,假如你想把前一个位图拷贝回它的目的设备描述表,应该首先调用Finish()参数:destDC, pdestDC“原始”设备描述表;pdestDC不能为NULL。rectDC 你想使用内存设备描述表绘制的原始设备描述表中的矩形区域。假如没有提供,就使用当前设备描述表的整个剪贴区域。注意 在两种情况下,rectDC都会和原始设备描述表剪贴区域相交,假如不相交,函数会失败。 iAngle 你的输出的旋转角.例如:假如是“
17、90”,你画一从左向右的的箭头显示出来是从上倒下的(见示例的图像)假如是“0”,cdxCRot90DC 就和CMemDC 一样(图像没有旋转) bCopy 假如你想拷贝你的destDC的rectDC的内容到新建的设备描述表,设为TRUE。假如内存设备描述表剪贴回了它的位图,你就不想重绘已有的任何未旋转的位图,这时这个参数就有用了。请注意CDC:PlgBlt不是一个最快的函数,因此你可以首先创建旋转的数据,把它们剪贴过去然后创建别的要旋转的内容 假如-destDC用于打印(我没有一个能够打印旋转后图像的打印机)-rectDC 与你的destDC的剪贴区域不相交,或者你没有提供rectDC-而你的
18、destDC的剪贴又是空的函数就会返回falsebool IsCreated() const;设备描述表被成功创建,返回true,否则返回false。const CRect & GetRotRect() const;operator const CRect & () const return GetRotRect(); 用于获得与目的(“输出”)设备描述表相配合的旋转后的内存设备描述表的矩形区域假如你指一个图像,对于目的矩形(10,20,250,120),这个函数返回(-120,10,-20,250) (rotate() 能用于传送别的2维对象) 假如设备描述表没有成功建立,该
19、函数返回(0,0,0,0) bool Finish(); 通知cdxCRot90DC 你已完成工作-该函数拷贝位图回目的设备描述表,假如Create()成功返回,该函数由析构器自动调用 你不必调用Invalidate()而且也不用亲自调用Finish() 注意再次调用Finish() 不会再次拷贝位图 void Invalidate();作废cdxCRot90DC设备描述表-这样Finish()就不会把位图绘制到目的设备描述表(因此析构器也不会)而且,这个函数会把当前的剪贴区域设为一个空矩形-所有更多的绘制操作就不会影响内存设备描述表了假如你发现你旋转后的图形是空的,就可以使用这个函数来避免内
20、存设备描述表把它拷贝回目的设备描述表(这样做更快速) CRect rotate(const CRect & r) const;CPoint rotate(const CPoint & p) const;CSize rotate(const CSize & s) const;void rotate(POINT *pPnts, UINT nCnt) const;转换目的2维对象为旋转后的2维对象. 例如:假如你向Create()传递"r",GetRotRect()会返回rotate(r). CRect rotateBack(const CRect &am
21、p; r) const;CPoint rotateBack(const CPoint & p) const;CSize rotateBack(const CSize & s) const;void rotateBack(POINT *pPnts, UINT nCnt) const;转换旋转后的2维对象为目的2维对象.CRect operator()(const CRect & r, bool bFwd = true) const;CPoint operator()(const CPoint & p, bool bFwd = true) const;CSize o
22、perator()(const CSize & sz, bool bFwd = true) const;void operator()(POINT *pPnts, UINT nCnt, bool bFwd = true) const;上述函数操作的快捷操作.假如bFwd是true, 使用rotate(),否则使用rotateBack() .static CRect rotate(const CRect & r, int iAngle);static CPoint rotate(const CPoint & p, int iAngle);static CSize rota
23、te(const CSize & s, int iAngle);static void rotate(POINT *pPnts, UINT nCnt, int iAngle); 所有从一个目的2维对象到旋转后的2维对象的转化,这种旋转使用"方角" iAngle你可以使用这些函数来进行计算而不需要创建一个设备描述表 operator cdxCRot90DC * ();cdxCRot90DC *operator->();const cdxCRot90DC *operator->() const;用指针使用类cdxCRot90DC的对象这在使用CDC的要求有一个CDC对象的指针为参数的函数时有用 一些技巧 在旋转后的设备描述表中绘制3维文字需要你知道: 在旋转后的设备描述表中,目的设备描述表的右下角在哪个方向 例如: 假如你想绘制一些变灰的文字(就如在变灰的CStatic中看到的一样),通常如下使用: dc.SetBkMode(TRANSPARENT);dc.SetTextColor(:GetSysColor(COLOR_3DHILIGHT);dc.TextOut(pnt + CPoint(1,1),strText);dc.SetTextColor(:GetSysColor(COLOR_3DSHADOW);dc.TextOut(
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- hCAII-hCAIX-IN-1-生命科学试剂-MCE
- 医疗病例记录及治疗进度跟踪表
- ADORA2A-PDE4D-IN-1-生命科学试剂-MCE
- 中介手房买卖协议书
- 农业绿色发展实践案例
- 生物医学实验技术考核题
- 废弃物处理厂干化系统
- 个人工作台使用情况统计表
- 交通运输企业车辆保险合作协议
- 双方知识产权保护协议书
- 养老院院感管理与应急预案
- 通站(2017)8012 铁路站场排水构筑物
- 2024-2025学年上学期上海初中英语七年级期末模拟试卷2
- 2024-2025学年上学期河北初中英语八年级期末试卷
- 极端天气下的新能源电力系统电力电量平衡体系
- 成人重症患者人工气道湿化护理专家共识解读教学课件
- 建设工程项目质量控制实务
- 教育技术学导论 黄荣怀(第2版)学习通超星期末考试答案章节答案2024年
- 英语课件音标教学课件
- 2024年湖北省中考语文真题(学生版+解析版)
- 装维服务年终总结
评论
0/150
提交评论