您的位置:首页 > 其它

卷三 绘图的艺术

2016-07-08 09:39 302 查看
前两张写了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等等。

到此,基础的绘图就算完成了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: