1.预备知识
MFC(Microsoft Foundation Classes)是微软提供的一组用于创建基于Windows的应用程序的类库。在MFC中,CDC类是一个非常重要的绘图类,用于处理所有的绘图操作。
CDC类代表一个设备上下文(Device Context),它是一个用于绘图的虚拟设备。在Windows中,所有的屏幕输出都是通过设备上下文进行的。设备上下文可以看作是一个画布,应用程序可以在上面绘制各种图形,如线条、矩形、椭圆、文本等。
CDC对象提供处理显示器或打印机等设备上下文的成员函数,以及处理与窗口客户区对应的显示上下文的成员。CDC类有很多成员函数,可以用来进行各种绘图操作。例如:
CDC::TextOut()
:用当前选取字体在指定位置写字符串。CDC::LineTo()
:从当前位置到一点画直线,但不包括那个点。CDC::Arc()
:画一段椭圆弧。CDC::PolylineTo()
:画一条或多条直线,并把当前位置移到最后一条直线的终点。
除了绘图函数外,CDC类还有很多与设备上下文相关的操作,如设置背景色、设置文本颜色、设置画刷样式等。
在MFC中,当你创建一个窗口或控件时,MFC会为你创建一个CDC对象,并通过控件的消息处理函数将CDC对象的指针传递给你,可以通过这个CDC对象来绘制各种图形。
2.实验目的
熟悉VS2010的开发平台,并掌握CDC类的使用方法。
3.实验内容
使用MFC(单文档)自动绘制正弦曲线。
要求正弦曲线为黑色且宽度为2,坐标系为红色宽度为1。
4.代码实现
首先由于需要使用sin
函数以及使用常量
π
\pi
π,在Ex2View.cpp
中添加准备如下:
#include <math.h>
// const double pi(52163.0 / 16604);
const double pi2(52163.0 / 33208);
重写CEx2View
的OnDraw
函数如下:
void CEx2View::OnDraw(CDC *pDC)
{
CEx2Doc *pDoc = GetDocument();
ASSERT_VALID(pDoc);
if (!pDoc)
return;
// 生成sin(x)的图像点
short k(550);
CPoint sin_x[550], *p(sin_x + k);
do
{
(--p)->x = 50 + k;
p->y = 200 - 70 * sin(k * pi2 / 50 - pi2);
} while (--k);
CPen axis(PS_SOLID, 1, RGB(255, 0, 0)), fun(PS_SOLID, 2, RGB(0, 0, 0));
pDC->SelectObject(axis);
pDC->SetTextColor(RGB(255, 0, 0));
// 绘制x轴
const short s_1(1), end(11);
CString str(TEXT("-pi/2"));
pDC->TextOutW(40, 205, str);
pDC->MoveTo(50, 195);
pDC->LineTo(50, 200);
pDC->LineTo(100, 200);
str.Format(TEXT("O"));
pDC->TextOutW(90, 205, str);
pDC->MoveTo(100, 195);
pDC->LineTo(100, 200);
while (++k != end)
{
short pos(100 + 50 * k);
pDC->LineTo(pos, 200);
if (k & s_1)
{
str.Format(TEXT("%d/2*pi"), k);
pDC->TextOutW(pos - 25, 205, str);
}
else if (k != 2)
{
str.Format(TEXT("%d*pi"), k >> 1);
pDC->TextOutW(pos - 15, 205, str);
}
else
{
str.Format(TEXT("pi"));
pDC->TextOutW(pos - 5, 205, str);
}
pDC->MoveTo(pos, 195);
pDC->LineTo(pos, 200);
}
// 绘制y轴
pDC->MoveTo(105, 340);
pDC->LineTo(100, 340);
str.Format(TEXT("-2"));
pDC->TextOutW(80, 330, str);
pDC->LineTo(100, 60);
pDC->MoveTo(100, 270);
pDC->LineTo(105, 270);
pDC->MoveTo(100, 140);
pDC->LineTo(105, 140);
pDC->MoveTo(100, 60);
pDC->LineTo(105, 60);
str.Format(TEXT("-1"));
pDC->TextOutW(80, 260, str);
str.Format(TEXT("1"));
pDC->TextOutW(85, 130, str);
str.Format(TEXT("2"));
pDC->TextOutW(85, 50, str);
// 绘制函数图像
pDC->SelectObject(fun);
pDC->Polyline(p, 550);
}
5.运行结果
6.总结
1.实验中遇到的困难
如何设置绘制曲线的颜色及宽度
一开始在CDC
类的文档里未找到对应的api,后查阅资料获知需要借助CPen
类型进行设置。设置方式有两种,一种是直接在构造函数里进行初始化,这里使用第1个有参构造:
CPen::CPen( int nPenStyle, int nWidth, COLORREF crColor );
由于函数图像和坐标轴均为实线,故采用PS_SOLID
风格。而nWidth
和crColor
按实验要求填写即可。另一种方式是利用CreatePen
设置,函数使用如下:
BOOL CPen::CreatePen( int nPenStyle, int nWidth, COLORREF cfColor );
参数与构造函数相同,故不赘述。
如何绘制坐标轴
CDC
类未提供直接画出坐标轴的api,因此按一根根线画出来即可。
如何绘制函数图像
只要点取得足够密集,可以近似使用折线图代替函数图像,绘制折线图调用Polyline
即可。
2.心得体会
通过本次实验,我了解了在MFC中使用CDC
类进行绘图的基本方法。CDC
类是一个非常重要的绘图类,可以实现各种绘图操作,如绘制线条、矩形、椭圆、文本等。在本次实验中,我通过调用CDC
类的函数,成功绘制出了正弦曲线和坐标系。
在实验中,我遇到了一些困难,如如何设置绘制曲线的颜色和宽度,如何绘制坐标轴,以及如何绘制函数图像。通过查阅相关资料,我学会了使用CPen
类型来设置曲线的颜色和宽度,使用CDC
类的线条绘制函数来绘制坐标轴,以及使用Polyline
函数来绘制函数图像。
通过本次实验,我还了解到在MFC中,绘制图形的时候,可以近似使用折线图来代替函数图像。只要取得足够密集的点,就可以通过绘制折线图来实现对函数图像的近似绘制。
通过这次实验,我不仅掌握了使用CDC
类进行绘图的方法,还加深了对MFC开发平台的理解,我会在实际应用中继续探索和学习。