用 vc++ 在屏幕上绘图
DESCRIPTION
用 VC++ 在屏幕上绘图. 计算机图形学实验. 如何建立一个 VC++ 应用程序框架文件 :. 一 .MFC 绘图函数:. 1.1 生成设备环境对象 设备环境是一个对窗口的绘图表面的属性保持跟踪的数据结构。这些属性包括用于在屏幕上绘图的当前所使用的画笔和画刷。与可以同时使用很多画刷和画笔的艺术家不同,设备环境每次只能用一种画笔和一种画刷。而设备环境对象就是设备环境类的一个实例,它设置了绘图工具,并提供了绘制点,线等简单图形的绘图函数。所有的绘图工作都要通过设备环境对象来实现。. - PowerPoint PPT PresentationTRANSCRIPT
用用 VC++VC++ 在屏幕上绘图在屏幕上绘图计算机图形学实验
如何建立一个 VC++ 应用程序框架文件 :
一 .MFC 绘图函数: 1.1 生成设备环境对象 设备环境是一个对窗口的绘图表面的属性保持跟踪的数据结构。这些属性包括用于在屏幕上绘图的当前所使用的画笔和画刷。与可以同时使用很多画刷和画笔的艺术家不同,设备环境每次只能用一种画笔和一种画刷。而设备环境对象就是设备环境类的一个实例,它设置了绘图工具,并提供了绘制点,线等简单图形的绘图函数。所有的绘图工作都要通过设备环境对象来实现。
例如,如果想用一个能够画粗线条的画笔,就必须创建一个新画笔,然后用它取代设备环境中原有的画笔。类似的,如果想用红色的画刷填充一个图形,必须创建一个画刷,并将它选进设备环境,这就是 Windows 程序员在设备环境中取代工具的方式。
下面简单介绍几种设备环境 :①.CDC 设备环境对象类,是其它设备环境的基类。
一般情况下,应用程序都要在 View( 视图)类中来进行绘图,视图窗口绘制或者重绘,应用程序框架都要调用视图类的 OnDraw 成员函数。
void CMyDrawView::OnDraw(CDC* pDC)
{
// TODO: add draw code for native data here
}
②.CPaintDC 构造函数调用 BeginPaint ,析构函数调用 EndPaint 。
有时在视图窗口以外的窗口(如对话框)中绘制图形,需要调用窗口类的 WM_PAINT 的消息处理函数 OnPaint 来绘制或者重绘窗口,OnPaint 函数必须生成由 CPaintDC 类派生的设备环境对象,如下所示:
void CMyDialog::OnPaint()
{ CPaintDC dc(this);
}
(*)
CPaintDC dc(this); 创建一个名为 dc 的设备环境对象,而 this 指向当前的对话框。这样就可以在对话框画图了。
注意:由于视图类窗口也是窗口的一类,所以视图窗口要绘制时也收到 WM_PAINT 的消息,但是 Cview 提供一个 OnPaint 函数,生成和准备设备环境对象,然后将对象传入 OnDraw 函数。只有不从视图类派生的窗口类才需要提供自己的 OnPaint 函数做各种窗口绘图工作。
③③..CClientDC 这个设备环境对象仅仅代表了了当前窗口区域。它的构造函数调用 GetDC 函数,它的析构函数调用 ReleaseDC 函数。。
对于在 OnDraw 和 OnPaint 处理器之外的函数中显示图形,必须生成 CClientDC 类成员的设备环境对象。
CMyFunction::Function()
{CClientDC ClientDC(this);
// TODO: Add your message handler code here}
1.2 1.2 选择绘图工具画笔,画刷,字体等等。。系统默认的画笔和画刷::默认的画笔画出的线为宽度为 1 像素的黑色实线。默认的画刷是白色的,己用默认的画刷填充图形时,图形的内部填充成白色。。
1 . 2 . 1 选用库存的绘图工具CDC::SelectStockObject(int nIndex);
void CMyView::OnDraw(CDC*pDC){pDC->SelectStockObject(WHITE_PEN);pDC->SelectStockObject(GRAY_BRUSH);}
11 .. 22 .. 2 2 生成自定义的绘图工具
生成自定义画笔和画刷的基本步骤: (1) 生成画笔( CPen 类)和画刷( CBrush )类的实例; (2) 调用 CPen 类和 CBrush 类的成员函数来初始化画笔和画刷; (3) 将生成的画笔和画刷选入设备环境对象中,并将设备环境对象的原有的画笔和画刷保存在指针中; (4) 调用相应的绘图函数进行绘图; (5) 将原来的画笔和画刷重新选入设备环境对象中中
(1) 生成笔( CPen 类)和刷( CBrush )类的实例;
CPen pen; CBrush brush;
(2) 调用 CPen 类和 CBrush 类的成员函数来初始化笔和刷;
画笔的初始化
CPen::CreatePen
BOOL CreatePen(int nPenStyle,
int nWidth,COLORREF crColor);
nPenStyle : PS_SOLID
PS_DOT
PS_DASH
PS_DASHDOT
PS_DASHDOTDOT
nWidth : 线的宽度 ( 线宽 >1均产生实线 )
crColor参数指定线的颜色,类型为
COLORREF RGB(BYTE bRed ,
BYTE bGreen, BYTE bBlue);
0≤bRed ,bGreen, bBlue≤255
RGB宏功能定义了 16种纯颜色。
RGB(0,0,0); 黑色 RGB(255,255,255); 白色
RGB(128,0,0);深红 RGB(255,0,0);淡红
RGB(0, 128,0);深绿 RGB(0, 255,0);淡绿
RGB(0,0,128);深蓝 RGB(0,0.255);淡蓝
RGB(128,128,0);深黄
RGB(255,255,0);淡黄
RGB(0,128,128);深青
RGB(0,255,255);淡青 等。
画刷的初始化:
BOOL CreateSolidBrush(
COLORREF crColor);
BOOL CreateHatchBrush(
int nIndex,COLORREF crColor);
BOOL CreatePatternBrush(
Cbitmap *pBitmap);
nIndex 指定格子的形式。
HS_CROSS 水平垂直交叉阴影
HS_HORIZONAL 水平阴影线
HS_VERTICAL 竖直阴影线
HS_DIAGCROSS 45度交叉阴影对角线
HS_BDIAGONL 以 45度角从左上到右下倾斜的阴影
HS_FDIAGONL 以 45度角从左下到右上倾斜的阴影
(3) 将生成的笔和刷选入设备环境对象中,并将设备环境对象的原有的笔和刷保存在指针中;;
CDC::SelectObject
CPen * SelectObject (CPen *pPen);
CBrush*SelectObject(Cbrush*pBrush);
注意 :该函数返回的是原来的设备环境对象的指针
1.3 设置绘图属性 (1) 背景色 GetBkColor()返回当前的背景色。 SetBkColor(COLORREF crColor) 函数是将当前的背景色设置成参数 crColor 所代表的颜色值。
(2)背景方式 GetBkMode() SetBkMode(int nBkMode) nBkMode : OPAQUE TRANSPARENT 这两个函数主要影响 Chord ,Ellipse 和 Pie等闭合图形绘图函数。
(3) 绘图方式
GetROP2( );
int SetROP2( int nDrawMode );
绘图方式 (nDrawMode) 组合后像素的颜色
R2_BLACK 总为黑色
R2_WHITE 总为白色
R2_NOT 颜色与屏幕颜色相反
R2_COPYPEN 具有画笔的颜色
R2_NOTCOPYPEN 具有与画笔相反的颜色
1.4 1.4 几种常用的绘图函数 1. 画线函数 (1) 成员函数 MoveTo: 将当前的绘图位置移到
point 指定的坐标处 CPoint MoveTo(int x,int y); CPoint MoveTo(POINT point); (2) 成员函数 LineTo 在当前的绘图位置上与一个新坐标点之间画一
条直线,这个新的坐标点将变成当前位置。 BOOL LineTo (int x,int y); BOOL LineTo (POINT);
(3) 成员函数 Arc
画一个椭圆形的弧线,它是一个指定边界矩形内一个内切椭圆的一段。
BOOL Arc(int x1,int y1,int x2,
int y2,int x3,int y3,int x4,int y4);
(4) 成员函数 PolylBezier
BOOL PolyBezier(
const POINT *lpPoints,int nCount);
绘制由几个控制点所决定的多条 Bezier曲线
一般给定的点为所画样条函数的 3倍加 1
void CMyDrawView::OnDraw(CDC *pDC)
{
CPen Pen;
CPen *OldPen;
Pen.CreatePen(PS_SOLID,4,RGB(0,0,0));
OldPen=pDC->SelectObject(&Pen);
POINT points[7];
points[0].x=100; points[0].y=100;
points[1].x=200; points[1].y=200;
points[2].x=300; points[2].y=200;
points[3].x=400; points[3].y=300;
points[4].x=500; points[4].y=400;
points[5].x=300; points[5].y=400;
points[6].x=200; points[6].y=400;
pDC->PolyBezier(points,7);
pDC-> SelectObject(OldPen);}
2. 画简单的闭合图形
(1) Rectangle BOOL Rectangle(int x1,int y1, int x2,int y2); (2) Ellipse BOOL Ellipse(int x1,int y1, int x2,int y2);
(3) Chord( 一个椭圆和一条直线相交的图形 ) BOOL Chord(int x1,int y1,int x2,int y2,int x3,int y3,int x4,int y4); (4) Polygon
BOOL Polygon( LPPOINT lpPoints, int nCount );
LpPoints 是一个指向 CPoint 实例的 POINT数组的指针
其中 nCount>2
void CMyTestView::OnDraw(CDC *pDC)
{CPen Pen; CPen *OldPen;
CBrush Brush;CBrush *OldBrush;
Pen.CreatePen(PS_SOLID,5,RGB(0,0,0));
Brush.CreateSolidBrush(RGB(0,255,0));
OldPen=pDC->SelectObject(&Pen);
OldBrush=pDC->SelectObject(&Brush);
pDC->Chord(120,20,420,450,100,0,400,200);
pDC->SelectObject(OldPen);
pDC->SelectObject(OldBrush);}
void CMyTestView::OnDraw(CDC *pDC)
{CPen Pen;CPen *OldPen;
Pen.CreatePen(PS_SOLID,2,RGB(255,255,0));
CBrush Brush; CBrush *OldBrush;
Brush.CreateHatchBrush(4,RGB(0,200,200));
OldPen= pDC->SelectObject(&Pen);
OldBrush=pDC->SelectObject(&Brush);
二 .. 实例
pDC->RoundRect(100,100,300,300,30,60);
pDC->SetBkColor(RGB(255,255,0));
pDC->SetBkMode(OPAQUE);
pDC->Ellipse(300,100,500,200);
pDC->Pie(300,100,600,400,300,400,600,400);
pDC->SelectObject(OldPen);
pDC->SelectObject(OldBrush);
}
三 .鼠标消息函数的应用:
void CMyLineView::OnLButtonDown (UINT nFlags, CPoint point) {m_Oldpoint=point;// 保存光标的当前位置m_Newpoint=point;// 存放画线的起始位置SetCapture(); //捕捉鼠标m_pLMouseDown=TRUE;// 表示鼠标为按下的状态
CRect rect;GetClientRect(&rect);//获得并保存用户区坐标
MyLine 应用程序(鼠标消息的应用)
ClientToScreen(&rect); // 用用户区坐标重新计算屏幕坐标
ClipCursor(&rect); //限制光标在用户区内// 默认处理,调用基类消息处理函数CView::OnLButtonDown(nFlags, point);}
void CMyLineView::OnMouseMove
(UINT nFlags, CPoint point)
{
SetCursor(m_HCursor); // 设置自定义光标
if(m_pLMouseDown)
{CClientDC dc(this);
dc.SetROP2(R2_NOT); // 设置绘图模式,以屏幕颜色的相反色绘图
// 以重绘的方式擦除前一个 OnMouseMove 绘制的直线
dc.MoveTo(m_Newpoint);
dc.LineTo(m_Oldpoint);
dc.MoveTo(m_Newpoint); // 重新位置到当前位置画一条直线
dc.LineTo(point);
m_Oldpoint=point; // 存放当前鼠标位置
}
CView::OnMouseMove(nFlags, point);}
void CMyLineView::OnLButtonUp
(UINT nFlags, CPoint point)
{if(m_pLMouseDown)
{
m_pLMouseDown=FALSE;//标志鼠标释放
ReleaseCapture();//释放鼠标捕捉
ClipCursor(NULL);// 使光标可以随意移动 }
CView::OnLButtonUp(nFlags, point);}