Download - 用 VC++ 在屏幕上绘图
![Page 1: 用 VC++ 在屏幕上绘图](https://reader036.vdocuments.mx/reader036/viewer/2022081415/568144d8550346895db1a3f0/html5/thumbnails/1.jpg)
用用 VC++VC++ 在屏幕上绘图在屏幕上绘图计算机图形学实验
![Page 2: 用 VC++ 在屏幕上绘图](https://reader036.vdocuments.mx/reader036/viewer/2022081415/568144d8550346895db1a3f0/html5/thumbnails/2.jpg)
如何建立一个 VC++ 应用程序框架文件 :
![Page 3: 用 VC++ 在屏幕上绘图](https://reader036.vdocuments.mx/reader036/viewer/2022081415/568144d8550346895db1a3f0/html5/thumbnails/3.jpg)
![Page 4: 用 VC++ 在屏幕上绘图](https://reader036.vdocuments.mx/reader036/viewer/2022081415/568144d8550346895db1a3f0/html5/thumbnails/4.jpg)
![Page 5: 用 VC++ 在屏幕上绘图](https://reader036.vdocuments.mx/reader036/viewer/2022081415/568144d8550346895db1a3f0/html5/thumbnails/5.jpg)
![Page 6: 用 VC++ 在屏幕上绘图](https://reader036.vdocuments.mx/reader036/viewer/2022081415/568144d8550346895db1a3f0/html5/thumbnails/6.jpg)
![Page 7: 用 VC++ 在屏幕上绘图](https://reader036.vdocuments.mx/reader036/viewer/2022081415/568144d8550346895db1a3f0/html5/thumbnails/7.jpg)
![Page 8: 用 VC++ 在屏幕上绘图](https://reader036.vdocuments.mx/reader036/viewer/2022081415/568144d8550346895db1a3f0/html5/thumbnails/8.jpg)
![Page 9: 用 VC++ 在屏幕上绘图](https://reader036.vdocuments.mx/reader036/viewer/2022081415/568144d8550346895db1a3f0/html5/thumbnails/9.jpg)
![Page 10: 用 VC++ 在屏幕上绘图](https://reader036.vdocuments.mx/reader036/viewer/2022081415/568144d8550346895db1a3f0/html5/thumbnails/10.jpg)
![Page 11: 用 VC++ 在屏幕上绘图](https://reader036.vdocuments.mx/reader036/viewer/2022081415/568144d8550346895db1a3f0/html5/thumbnails/11.jpg)
![Page 12: 用 VC++ 在屏幕上绘图](https://reader036.vdocuments.mx/reader036/viewer/2022081415/568144d8550346895db1a3f0/html5/thumbnails/12.jpg)
![Page 13: 用 VC++ 在屏幕上绘图](https://reader036.vdocuments.mx/reader036/viewer/2022081415/568144d8550346895db1a3f0/html5/thumbnails/13.jpg)
一 .MFC 绘图函数: 1.1 生成设备环境对象 设备环境是一个对窗口的绘图表面的属性保持跟踪的数据结构。这些属性包括用于在屏幕上绘图的当前所使用的画笔和画刷。与可以同时使用很多画刷和画笔的艺术家不同,设备环境每次只能用一种画笔和一种画刷。而设备环境对象就是设备环境类的一个实例,它设置了绘图工具,并提供了绘制点,线等简单图形的绘图函数。所有的绘图工作都要通过设备环境对象来实现。
![Page 14: 用 VC++ 在屏幕上绘图](https://reader036.vdocuments.mx/reader036/viewer/2022081415/568144d8550346895db1a3f0/html5/thumbnails/14.jpg)
例如,如果想用一个能够画粗线条的画笔,就必须创建一个新画笔,然后用它取代设备环境中原有的画笔。类似的,如果想用红色的画刷填充一个图形,必须创建一个画刷,并将它选进设备环境,这就是 Windows 程序员在设备环境中取代工具的方式。
![Page 15: 用 VC++ 在屏幕上绘图](https://reader036.vdocuments.mx/reader036/viewer/2022081415/568144d8550346895db1a3f0/html5/thumbnails/15.jpg)
下面简单介绍几种设备环境 :①.CDC 设备环境对象类,是其它设备环境的基类。
一般情况下,应用程序都要在 View( 视图)类中来进行绘图,视图窗口绘制或者重绘,应用程序框架都要调用视图类的 OnDraw 成员函数。
void CMyDrawView::OnDraw(CDC* pDC)
{
// TODO: add draw code for native data here
}
![Page 16: 用 VC++ 在屏幕上绘图](https://reader036.vdocuments.mx/reader036/viewer/2022081415/568144d8550346895db1a3f0/html5/thumbnails/16.jpg)
②.CPaintDC 构造函数调用 BeginPaint ,析构函数调用 EndPaint 。
有时在视图窗口以外的窗口(如对话框)中绘制图形,需要调用窗口类的 WM_PAINT 的消息处理函数 OnPaint 来绘制或者重绘窗口,OnPaint 函数必须生成由 CPaintDC 类派生的设备环境对象,如下所示:
void CMyDialog::OnPaint()
{ CPaintDC dc(this);
}
(*)
![Page 17: 用 VC++ 在屏幕上绘图](https://reader036.vdocuments.mx/reader036/viewer/2022081415/568144d8550346895db1a3f0/html5/thumbnails/17.jpg)
CPaintDC dc(this); 创建一个名为 dc 的设备环境对象,而 this 指向当前的对话框。这样就可以在对话框画图了。
注意:由于视图类窗口也是窗口的一类,所以视图窗口要绘制时也收到 WM_PAINT 的消息,但是 Cview 提供一个 OnPaint 函数,生成和准备设备环境对象,然后将对象传入 OnDraw 函数。只有不从视图类派生的窗口类才需要提供自己的 OnPaint 函数做各种窗口绘图工作。
![Page 18: 用 VC++ 在屏幕上绘图](https://reader036.vdocuments.mx/reader036/viewer/2022081415/568144d8550346895db1a3f0/html5/thumbnails/18.jpg)
③③..CClientDC 这个设备环境对象仅仅代表了了当前窗口区域。它的构造函数调用 GetDC 函数,它的析构函数调用 ReleaseDC 函数。。
对于在 OnDraw 和 OnPaint 处理器之外的函数中显示图形,必须生成 CClientDC 类成员的设备环境对象。
CMyFunction::Function()
{CClientDC ClientDC(this);
// TODO: Add your message handler code here}
![Page 19: 用 VC++ 在屏幕上绘图](https://reader036.vdocuments.mx/reader036/viewer/2022081415/568144d8550346895db1a3f0/html5/thumbnails/19.jpg)
1.2 1.2 选择绘图工具画笔,画刷,字体等等。。系统默认的画笔和画刷::默认的画笔画出的线为宽度为 1 像素的黑色实线。默认的画刷是白色的,己用默认的画刷填充图形时,图形的内部填充成白色。。
![Page 20: 用 VC++ 在屏幕上绘图](https://reader036.vdocuments.mx/reader036/viewer/2022081415/568144d8550346895db1a3f0/html5/thumbnails/20.jpg)
1 . 2 . 1 选用库存的绘图工具CDC::SelectStockObject(int nIndex);
void CMyView::OnDraw(CDC*pDC){pDC->SelectStockObject(WHITE_PEN);pDC->SelectStockObject(GRAY_BRUSH);}
![Page 21: 用 VC++ 在屏幕上绘图](https://reader036.vdocuments.mx/reader036/viewer/2022081415/568144d8550346895db1a3f0/html5/thumbnails/21.jpg)
11 .. 22 .. 2 2 生成自定义的绘图工具
生成自定义画笔和画刷的基本步骤: (1) 生成画笔( CPen 类)和画刷( CBrush )类的实例; (2) 调用 CPen 类和 CBrush 类的成员函数来初始化画笔和画刷; (3) 将生成的画笔和画刷选入设备环境对象中,并将设备环境对象的原有的画笔和画刷保存在指针中; (4) 调用相应的绘图函数进行绘图; (5) 将原来的画笔和画刷重新选入设备环境对象中中
![Page 22: 用 VC++ 在屏幕上绘图](https://reader036.vdocuments.mx/reader036/viewer/2022081415/568144d8550346895db1a3f0/html5/thumbnails/22.jpg)
(1) 生成笔( CPen 类)和刷( CBrush )类的实例;
CPen pen; CBrush brush;
(2) 调用 CPen 类和 CBrush 类的成员函数来初始化笔和刷;
画笔的初始化
CPen::CreatePen
![Page 23: 用 VC++ 在屏幕上绘图](https://reader036.vdocuments.mx/reader036/viewer/2022081415/568144d8550346895db1a3f0/html5/thumbnails/23.jpg)
BOOL CreatePen(int nPenStyle,
int nWidth,COLORREF crColor);
nPenStyle : PS_SOLID
PS_DOT
PS_DASH
PS_DASHDOT
PS_DASHDOTDOT
nWidth : 线的宽度 ( 线宽 >1均产生实线 )
![Page 24: 用 VC++ 在屏幕上绘图](https://reader036.vdocuments.mx/reader036/viewer/2022081415/568144d8550346895db1a3f0/html5/thumbnails/24.jpg)
crColor参数指定线的颜色,类型为
COLORREF RGB(BYTE bRed ,
BYTE bGreen, BYTE bBlue);
0≤bRed ,bGreen, bBlue≤255
RGB宏功能定义了 16种纯颜色。
![Page 25: 用 VC++ 在屏幕上绘图](https://reader036.vdocuments.mx/reader036/viewer/2022081415/568144d8550346895db1a3f0/html5/thumbnails/25.jpg)
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++ 在屏幕上绘图](https://reader036.vdocuments.mx/reader036/viewer/2022081415/568144d8550346895db1a3f0/html5/thumbnails/26.jpg)
![Page 27: 用 VC++ 在屏幕上绘图](https://reader036.vdocuments.mx/reader036/viewer/2022081415/568144d8550346895db1a3f0/html5/thumbnails/27.jpg)
画刷的初始化:
BOOL CreateSolidBrush(
COLORREF crColor);
BOOL CreateHatchBrush(
int nIndex,COLORREF crColor);
BOOL CreatePatternBrush(
Cbitmap *pBitmap);
![Page 28: 用 VC++ 在屏幕上绘图](https://reader036.vdocuments.mx/reader036/viewer/2022081415/568144d8550346895db1a3f0/html5/thumbnails/28.jpg)
nIndex 指定格子的形式。
HS_CROSS 水平垂直交叉阴影
HS_HORIZONAL 水平阴影线
HS_VERTICAL 竖直阴影线
HS_DIAGCROSS 45度交叉阴影对角线
HS_BDIAGONL 以 45度角从左上到右下倾斜的阴影
HS_FDIAGONL 以 45度角从左下到右上倾斜的阴影
![Page 29: 用 VC++ 在屏幕上绘图](https://reader036.vdocuments.mx/reader036/viewer/2022081415/568144d8550346895db1a3f0/html5/thumbnails/29.jpg)
![Page 30: 用 VC++ 在屏幕上绘图](https://reader036.vdocuments.mx/reader036/viewer/2022081415/568144d8550346895db1a3f0/html5/thumbnails/30.jpg)
(3) 将生成的笔和刷选入设备环境对象中,并将设备环境对象的原有的笔和刷保存在指针中;;
CDC::SelectObject
CPen * SelectObject (CPen *pPen);
CBrush*SelectObject(Cbrush*pBrush);
注意 :该函数返回的是原来的设备环境对象的指针
![Page 31: 用 VC++ 在屏幕上绘图](https://reader036.vdocuments.mx/reader036/viewer/2022081415/568144d8550346895db1a3f0/html5/thumbnails/31.jpg)
1.3 设置绘图属性 (1) 背景色 GetBkColor()返回当前的背景色。 SetBkColor(COLORREF crColor) 函数是将当前的背景色设置成参数 crColor 所代表的颜色值。
![Page 32: 用 VC++ 在屏幕上绘图](https://reader036.vdocuments.mx/reader036/viewer/2022081415/568144d8550346895db1a3f0/html5/thumbnails/32.jpg)
(2)背景方式 GetBkMode() SetBkMode(int nBkMode) nBkMode : OPAQUE TRANSPARENT 这两个函数主要影响 Chord ,Ellipse 和 Pie等闭合图形绘图函数。
![Page 33: 用 VC++ 在屏幕上绘图](https://reader036.vdocuments.mx/reader036/viewer/2022081415/568144d8550346895db1a3f0/html5/thumbnails/33.jpg)
(3) 绘图方式
GetROP2( );
int SetROP2( int nDrawMode );
绘图方式 (nDrawMode) 组合后像素的颜色
R2_BLACK 总为黑色
R2_WHITE 总为白色
R2_NOT 颜色与屏幕颜色相反
R2_COPYPEN 具有画笔的颜色
R2_NOTCOPYPEN 具有与画笔相反的颜色
![Page 34: 用 VC++ 在屏幕上绘图](https://reader036.vdocuments.mx/reader036/viewer/2022081415/568144d8550346895db1a3f0/html5/thumbnails/34.jpg)
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++ 在屏幕上绘图](https://reader036.vdocuments.mx/reader036/viewer/2022081415/568144d8550346895db1a3f0/html5/thumbnails/35.jpg)
(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++ 在屏幕上绘图](https://reader036.vdocuments.mx/reader036/viewer/2022081415/568144d8550346895db1a3f0/html5/thumbnails/36.jpg)
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++ 在屏幕上绘图](https://reader036.vdocuments.mx/reader036/viewer/2022081415/568144d8550346895db1a3f0/html5/thumbnails/37.jpg)
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++ 在屏幕上绘图](https://reader036.vdocuments.mx/reader036/viewer/2022081415/568144d8550346895db1a3f0/html5/thumbnails/38.jpg)
![Page 39: 用 VC++ 在屏幕上绘图](https://reader036.vdocuments.mx/reader036/viewer/2022081415/568144d8550346895db1a3f0/html5/thumbnails/39.jpg)
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++ 在屏幕上绘图](https://reader036.vdocuments.mx/reader036/viewer/2022081415/568144d8550346895db1a3f0/html5/thumbnails/40.jpg)
(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++ 在屏幕上绘图](https://reader036.vdocuments.mx/reader036/viewer/2022081415/568144d8550346895db1a3f0/html5/thumbnails/41.jpg)
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++ 在屏幕上绘图](https://reader036.vdocuments.mx/reader036/viewer/2022081415/568144d8550346895db1a3f0/html5/thumbnails/42.jpg)
![Page 43: 用 VC++ 在屏幕上绘图](https://reader036.vdocuments.mx/reader036/viewer/2022081415/568144d8550346895db1a3f0/html5/thumbnails/43.jpg)
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++ 在屏幕上绘图](https://reader036.vdocuments.mx/reader036/viewer/2022081415/568144d8550346895db1a3f0/html5/thumbnails/44.jpg)
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++ 在屏幕上绘图](https://reader036.vdocuments.mx/reader036/viewer/2022081415/568144d8550346895db1a3f0/html5/thumbnails/45.jpg)
![Page 46: 用 VC++ 在屏幕上绘图](https://reader036.vdocuments.mx/reader036/viewer/2022081415/568144d8550346895db1a3f0/html5/thumbnails/46.jpg)
三 .鼠标消息函数的应用:
![Page 47: 用 VC++ 在屏幕上绘图](https://reader036.vdocuments.mx/reader036/viewer/2022081415/568144d8550346895db1a3f0/html5/thumbnails/47.jpg)
![Page 48: 用 VC++ 在屏幕上绘图](https://reader036.vdocuments.mx/reader036/viewer/2022081415/568144d8550346895db1a3f0/html5/thumbnails/48.jpg)
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++ 在屏幕上绘图](https://reader036.vdocuments.mx/reader036/viewer/2022081415/568144d8550346895db1a3f0/html5/thumbnails/49.jpg)
ClientToScreen(&rect); // 用用户区坐标重新计算屏幕坐标
ClipCursor(&rect); //限制光标在用户区内// 默认处理,调用基类消息处理函数CView::OnLButtonDown(nFlags, point);}
![Page 50: 用 VC++ 在屏幕上绘图](https://reader036.vdocuments.mx/reader036/viewer/2022081415/568144d8550346895db1a3f0/html5/thumbnails/50.jpg)
void CMyLineView::OnMouseMove
(UINT nFlags, CPoint point)
{
SetCursor(m_HCursor); // 设置自定义光标
if(m_pLMouseDown)
{CClientDC dc(this);
dc.SetROP2(R2_NOT); // 设置绘图模式,以屏幕颜色的相反色绘图
![Page 51: 用 VC++ 在屏幕上绘图](https://reader036.vdocuments.mx/reader036/viewer/2022081415/568144d8550346895db1a3f0/html5/thumbnails/51.jpg)
// 以重绘的方式擦除前一个 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++ 在屏幕上绘图](https://reader036.vdocuments.mx/reader036/viewer/2022081415/568144d8550346895db1a3f0/html5/thumbnails/52.jpg)
void CMyLineView::OnLButtonUp
(UINT nFlags, CPoint point)
{if(m_pLMouseDown)
{
m_pLMouseDown=FALSE;//标志鼠标释放
ReleaseCapture();//释放鼠标捕捉
ClipCursor(NULL);// 使光标可以随意移动 }
CView::OnLButtonUp(nFlags, point);}