第二章 MFC入门图形输出.docx
《第二章 MFC入门图形输出.docx》由会员分享,可在线阅读,更多相关《第二章 MFC入门图形输出.docx(13页珍藏版)》请在冰豆网上搜索。
第二章MFC入门图形输出
第二章图形输出
2.1和GUI有关的各种对象
2.2在窗口中输出文字
2.3使用点、刷子、笔进行绘图
2.4在窗口中绘制设备相关位图、图标、设备无关位图
2.5使用各种映射方式
2.6多边形和剪贴区域
2.1和GUI有关的各种对象
在Windows中有各种GUI对象(不要和C++对象混淆),当你在进行绘图就需要利用这些对象。
而各种对象都拥有各种属性,下面分别讲述各种GUI对象和拥有的属性
字体对象CFont用于输出文字时选用不同风格和大小的字体。
可选择的风格包括:
是否为斜体,是否为粗体,字体名称,是否有下划线等。
颜色和背景色不属于字体的属性。
关于如何创建和使用字体在2.2在窗口中输出文字中会详细讲解
刷子CBrush对象决定填充区域时所采用的颜色或模板。
对于一个固定色的刷子来讲它的属性为颜色,是否采用网格和网格的类型如水平的,垂直的,交叉的等。
你也可以利用8*8的位图来创建一个自定义模板的刷子,在使用这种刷子填充时系统会利用位图逐步填充区域。
关于如何创建和使用刷子在2.3使用刷子、笔进行绘图中会详细讲解
画笔CPen对象在画点和画线时有用。
它的属性包括颜色,宽度,线的风格,如虚线,实线,点划线等。
关于如何创建和使用画笔在2.3使用刷子、笔进行绘图中会详细讲解
位图CBitmap对象可以包含一幅图像,可以保存在资源中。
关于如何使用位图在2.4在窗口中绘制设备相关位图、图标、设备无关位图中会详细讲解
还有一种特殊的GUI对象是多边形,利用多边形可以很好的限制作图区域或是改变窗口外型。
关于如何创建和使用多边形在2.6多边形和剪贴区域中会详细讲解。
在Windows中使用GUI对象必须遵守一定的规则。
首先需要创建一个合法的对象,不同的对象创建方法不同。
然后需要将该GUI对象选入DC中,同时保存DC中原来的GUI对象。
如果选入一个非法的对象将会引起异常。
在使用完后应该恢复原来的对象,这一点特别重要,如果保存一个临时对象在DC中,而在临时对象被销毁后可能引起异常。
有一点必须注意,每一个对象在重新创建前必须销毁,下面的代码演示了这一种安全的使用方法。
OnDraw(CDC*pDC)
{
CPenpen1,pen2;
pen1.CreatePen(PS_SOLID,2,RGB(128,128,128));//创建对象
pen2.CreatePen(PS_SOLID,2,RGB(128,128,0));//创建对象
CPen*pPenOld=(CPen*)pDC->SelectObject(&pen1);//选择对象进DC
drawWithPen1...
(CPen*)pDC->SelectObject(&pen2);//选择对象进DC
drawWithPen2...
pen1.DeleteObject();//再次创建前先销毁
pen1.CreatePen(PS_SOLID,2,RGB(0,0,0));//再次创建对象
(CPen*)pDC->SelectObject(&pen1);//选择对象进DC
drawWithPen1...
pDC->SelectObject(pOldPen);//恢复
}
此外系统中还拥有一些库存GUI对象,你可以利用
CDC:
:
SelectStockObject(SelectStockObject(intnIndex)
选入这些对象,它们包括一些固定颜色的刷子,画笔和一些基本字体.
●BLACK_BRUSHBlackbrush.
●DKGRAY_BRUSHDarkgraybrush.
●GRAY_BRUSHGraybrush.
●HOLLOW_BRUSHHollowbrush.
●LTGRAY_BRUSHLightgraybrush.
●NULL_BRUSHNullbrush.
●WHITE_BRUSHWhitebrush.
●BLACK_PENBlackpen.
●NULL_PENNullpen.
●WHITE_PENWhitepen.
●ANSI_FIXED_FONTANSIfixedsystemfont.
●ANSI_VAR_FONTANSIvariablesystemfont.
●DEVICE_DEFAULT_FONTDevice-dependentfont.
●OEM_FIXED_FONTOEM-dependentfixedfont.
●SYSTEM_FONTThesystemfont.Bydefault,Windowsusesthesystemfonttodrawmenus,dialog-boxcontrols,andothertext.InWindowsversions3.0andlater,thesystemfontisproportionalwidth;earlierversionsofWindowsuseafixed-widthsystemfont.
●SYSTEM_FIXED_FONTThefixed-widthsystemfontusedinWindowspriortoversion3.0.ThisobjectisavailableforcompatibilitywithearlierversionsofWindows.
●DEFAULT_PALETTEDefaultcolorpalette.Thispaletteconsistsofthe20staticcolorsinthesystempalette.
这些对象留在DC中是安全的,所以你可以利用选入库存对象来作为恢复DC中GUI对象。
大家可能都注意到了绘图时都需要一个DC对象,DC(DeviceContext设备环境)对象是一个抽象的作图环境,可能是对应屏幕,也可能是对应打印机或其它。
这个环境是设备无关的,所以你在对不同的设备输出时只需要使用不同的设备环境就行了,而作图方式可以完全不变。
这也就是Windows耀眼的一点设备无关性。
如同你将对一幅画使用照相机或复印机将会产生不同的输出,而不需要对画进行任何调整。
DC的使用会穿插在本章中进行介绍
2.2在窗口中输出文字
在这里我假定读者已经利用ApplicationWizard生成了一个SDI界面的程序代码。
接下来的你只需要在CView派生类的OnDraw成员函数中加入绘图代码就可以了。
在这里我需要解释一下OnDraw函数的作用,OnDraw函数会在窗口需要重绘时自动被调用,传入的参数CDC*pDC对应的就是DC环境。
使用OnDraw的优点就在于在你使用打印功能的时候传入OnDraw的DC环境将会是打印机绘图环境,使用打印预览时传入的是一个称为CPreviewDC的绘图环境,所以你只需要一份代码就可以完成窗口/打印预览/打印机绘图三重功能。
利用Windows的设备无关性和M$为打印预览所编写的上千行代码你可以很容易的完成一个具有所见即所得的软件。
输出文字一般使用CDC:
:
BOOLTextOut(intx,inty,constCString&str)和CDC:
:
intDrawText(constCString&str,LPRECTlpRect,UINTnFormat)两个函数,对TextOut来讲只能输出单行的文字,而DrawText可以指定在一个矩形中输出单行或多行文字,并且可以规定对齐方式和使用何种风格。
nFormat可以是多种以下标记的组合(利用位或操作)以达到选择输出风格的目的。
pDC->TextOut(100,100,”wqewr”);
●DT_BOTTOM底部对齐Specifiesbottom-justifiedtext.ThisvaluemustbecombinedwithDT_SINGLELINE.
●DT_CALCRECT计算指定文字时所需要矩形尺寸Determinesthewidthandheightoftherectangle.Iftherearemultiplelinesoftext,DrawTextwillusethewidthoftherectanglepointedtobylpRectandextendthebaseoftherectangletoboundthelastlineoftext.Ifthereisonlyonelineoftext,DrawTextwillmodifytherightsideoftherectanglesothatitboundsthelastcharacterintheline.Ineithercase,DrawTextreturnstheheightoftheformattedtext,butdoesnotdrawthetext.
●DT_CENTER中部对齐Centerstexthorizontally.
●DT_END_ELLIPSISorDT_PATH_ELLIPSISReplacespartofthegivenstringwithellipses,ifnecessary,sothattheresultfitsinthespecifiedrectangle.ThegivenstringisnotmodifiedunlesstheDT_MODIFYSTRINGflagisspecified.
YoucanspecifyDT_END_ELLIPSIStoreplacecharactersattheendofthestring,orDT_PATH_ELLIPSIStoreplacecharactersinthemiddleofthestring.Ifthestringcontainsbackslash(\)characters,DT_PATH_ELLIPSISpreservesasmuchaspossibleofthetextafterthelastbackslash.
●DT_EXPANDTABSExpandstabcharacters.Thedefaultnumberofcharacterspertabiseight.
●DT_EXTERNALLEADINGIncludesthefont抯externalleadinginthelineheight.Normally,externalleadingisnotincludedintheheightofalineoftext.
●DT_LEFT左对齐Alignstextflush-left.
●DT_MODIFYSTRINGModifiesthegivenstringtomatchthedisplayedtext.ThisflaghasnoeffectunlesstheDT_END_ELLIPSISorDT_PATH_ELLIPSISflagisspecified.
NoteSomeuFormatflagcombinationscancausethepassedstringtobemodified.UsingDT_MODIFYSTRINGwitheitherDT_END_ELLIPSISorDT_PATH_ELLIPSISmaycausethestringtobemodified,causinganassertionintheCStringoverride.
●DT_NOCLIPDrawswithoutclipping.DrawTextissomewhatfasterwhenDT_NOCLIPisused.
●DT_NOPREFIX禁止使用&前缀Turnsoffprocessingofprefixcharacters.Normally,DrawTextinterpretstheampersand(&)mnemonic-prefixcharacterasadirectivetounderscorethecharacterthatfollows,andthetwo-ampersand(&&)mnemonic-prefixcharactersasadirectivetoprintasingleampersand.ByspecifyingDT_NOPREFIX,thisprocessingisturnedoff.
●DT_PATH_ELLIPSIS
●DT_RIGHT右对齐Alignstextflush-right.
●DT_SINGLELINE单行输出Specifiessinglelineonly.Carriagereturnsandlinefeedsdonotbreaktheline.
●DT_TABSTOP设置TAB字符所占宽度Setstabstops.Thehigh-orderbyteofnFormatisthenumberofcharactersforeachtab.Thedefaultnumberofcharacterspertabiseight.
●DT_TOP定部对齐Specifiestop-justifiedtext(singlelineonly).
●DT_VCENTER中部对齐Specifiesverticallycenteredtext(singlelineonly).
●DT_WORDBREAK每行只在单词间被折行Specifiesword-breaking.LinesareautomaticallybrokenbetweenwordsifawordwouldextendpasttheedgeoftherectanglespecifiedbylpRect.Acarriagereturn杔inefeedsequencewillalsobreaktheline.
在输出文字时如果希望改变文字的颜色,你可以利用CDC:
:
SetTextColor(COLORREFcrColor)进行设置,如果你希望改变背景色就利用CDC:
:
SetBkColor(COLORREFcrColor),很多时候你可能需要透明的背景色你可以利用CDC:
:
SetBkMode(intnBkMode)设置,可接受的参数有
●OPAQUEBackgroundisfilledwiththecurrentbackgroundcolorbeforethetext,hatchedbrush,orpenisdrawn.Thisisthedefaultbackgroundmode.
●TRANSPARENTBackgroundisnotchangedbeforedrawing.
接下来讲讲如何创建字体,你可以创建的字体有两种:
库存字体CDC:
:
CreateStockObject(intnIndex)和自定义字体。
在创建非库存字体时需要填充一个LOGFONT结构并使用CFont:
:
CreateFontIndirect(constLOGFONT*lpLogFont)(可以参考文章在同一系统中显示GB字符和BIG5字符),或使用CFont:
:
CreateFont(intnHeight,intnWidth,intnEscapement,intnOrientation,intnWeight,BYTEbItalic,BYTEbUnderline,BYTEcStrikeOut,BYTEnCharSet,BYTEnOutPrecision,BYTEnClipPrecision,BYTEnQuality,BYTEnPitchAndFamily,LPCTSTRlpszFacename)其中的参数和LOGFONT中的分量有一定的对应关系。
下面分别讲解参数的意义:
nHeight字体高度(逻辑单位)等于零为缺省高度,否则取绝对值并和可用的字体高度进行匹配。
nWidth宽度(逻辑单位)如果为零则使用可用的横纵比进行匹配。
nEscapement出口矢量与X轴间的角度
nOrientation字体基线与X轴间的角度
nWeight字体粗细,可取以下值
ConstantValue
FW_DONTCARE0
FW_THIN100
FW_EXTRALIGHT200
FW_ULTRALIGHT200
FW_LIGHT300
FW_NORMAL400
FW_REGULAR400
FW_MEDIUM500
FW_SEMIBOLD600
FW_DEMIBOLD600
FW_BOLD700
FW_EXTRABOLD800
FW_ULTRABOLD800
FW_BLACK900
FW_HEAVY900
bItalic是否为斜体
bUnderline是否有下划线
cStrikeOut是否带删除线
nCharSet指定字符集合,可取以下值
ConstantValue
ANSI_CHARSET0
DEFAULT_CHARSET1
SYMBOL_CHARSET2
SHIFTJIS_CHARSET128
OEM_CHARSET255
nOutPrecision输出精度
OUT_CHARACTER_PRECISOUT_STRING_PRECIS
OUT_DEFAULT_PRECISOUT_STROKE_PRECIS
OUT_DEVICE_PRECISOUT_TT_PRECIS
OUT_RASTER_PRECIS
nClipPrecision剪辑精度,可取以下值
CLIP_CHARACTER_PRECISCLIP_MASK
CLIP_DEFAULT_PRECISCLIP_STROKE_PRECIS
CLIP_ENCAPSULATECLIP_TT_ALWAYS
CLIP_LH_ANGLES
nQuality输出质量,可取以下值
●DEFAULT_QUALITYAppearanceofthefontdoesnotmatter.
●DRAFT_QUALITYAppearanceofthefontislessimportantthanwhenPROOF_QUALITYisused.ForGDIrasterfonts,scalingisenabled.Bold,italic,underline,andstrikeoutfontsaresynthesizedifnecessary.
●PROOF_QUALITYCharacterqualityofthefontismoreimportantthanexactmatchingofthelogical-fontattributes.ForGDIrasterfonts,scalingisdisabledandthefontclosestinsizeischosen.Bold,italic,underline,andstrikeoutfontsaresynthesizedifnecessary.
nPitchAndFamily字体间的间距
lpszFacename指定字体名称,为了得到系统所拥有的字体可以利用EmunFontFamiliesEx。
(可以参考文章在同一系统中显示GB字符和BIG5字符)
此外可以利用CFontDialog来得到用户选择的字体的LOGFONT数据。
最后我讲一下文本坐标的计算,利用CDC:
:
GetTextExtent(constCString&str)可以得到字符串的在输出时所占用的宽度和高度,这样就可以在手工输出多行文字时使用正确的行距。
另外如果需要更精确的对字体高度和宽度进行计算就需要使用CDC:
:
GetTextMetrics(LPTEXTMETRIClpMetrics)该函数将会填充TEXTMETRIC结构,该结构中的分量可以非常精确的描述字体的各种属性。
2.3使用点、刷子、笔进行绘图
在Windows中画点的方法很简单,只需要调用COLORREFCDC:
:
SetPixel(intx,inty,COLORREFcrColor)就可以在指定点画上指定颜色,同时返回原来的颜色。
COLORREFCDC:
:
GetPixel(intx,inty)可以得到指定点的颜色。
在Windows中应该少使用画点的函数,因为这样做的执行效率比较低。
刷子和画笔在Windows作图中是使用最多的GUI对象,本节在讲解刷子和画笔使用方法的同时也讲述一写基本作图函数。
在画点或画线时系统使用当前DC中的画笔,所以在创建画笔后必须将其选入DC才会在绘图时产生效果。
画笔可以通过CPen对象来产生,通过调用CPen:
:
CreatePen(intnPenStyle,intnWidth,COLORREFcrColor)来创建。
其中nPenStyle指名画笔的风格,可取如下值:
●PS_SOLID实线Createsasolidpen.
●PS_DASH虚线,宽度必须为一Createsadashedpen.Validonlywhenthepenwidthis1orless,indeviceunits.
●PS_DOT点线,宽度必须为一Createsadottedpen.Validonlywhenthepenwidthis1orless,indeviceunits.
●PS_DASHDOT点划线,宽度必须为一Createsapenwithalternatingdashesanddots.Validonlywhenthepenwidthis1orless,indeviceunits.
●PS_DASHDOTDOT双点划线,宽度必须为一Createsapenwithalternatingdashesanddoubledots.Validonlywhenthepenwidthis1orless,indeviceunits.
●PS_NULL空线,使用时什么也不会产生Createsanull