用 vc++ 在屏幕上绘图

52
VC++ VC++ 用用用用用用 用用用用用用 计计计计计计计计

Upload: garth

Post on 12-Jan-2016

288 views

Category:

Documents


0 download

DESCRIPTION

用 VC++ 在屏幕上绘图. 计算机图形学实验. 如何建立一个 VC++ 应用程序框架文件 :. 一 .MFC 绘图函数:. 1.1 生成设备环境对象 设备环境是一个对窗口的绘图表面的属性保持跟踪的数据结构。这些属性包括用于在屏幕上绘图的当前所使用的画笔和画刷。与可以同时使用很多画刷和画笔的艺术家不同,设备环境每次只能用一种画笔和一种画刷。而设备环境对象就是设备环境类的一个实例,它设置了绘图工具,并提供了绘制点,线等简单图形的绘图函数。所有的绘图工作都要通过设备环境对象来实现。. - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: 用 VC++ 在屏幕上绘图

用用 VC++VC++ 在屏幕上绘图在屏幕上绘图计算机图形学实验

Page 2: 用 VC++ 在屏幕上绘图

如何建立一个 VC++ 应用程序框架文件 :

Page 3: 用 VC++ 在屏幕上绘图
Page 4: 用 VC++ 在屏幕上绘图
Page 5: 用 VC++ 在屏幕上绘图
Page 6: 用 VC++ 在屏幕上绘图
Page 7: 用 VC++ 在屏幕上绘图
Page 8: 用 VC++ 在屏幕上绘图
Page 9: 用 VC++ 在屏幕上绘图
Page 10: 用 VC++ 在屏幕上绘图
Page 11: 用 VC++ 在屏幕上绘图
Page 12: 用 VC++ 在屏幕上绘图
Page 13: 用 VC++ 在屏幕上绘图

一 .MFC 绘图函数: 1.1 生成设备环境对象 设备环境是一个对窗口的绘图表面的属性保持跟踪的数据结构。这些属性包括用于在屏幕上绘图的当前所使用的画笔和画刷。与可以同时使用很多画刷和画笔的艺术家不同,设备环境每次只能用一种画笔和一种画刷。而设备环境对象就是设备环境类的一个实例,它设置了绘图工具,并提供了绘制点,线等简单图形的绘图函数。所有的绘图工作都要通过设备环境对象来实现。

Page 14: 用 VC++ 在屏幕上绘图

例如,如果想用一个能够画粗线条的画笔,就必须创建一个新画笔,然后用它取代设备环境中原有的画笔。类似的,如果想用红色的画刷填充一个图形,必须创建一个画刷,并将它选进设备环境,这就是 Windows 程序员在设备环境中取代工具的方式。

Page 15: 用 VC++ 在屏幕上绘图

下面简单介绍几种设备环境 :①.CDC 设备环境对象类,是其它设备环境的基类。

一般情况下,应用程序都要在 View( 视图)类中来进行绘图,视图窗口绘制或者重绘,应用程序框架都要调用视图类的 OnDraw 成员函数。

void CMyDrawView::OnDraw(CDC* pDC)

{

// TODO: add draw code for native data here

}

Page 16: 用 VC++ 在屏幕上绘图

②.CPaintDC 构造函数调用 BeginPaint ,析构函数调用 EndPaint 。

有时在视图窗口以外的窗口(如对话框)中绘制图形,需要调用窗口类的 WM_PAINT 的消息处理函数 OnPaint 来绘制或者重绘窗口,OnPaint 函数必须生成由 CPaintDC 类派生的设备环境对象,如下所示:

void CMyDialog::OnPaint()

{ CPaintDC dc(this);

}

(*)

Page 17: 用 VC++ 在屏幕上绘图

CPaintDC dc(this); 创建一个名为 dc 的设备环境对象,而 this 指向当前的对话框。这样就可以在对话框画图了。

注意:由于视图类窗口也是窗口的一类,所以视图窗口要绘制时也收到 WM_PAINT 的消息,但是 Cview 提供一个 OnPaint 函数,生成和准备设备环境对象,然后将对象传入 OnDraw 函数。只有不从视图类派生的窗口类才需要提供自己的 OnPaint 函数做各种窗口绘图工作。

Page 18: 用 VC++ 在屏幕上绘图

③③..CClientDC 这个设备环境对象仅仅代表了了当前窗口区域。它的构造函数调用 GetDC 函数,它的析构函数调用 ReleaseDC 函数。。

对于在 OnDraw 和 OnPaint 处理器之外的函数中显示图形,必须生成 CClientDC 类成员的设备环境对象。

CMyFunction::Function()

{CClientDC ClientDC(this);

// TODO: Add your message handler code here}

Page 19: 用 VC++ 在屏幕上绘图

1.2 1.2 选择绘图工具画笔,画刷,字体等等。。系统默认的画笔和画刷::默认的画笔画出的线为宽度为 1 像素的黑色实线。默认的画刷是白色的,己用默认的画刷填充图形时,图形的内部填充成白色。。

Page 20: 用 VC++ 在屏幕上绘图

1 . 2 . 1 选用库存的绘图工具CDC::SelectStockObject(int nIndex);

void CMyView::OnDraw(CDC*pDC){pDC->SelectStockObject(WHITE_PEN);pDC->SelectStockObject(GRAY_BRUSH);}

Page 21: 用 VC++ 在屏幕上绘图

11 .. 22 .. 2 2 生成自定义的绘图工具

生成自定义画笔和画刷的基本步骤: (1) 生成画笔( CPen 类)和画刷( CBrush )类的实例; (2) 调用 CPen 类和 CBrush 类的成员函数来初始化画笔和画刷; (3) 将生成的画笔和画刷选入设备环境对象中,并将设备环境对象的原有的画笔和画刷保存在指针中; (4) 调用相应的绘图函数进行绘图; (5) 将原来的画笔和画刷重新选入设备环境对象中中

Page 22: 用 VC++ 在屏幕上绘图

(1) 生成笔( CPen 类)和刷( CBrush )类的实例;

CPen pen; CBrush brush;

(2) 调用 CPen 类和 CBrush 类的成员函数来初始化笔和刷;

画笔的初始化

CPen::CreatePen

Page 23: 用 VC++ 在屏幕上绘图

BOOL CreatePen(int nPenStyle,

int nWidth,COLORREF crColor);

nPenStyle : PS_SOLID

PS_DOT

PS_DASH

PS_DASHDOT

PS_DASHDOTDOT

nWidth : 线的宽度 ( 线宽 >1均产生实线 )

Page 24: 用 VC++ 在屏幕上绘图

crColor参数指定线的颜色,类型为

COLORREF RGB(BYTE bRed ,

BYTE bGreen, BYTE bBlue);

0≤bRed ,bGreen, bBlue≤255

RGB宏功能定义了 16种纯颜色。

Page 25: 用 VC++ 在屏幕上绘图

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);淡青 等。

Page 26: 用 VC++ 在屏幕上绘图
Page 27: 用 VC++ 在屏幕上绘图

画刷的初始化:

BOOL CreateSolidBrush(

COLORREF crColor);

BOOL CreateHatchBrush(

int nIndex,COLORREF crColor);

BOOL CreatePatternBrush(

Cbitmap *pBitmap);

Page 28: 用 VC++ 在屏幕上绘图

nIndex 指定格子的形式。

HS_CROSS 水平垂直交叉阴影

HS_HORIZONAL 水平阴影线

HS_VERTICAL 竖直阴影线

HS_DIAGCROSS 45度交叉阴影对角线

HS_BDIAGONL 以 45度角从左上到右下倾斜的阴影

HS_FDIAGONL 以 45度角从左下到右上倾斜的阴影

Page 29: 用 VC++ 在屏幕上绘图
Page 30: 用 VC++ 在屏幕上绘图

(3) 将生成的笔和刷选入设备环境对象中,并将设备环境对象的原有的笔和刷保存在指针中;;

CDC::SelectObject

CPen * SelectObject (CPen *pPen);

CBrush*SelectObject(Cbrush*pBrush);

注意 :该函数返回的是原来的设备环境对象的指针

Page 31: 用 VC++ 在屏幕上绘图

1.3 设置绘图属性 (1) 背景色 GetBkColor()返回当前的背景色。 SetBkColor(COLORREF crColor) 函数是将当前的背景色设置成参数 crColor 所代表的颜色值。

Page 32: 用 VC++ 在屏幕上绘图

(2)背景方式 GetBkMode() SetBkMode(int nBkMode) nBkMode : OPAQUE TRANSPARENT 这两个函数主要影响 Chord ,Ellipse 和 Pie等闭合图形绘图函数。

Page 33: 用 VC++ 在屏幕上绘图

(3) 绘图方式

GetROP2( );

int SetROP2( int nDrawMode );

绘图方式 (nDrawMode) 组合后像素的颜色

R2_BLACK 总为黑色

R2_WHITE 总为白色

R2_NOT 颜色与屏幕颜色相反

R2_COPYPEN 具有画笔的颜色

R2_NOTCOPYPEN 具有与画笔相反的颜色

Page 34: 用 VC++ 在屏幕上绘图

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);

Page 35: 用 VC++ 在屏幕上绘图

(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

Page 36: 用 VC++ 在屏幕上绘图

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];

Page 37: 用 VC++ 在屏幕上绘图

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);}

Page 38: 用 VC++ 在屏幕上绘图
Page 39: 用 VC++ 在屏幕上绘图

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);

Page 40: 用 VC++ 在屏幕上绘图

(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

Page 41: 用 VC++ 在屏幕上绘图

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);}

Page 42: 用 VC++ 在屏幕上绘图
Page 43: 用 VC++ 在屏幕上绘图

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);

二 .. 实例

Page 44: 用 VC++ 在屏幕上绘图

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);

}

Page 45: 用 VC++ 在屏幕上绘图
Page 46: 用 VC++ 在屏幕上绘图

三 .鼠标消息函数的应用:

Page 47: 用 VC++ 在屏幕上绘图
Page 48: 用 VC++ 在屏幕上绘图

void CMyLineView::OnLButtonDown (UINT nFlags, CPoint point) {m_Oldpoint=point;// 保存光标的当前位置m_Newpoint=point;// 存放画线的起始位置SetCapture(); //捕捉鼠标m_pLMouseDown=TRUE;// 表示鼠标为按下的状态

CRect rect;GetClientRect(&rect);//获得并保存用户区坐标

MyLine 应用程序(鼠标消息的应用)

Page 49: 用 VC++ 在屏幕上绘图

ClientToScreen(&rect); // 用用户区坐标重新计算屏幕坐标

ClipCursor(&rect); //限制光标在用户区内// 默认处理,调用基类消息处理函数CView::OnLButtonDown(nFlags, point);}

Page 50: 用 VC++ 在屏幕上绘图

void CMyLineView::OnMouseMove

(UINT nFlags, CPoint point)

{

SetCursor(m_HCursor); // 设置自定义光标

if(m_pLMouseDown)

{CClientDC dc(this);

dc.SetROP2(R2_NOT); // 设置绘图模式,以屏幕颜色的相反色绘图

Page 51: 用 VC++ 在屏幕上绘图

// 以重绘的方式擦除前一个 OnMouseMove 绘制的直线

dc.MoveTo(m_Newpoint);

dc.LineTo(m_Oldpoint);

dc.MoveTo(m_Newpoint); // 重新位置到当前位置画一条直线

dc.LineTo(point);

m_Oldpoint=point; // 存放当前鼠标位置

}

CView::OnMouseMove(nFlags, point);}

Page 52: 用 VC++ 在屏幕上绘图

void CMyLineView::OnLButtonUp

(UINT nFlags, CPoint point)

{if(m_pLMouseDown)

{

m_pLMouseDown=FALSE;//标志鼠标释放

ReleaseCapture();//释放鼠标捕捉

ClipCursor(NULL);// 使光标可以随意移动 }

CView::OnLButtonUp(nFlags, point);}