前两张写了mfc的一些基础操作。这一章写点关于绘图的,这应该是计算机图形学的基础内容了把。好了,直接进入正题,MFC的绘图个人觉得跟windows编程的绘图相差不了多少,命名上有点区别,mfc中都是以C开头,windows以H开头,在mfc中可以完全调用windows的写法,这是完全允许的,不过为了使用面向对象的机制,而不是简单的带类的C语言,我们还是尽量以mfc中的类库为主。
首先,要介绍一个概念dc,dc的中文名称叫设备描述表,(Device Content),下面是百度百科的介绍:
设备描述表是一个定义一组图形对象及其属性、影响输出的图形方式(数据)结构。windows提供设备描述表,用于应用程序和物理设备之间进行交互,从而提供了应用程序设计的平台无关性。设备描述表又称为设备上下文,或者设备环境。
获取dc方法:
CDC *dc; dc = GetDC(); dc->Rectangle(250, 250, 350, 350); dc->DeleteDC();
上述代码我们就获取了dc,并画了一个矩形,最后释放了资源。mfc中很重要的一点,当然也是c++中很重要的,对象必须要及时释放,不然很可能造成内存泄漏,轻者运行缓慢,重者直接占满内存也是可能的。
还有其它一些dc,例如CPaintDC,它只能用于在OnPaint中处理使用的,还有CClientDC,获取的是客户端的DC,CWindowDC,是整个窗口的DC.
有了这个dc,我们就可以做一些更复杂的操作。比如永远的Hello World ,使用TextOut函数就可以打印出字符串。例:
CDC *dc; dc = GetDC(); dc->TextOut(200, 200, _T("Hello World!")); dc->DeleteDC();这样我们就在(300,200)位置打印出了Hello World字样。坐标系统采用的是左上角为(0,0),关于TextOut还有一些常用的函数:
dc->SetTextColor(RGB(255, 0, 0)); //字体色
dc->SetBkColor(RGB(0, 255, 255));//背景色
//dc->SetBkMode(TRANSPARENT);//背景透明
dc->TextOut(200, 200, _T("Hello World!"));
此时我们的字体使用的是系统默认字体。还可以使用别的字体,在打印前创建一个字体,并将字体选入dc,之后再打印,字体就变了。
创建时第一个参数为字体的大小,第二个参数为字体名,要确认在系统中存在该名字的字体哦~
CFont font;
font.CreatePointFont(300, _T("楷体"));
dc->SelectObject(&font);
最后别忘了删除该对象呐DeleteObject(font);
也许这个还不能满足你的需要,别担心,还有更详细的。我们可以使用一个结构体LOGFONT
先看下结构体的成员,这么多,应该可以满足需求了ba
typedef struct tagLOGFONTA
{
LONG lfHeight;
LONG lfWidth;
LONG lfEscapement;
LONG lfOrientation;
LONG lfWeight;
BYTE lfItalic;
BYTE lfUnderline;
BYTE lfStrikeOut;
BYTE lfCharSet;
BYTE lfOutPrecision;
BYTE lfClipPrecision;
BYTE lfQuality;
BYTE lfPitchAndFamily;
CHAR lfFaceName[LF_FACESIZE];
} LOGFONTA
lfHeight:指定逻辑单位的字符或者字符元高度。
lfWidth:指定逻辑单位的字体字符的平均宽度。
lfEscapement:指定每行文本输出时相对于设备x轴的角度,其单位为1/10度。
lfOrientation:指定字符基线相对于设备x轴的角度,其单位为1/10度。此值在Win9X中和lfEscapement具有相同的值,而在WinNT下有时候可能不同
lfWeight:指定字体的重量,Windows中字体重量表示字体的粗细程度,其范围在0~1000之间,正常为400,粗体为700,若此值为空,则使用默认的字体重量
lfItalic:此值为TRUE时,字体为斜体。
lfUnderline:此值为TRUE时,字体带下划线。
lfStrikeOut:此值为TRUE时,字体带删除线。
lfCharSet:指定所使用的字符集,如GB2312_CHARSET,CHINESEBIG5_CHARSET等。
lfOutPrecision:指定输出精度,它定义了输出与所要求的字体高度、宽度、字符方向及字体类型等相接近的程度。
lfClipPrecision:指定剪辑精度,它定义了当字符的一部分超过剪辑区域时对字符的剪辑方式。
lfQuality:指定输出质量,它定义了GDI在匹配逻辑字体属性到实际的物理字体时所使用的方式。
lfPitchAndFamily:指定字体的字符间距和族。
lfFaceName:指向NULL结尾的字符串的指针,此字符串即为所使用的字体名称,其长度不能超过32个字符,如果为空,则使用系统默认的字体。
看到这么多参数,,呃~一脸懵逼,二连茫然。不过,用起来还是很简单的,你只需要更改一些你需要的,其它都使用默认值就好了。比如:
CDC *dc; dc = GetDC(); LOGFONT lf; memset(&lf, 0, sizeof(LOGFONT)); lf.lfUnderline = TRUE; lf.lfWeight = 300; lf.lfHeight = 50; CFont font; font.CreateFontIndirect(&lf); dc->SelectObject(&font); dc->TextOut(200, 200, _T("Hello World!")); dc->DeleteDC(); DeleteObject(font);上述代码创建了一个带下划线的,且长度为300,高度为50。其他参数自己可以参照上面的进行尝试啊,对了,使用结构体前记得清零啊~
关于TextOut暂时就这样。
下面是开始真正绘图:
首先从一条直线开始
dc->MoveTo(200, 200);
dc->LineTo(400, 400);
这样就绘制了一条从(200,200)到(400,400)的直线
这时我们是采用的默认的画笔。一个美丽的画当然需要漂亮的画笔,所以我们可以多一些选择,自己创建画笔
CPen pen; pen.CreatePen(PS_SOLID, 3, RGB(255, 0,0)); dc->SelectObject(&pen); dc->MoveTo(200, 200); dc->LineTo(400, 400); DeleteObject(pen);这样我们就创建了一个实心的,宽度为3像素,颜色为红的笔。同上TextOut,我们也有LOGPEN,不过它也只有三个参数,还是直接CreatePen更简单。
笔的样式有
PS_SOLID 实线
PS_DASH 虚线
PS_DOT 点线
PS_DASHDOT 点化线
PS_DASHDOTDOT 双点化线
还有画刷,当我们画一个封闭图形时,需要画刷来填充颜色,画刷的使用方法如下:
CBrush brush; brush.CreateSolidBrush(RGB( 255, 0, 0)); dc->SelectObject(&brush); dc->Rectangle(50, 50, 300, 300);与pen差不多。Rectangle代表矩形,左上角为(50,50),右下角为(300,300)。且将一个画刷选进去了,所以是红色的矩形。但是它的边框为黑色,如果需要去掉边框,需要将一个透明的笔选进去。dc->SelectStockObject(NULL_PEN);
SelectStockObject函数稍微讲一下,它是用来选择系统定义好的对象,如WHITE_BRUSH,WHITE_PEN等等。
有了这个Rectangle,我们还有类似的RoundRect(50, 50, 300, 300, 50, 50);代表一个圆角矩形,前四个参数跟Rectangle参数一样,后两个用来控制弧度的。
Ellipse,椭圆,参数与Rectangle完全相同,其实就是一个矩形内切的椭圆。还有ARC弧线,ArcTo等等。
到此,基础的绘图就算完成了。