VC++基础实验

实验1  Visual C++图形程序设计

一、实验目的

Visual C++是在Microsoft C的基础上发展而来的,随着计算机软、硬件技术的快速发展,如今Visual C++已成为集编辑、编译、运行、调试于一体功能强大的集成编程环境。本章以Visual C++ 6.0为对象,主要介绍Visual C++集成编成环境的使用、图形设备接口和常用图形程序设计、鼠标编程以及菜单设计等基础,目的是通过对Visual C++的学习,掌握Visual C++图形程序设计的方法,为计算机图形学原理部分的算法实现提供程序工具和方法。

二、实验任务

1. 学习Visual C++图形程序设计的方法;

2. 掌握Visual C++集成编成环境的使用、图形设备接口和常用图形程序设计、鼠标编程、橡皮筋交互技术、画刷与画笔以及菜单设计等;

三、基础知识和实验步骤

31  Visual C++ 6.0应用程序开发方法

    介绍Visual C++ 6.0集成开发环境,以一个简单的实例介绍利用Visual C++应用程序工程建立方法和程序设计框架。

311  Visual C++的集成开发环境

从开始菜单中启动Visual C++ 6.0,进入开发集成环境。打开一个项目后,可以看到Visual C++ 6.0的开发环境由标题栏、工具栏、工作区窗口、源代码编辑窗口、输出窗口和状态栏组成,见图3.1所示。

标题栏用于显示应用程序名和所打开的文件名,标题栏的颜色可以表明对应窗口是否被激活。菜单栏包括文件、编辑、显示、插入、工程、编译、工具、窗口和帮助九项主菜单,包含了从源代码的编辑、界面设计、程序调试和编译运行在内的所有功能。工具栏列出了常用的菜单命令功能和对象方法。工具栏的下面是两个窗口,一个是工作区窗口,用于列出工程中的各种对象,一个是源代码编辑窗口,用于各个对象的程序设计。输出窗口显示项目建立过程中所产生的各种信息。屏幕底端是状态栏,它给出当前操作或所选择命令的提示信息。

 

 

                   3.1   Visual C++ 6.0集成开发环境

3.1.2 应用程序工程的建立方法

Visual C++提供了一种称为App Wizard的工具,利用该工具,用户可以方便地按照自己的需要创建符合需要的应用程序框架。在这个基础上,用户可以进一步将自己编写的程序加入到这个框架中,实现用户程序的功能。下面介绍建立VcApp应用程序框架的方法,其它应用程序的方法都与此类似。

第一步:启动Visual C++,选择工程方法

     从开始菜单中选择 Visual C++,进入Visual C++集成环境。从文件菜单中选择新建(New)命令,弹出图3-2对话框。切换到工程(Projects)标签,项目类型选择MFC AppWizard(exe),输入工程的名字(如VcApp),选择项目放置的位置,然后单击“确定”按钮。

 

                3-2  Visual C++New对话框

第二步:设置应用程序的特性。

      这些设置包括六个问题,每一个问题都有不同的选项供选择。一个问题选择完后,通过“下一步”(Next)选择下一个问题,直到六个问题选择完毕。还可以通过“上一步”(Back)返回上一个问题重新选择。下面继续上面的例子,在单击“确定”按钮后,弹出第一个问题窗口,如图3-3所示。

第一个问题是建立什么类型的应用程序,有三个选项:单个文档(Single document)、多重文档(Multiple document)和基本对话(Dialog based)。单个文档应用程序主窗口中只有一个窗口,多重文档可以在主窗口中开多个子窗口,基本对话主窗口是一个对话框。例中选择单个文档,单击“确定”,进入下一个问题,如图3-4所示。

第二个问题是数据库的支持,是否用ODBC存取数据库,有四个选项:不包括数据库的支持(None)、仅包含ODBC头文件(Header files only)、指定一个数据库但没有文件支持和指定一个数据库但需要文件支持。当选择了后两项,则需要用户选择一个已经建立的数据库。例中不需要数据库支持,选择第一个选项“否”,进入第三个问题,如图3-5所示。

 

              3-3   第一个问题:选择应用程序的类型

 

 

3-4   第二个问题:选择是否要用ODBC支持

 

第三个问题是对ActiveX的支持。有五个选项:(1)没有对ActiveX的支持;(2ActiveX容器,它可以包含链接和嵌入对象。容器不能为其它的ActiveX程序提供支持,它只能维护嵌入对象;(3)微型服务器(Mini-server),应用程序不能独立运行,只能被调用为其它程序建立ActiveX对象。(4)完整服务器(Full-server),它能够独立运行,并能够为其它应用程序建立ActiveX对象。(5)容器和服务器,一个应用程序可以同时是容器和服务器。

在例子中,选择第一个选项,没有对ActiveX的支持,单击“下一个”(Next)进入下一个问题。

 

 

3-5   第三个问题:选择是否对ActiveX的支持

 

第四个问题是应用程序的特性和高级选项,如图3-6所示。

 

3-6  应用程序的特性和高级选项

例中全部采用默认选项,进入下一个问题。

第五个问题是项目的风格、原文件注释和MFC库类型,如图3-7所示。

在例子中全部采用默认选项,进入第六个问题。

第六个问题是确定类名和文件名,如图3-8所示。

    基于第一个问题到第五个问题的回答,AppWizard会把将要建立的新类的名称通知用户。AppWizard将为应用程序建立四个新类,CVcAppApp是应用程序类,它是CWinApp的派生类。CMainFrame是一个拥有应用程序主窗口的类。CVcAppDocCVcAppView是该应用程序的文档和视图类。这些名字用户可以改变。最后单击“完成”(Finish,显示所建项目的信息,单击“确定”后,项目建立完成。

 

 

3-7  项目的风格、原文件注释和MFC库类型

 

 

3-8  通知MFC产生的类名称

3.1.3  输入源程序进行程序设计

     应用程序项目工程建立以后,就为应用程序的开发建立了一个框架,这是不输入任何程序代码,对该项目程序进行编译和运行,可以生成一个完整的窗口程序。用户根据项目工程中的不同类,输入自己设计的程序代码,完成用户的程序设计。

   例如,从VcApp Classes中找到CVcAppViewOnDraw()函数,如图3-9所示。双击OnDraw()函数,这时系统会打开VcAppView.cpp文件,而且光标正置于OnDraw()函数中,在其中输入下列语句:

pDc->TextOut(30,30,”同学们好,欢迎使用VC++编程!”)

编译并运行该程序,运行结果如图3-10所示。

 

                        3-9  输入程序源代码

 

 

3-10  运行结果

 

3.2  图形设备接口和图形程序设计

3.2.1 图形设备接口简介

Windows系统中,程序都是通过一个叫做图形设备接口(GDI, Graphics Device Interface)的抽象接口和硬件打交道,Windows会自动将设备环境表映射到相应的物理设备,并且会提供正确的输入/输出指令。

GDIWindows系统核心的三种动态链接库之一,它管理Windows系统的所有程序的图形输出。在Windows系统中,GDI向程序员提供了高层次的绘图函数,只要掌握这些绘图函数,就可以很方便地进行图形程序设计。

另一个概念是设备描述表(DC, Device Context)。DC是一个数据结构,当程序向GDI设备中绘图时,需要访问该设备的DCMFCGDIDC封装在C++类中,包括CDC类和CDC派生类,这些类中的许多成员都是对本地GDI绘图函数进行简单封装而形成的内联函数。

DC的作用就是提供程序与物理设备或者虚拟设备之间的联系,除此之外,DC还要处理绘图属性的设置,如文本的颜色等。程序员可以通过调用专门的GDI函数修改绘图属性,如SetTextColor()函数。

CDC类是GDI封装在MFC中最大的一个类,它表示总的DC。表3.1列出了CDC中的一些常用绘图函数。

3.1  CDC类中常用绘图函数

函  数

描  述

使用频率

Arc()

椭圆弧

****

BitBlt()

把位图从一个DC拷贝到另一个DC

*

Draw3dRect()

绘制三维矩形

**

DrawDragRect()

绘制用鼠标拖动的矩形

**

DrawEdge()

绘制矩形的边缘

**

DrawIcon()

绘制图标

***

Ellipse()

绘制椭圆

****

FillRect()

绘制用给定的画刷颜色填充矩形

***

FillRgn()

绘制用给定的画刷颜色填充区域

***

FillSolidRed()

绘制用给定的颜色填充矩形

***

FloodFill()

用当前的画刷颜色填充区域

***

FrameRect()

绘制矩形边界

**

FrameRgn()

绘制区域边界

**

GetBKColor()

获取背景颜色

*****

GetCurrentBitmap()

获取所选位图的指针

**

GetCurrentBrush()

获取所选画刷的指针

***

GetCurrentFont()

获取所选字体的指针

***

GetCurrentPalette()

获取所选调色板的指针

***

GetCurrentPen()

获取所选画笔的指针

***

GetCurrentPosition()

获取画笔的当前位置

****

GetDeviceCaps()

获取显示设备能力的信息

**

GetMapMode()

获取当前设置映射模式

***

Getpixel()

获取给定像素的RGB颜色值

*****

GetPolyFillMode()

获取多边形填充模式

***

GetTextColor()

获取文本颜色

****

GetTextExtent()

获取文本的宽度和高度

**

GetTextMetrics()

获取当前文本的信息

**

GetWindow()

获取DC窗口的指针

**

GrayString()

绘制灰色文本

***

LineTo()

绘制直线

******

MoveTo()

设置当前画笔位置

******

Pie()

绘制饼图

***

Polygon()

绘制多边形

***

PolyLine()

绘制一组直线

***

RealizePalette()

将逻辑调色板映射到系统调色板

**

Rectangle()

绘制矩形

****

RoundRect()

绘制圆角矩形

***

SelectObject()

选择GDI绘图对象

**

SelectPalette()

选择逻辑调色板

**

SelectStockObject()

选择预定义图形对象

**

SetBkColor()

设置背景颜色

******

SetMapMode()

设置映射模式

***

SetPixel()

把像素设定为给定的颜色

******

SetTextColor()

设置文本颜色

******

StretchBlt()

把位图从一个DC拷贝到另一个DC,并根据需要扩展或压缩位图

*

TextOut()

绘制字符串文本

*****

这些函数的语法和使用可以通过MSDN帮助查询。3.2.2节主要介绍Windows中基本图形,包括电、直线、圆、圆弧、矩形、椭圆、扇形、折线等程序设计

3.2.2 绘制基本图形

1)画点

     SetPixel()函数可以在指定的坐标位置按指定的颜色画点。函数原型说明如下:

 

 

    

其中,(XY)为点的坐标位置,crColor参数为点的颜色值。如果函数调用成功,则函数返回像素的颜色值,否则返回值为-1。颜色值通过RGB(Red,Green,Blue)来设置,其中三个参数取值0~255。例如,在VcAPP项目中,在CVcAppView类中的OnDraw()函数中加入下列画点语句:

//绘制一组彩色点

//绘制一组彩色点

pDC->TextOut(20,20,"point:");

pDC->SetPixel(100,20,RGB(255,0,0));

    pDC->SetPixel(110,20,RGB(0,255,0));

pDC->SetPixel(120,20,RGB(0,0,255));

pDC->SetPixel(100,20,RGB(255,255,0));

pDC->SetPixel(100,20,RGB(255,0,255));

pDC->SetPixel(100,20,RGB(0,255,255));

pDC->SetPixel(100,20,RGB(0,0,0));

pDC->SetPixel(100,20,RGB(255,255,255));

运行程序,查看运行结果。

 

2)画直线和折线

画直线需要LineTo()MoveTo()两个函数的配合使用。

LineTo()函数以当前位置所在的点为直线的起点,另指定一个点为直线的终点,画出一段直线。直线的颜色通过画笔的颜色来设定,在后面介绍。LineTo()函数原型说明如下:

 

 

 

直线的终点位置由(nXEnd, nYEnd)指定。如果函数调用成功,那么该点就成为当前位置,并返回TRUE,否则返回FALSE

MoveTo()函数只是将当前位置移动到指定位置,它并没有画出直线,其函数说明为:

 

 

 

示例:在CVcAppView类中的OnDraw()函数中加入下列画点语句:

//绘制直线

pDC->TextOut(20,60,"Line:");

pDC->MoveTo(20,90);

    pDC->LineTo(160,90);

Polyline()函数用来画一条折线,而PolyPolyline()函数则用来画多条折线,它们的函数原型说明如下:

 

 

 

    

 

Polyline()函数中,lppt是指向折线顶点数组的指针,而cPoints是折线顶点数组中的顶点数。例如,绘制一条具有4个顶点的折线,程序如下:

POINT polylinepoint[4]={{70,240},{20,190},{70,190},{20,240}};

pDC->Polyline(polylinepoint,4);

PolyPolyline()函数中,lppt是指向保存顶点数组的指针,而各条折线的顶点数则保存在lpdwPolyPoints参数所指向的数组中,最后的cCount参数指定折线的数目。例如:

POINT polypolylinePt[9]={{95,160},{120,185},{120,250},{145,160},{120,185},

{90,185},{150,185},{80,210},{160,210}};

     DWORD dwPolyPoints[4]={3,2,2,2}; //分四段折线,分别占用3222个顶点

     pDC->PolyPolyline(polypolylinePt, dwPolyPoints, 4);

注:由于一条折线至少需要2个顶点,因此dwPolyPoints数组中的数不应该小于2

 

3)画弧线和曲线

通过Arc()函数画弧线或整个椭圆。椭圆限定在一个矩形内,称为外接矩形。Arc()函数的圆形说明如下:

 

 

 

 

 

 

其中,(nLeftRect,  nTopRect)是外接矩形的左上角坐标值,(nRightRect, nBottomRect)是外接矩形的右下角坐标值。而椭圆中心与点(nXStartArc, nYStartArc)所构成的射线与椭圆的交点成为弧线的起点,椭圆中心与点(nXEndArc, nYEndArc)所构成的射线与椭圆的交点成为弧线的终点。椭圆上从始点到终点就形成一条弧线。

    Windows系统中,弧线从始点到终点的方向是逆时针方向,但可以通过SetArcDirection()函数将绘制弧线方向设置为顺时针方向。

示例,用Arc()绘制圆、圆弧和椭圆,程序如下:

for (i=0;i<6;i++)

{

  pDC->Arc(260-5*i,70-5*i,260+5*I,70+5*i,260+5*i,70,260+5*i,70);

}

for (i=3;i<6;i++)

{

   pDC->Arc(260-10*i, 70-10*i, 260+10*i, 70+10*i,

(int)260+10*i*cos(60*3.1415926/180),

(int)70+10*i*sin(60*3.1415926/180),

(int)260+10*i*cos(60*3.1415926/180),

(int)70-10*i*sin(60*3.1415926/180));

     

  pDC->Arc(260-10*i, 70-10*i, 260+10*i, 70+10*i,

(int)260-10*i*cos(60*3.1415926/180),

(int)70-10*i*sin(60*3.1415926/180),

(int)260-10*i*cos(60*3.1415926/180),

(int)70+10*i*sin(60*3.1415926/180));

}

Bezier曲线是最常见的非规则曲线之一。Bezier曲线属于三次曲线,需要四个控制顶点来确定一条Bezier曲线,其中曲线通过第一点和最后一点,并且第一条边和最后一条边是曲线在起点和终点处的切线,从而确定了曲线的走向。PolyBezier()函数可以画出一条或多条Bezier曲线,其函数原型说明如下:

 

 

 

其中,lppt参数是曲线控制顶点所组成的数组,cPoints参数表示lppt数组中的顶点数,一条Bezier曲线需要四个控制顶点。如果lppt数组用于画多条Bezier曲线,第二条以后的曲线只需要三个控制顶点,因为后面的曲线总是把前一条曲线的终点作为自己的起点。

示例,给出四个控制顶点,画出一条Bezier曲线和特征多边形。

//绘制Bezier 曲线

POINT polyBezier[4]={{20,310},{60,240},{120,300},{160,330}};

pDC->Polyline(polyBezier,4);

pDC->PolyBezier(polyBezier,4);

 

4)画封闭曲线

Windows中提供了一组画封闭曲线的函数,包括绘制矩形、多边性、椭圆等,这些画封闭曲线的函数不但可以利用画笔来画出轮廓线,同时还可以利用画刷来填充这些封闭曲线所围成的区域。

 

Rectangle()函数用来画矩形,其函数原型说明如下:

 

 

 

 

其中,参数nLeftRectnTopRect给出了矩形左上角的坐标,而nRightRectnBottomRect则给出矩形的右下角坐标。

 

Ellipse()函数的作用则是画椭圆形。在Ellipse()函数中,椭圆是由其外接矩形来确定的,外接矩形的中心与椭圆中心重合,矩形的长与宽和椭圆的长短轴相等。函数说明如下:

 

 

 

 

其中的参数说明与Rectangle()函数相同。

 

RoundRect()函数用来画圆角矩形,其函数的原型说明如下:

 

 

 

 

 

其中的前四个参数与Rectangle()函数相同,nWidth表示圆角的宽度,  nHeight表示圆角的高度。

 

Polygon()函数用来画封闭的任意多边形,其函数原型说明如下:

 

 

 

    其中的参数说明与Polyline()函数相同。但两个函数有区别,Polygon()函数会自动将起点和终点相连形成封闭的多边形,而Polyline()函数则画出多条折线,只有当最后一点与起点相同时才画出封闭的多边形。

示例,绘制矩形、圆角矩形、椭圆和多边形,程序如下:

//绘制矩形、圆角矩形、椭圆和多边形

pDC->Rectangle(190,270,250,310);

pDC->RoundRect(265,270,330,310,30,20);

pDC->Ellipse(260-50,200-30,260+50,200+30);

POINT polygonPts[3]={{390,160},{430,220},{350,210}};

pDC->Polygon(polygonPts,3);

3.2.3  画笔与画刷

1)画笔

当绘制图形时,线条的属性,包括颜色、宽度、样式等都是由画笔来确定的。程序员可以创建画笔,定义画笔的属性,从而画出多彩的图形。

创建画笔包括CreatePen()CreatePenIndirect()两个函数。MFC将这些函数封装在CPen类中,这样画笔就能够被视为对象进行处理。下面介绍创建画笔的方法。

方法一:直接构造一个CPen对象,并将定义画笔的参数传给它,例如:

  CPen  pen(PS-SOLID,1,RGB(255,0,0));

 创建一个宽度为一个像素、实线和红色的画笔。

方法二:首先声明一个没有初始化的CPen类对象,然后再用CreatePen()函数定义画笔的属性。例如,

CPen  Pen;

Pen->CreatePen (PS-SOLID,1,RGB(255,0,0));

方法三:先声明一个CPen类对象和一个描述画笔结构的LOGPEN类对象,并填入画笔的属性值,然后调用CreatePenIndirect()函数来创建画笔。如下所示:

CPen  Pen;

LOGPEN  LogPen;

LogPen.lopnStyle=PS_SOLID;

LogPen.lopnWidth=1;

LogPen.lpenColor=RGB(255,0,0);

Pen.CreatePenIndirect(&LogPen);

如果画笔被成功创建,那么两个函数返回TRUE,否则返回FALSE

 

  画笔包括样式、宽度和颜色三个属性。表3.2列出了GDI画笔的样式。

                       3.2   GDI画笔的样式

样式

说  明

PS_SOLID

创建实线笔

PS_DASH

创建虚线笔,只有当画笔宽度小于或等于1时有效

PS_DOT

创建点线笔,只有当画笔宽度小于或等于1时有效

PS_DASHDOT

点划线笔,只有当画笔宽度小于或等于1时有效

PS_DASHDOTDOT

双点划线笔,只有当画笔宽度小于或等于1时有效

PS_NULL

创建NULL笔,不绘制任何图形

PS_INSIDEFRAME

创建可以在封闭框架内部绘制直线的画笔。

   

画笔的宽度用像素个数来确定。PS_DASHPS_DOTPS_DASHDOTPS_DASHDOTDOT参数要求画笔宽度只能为1,其它参数可以创建任意宽度的画笔。画笔的颜色是一个24位的RGB颜色,由RGB(rColor,gColor,bColor)来定义,三个参数取值0~255

Windows预定义了三个实线、1个像素宽的画笔,它们是WHITE_PENBLACK_PENNULL_PEN,程序中可以直接使用这些画笔,方法如下:

  CPen Pen;

  Pen.CreateStockObject(WHITE_PEN);

 

示例:在屏幕上绘制三组直线,第一组按不同线型绘制,第二组按不同宽度绘制,第三组按不同颜色绘制。程序如下:

 //画笔的样式、宽度和颜色

int i1;

int nPenStyle[]=

{

PS_SOLID,PS_DASH,PS_DOT,PS_DASHDOT,PS_DASHDOTDOT,PS_NULL,

PS_INSIDEFRAME,

};

CPen *pNewPen;

CPen *pOldPen;

//用不同样式的画笔

for (i1=0;i1<7;i1++)

{

//构造新笔

pNewPen=new CPen;

if (pNewPen->CreatePen(nPenStyle[i1],1,RGB(0,0,0)))

{

pOldPen=pDC->SelectObject(pNewPen); //选择新笔,并保存旧笔

//画直线

pDC->MoveTo(20,60+i1*20);

pDC->LineTo(160,60+i1*20);

//恢复原有的笔

pDC->SelectObject(pOldPen);

}

else

{

//出错提示

AfxMessageBox("CreatePen Erroe!!");

}

//删除新笔

delete pNewPen;

}

//用不同的宽度的笔绘图

for(i1=0;i1<7;i1++)

{

//构造新笔

pNewPen=new CPen;

if (pNewPen->CreatePen(PS_SOLID,i1+1,RGB(0,0,0)))

{

pOldPen=pDC->SelectObject(pNewPen);

//画直线

pDC->MoveTo(200,60+i1*20);

pDC->LineTo(340,60+i1*20);

//恢复原有的笔

pDC->SelectObject(pOldPen);

}

else

{

//出错提示

AfxMessageBox("CreatePen Erroe!!");

}

//删除新笔

delete pNewPen;

}

 

//设置颜色表

  struct tagColor

  {

  int r,g,b;

  } color[7]=

  {

  {255,0,0},{0,255,0},{0,0,255},

  {255,255,0},{255,0,255},{0,255,255},{0,0,0},

  };

  //用不同颜色绘图

for(i1=0;i1<7;i1++)

{

//构造新笔

pNewPen=new CPen;

if (pNewPen->CreatePen(PS_SOLID,2,RGB(color[i1].r,color[i1].g,color[i1].b)))

{

pOldPen=pDC->SelectObject(pNewPen);

//画直线

pDC->MoveTo(380,60+i1*20);

pDC->LineTo(520,60+i1*20);

//恢复原有的笔

pDC->SelectObject(pOldPen);

}

else

{

//出错提示

AfxMessageBox("CreatePen Erroe!!");

}

//删除新笔

delete pNewPen;

}

//画笔程序结束

2)画刷

在进行区域填充或绘制封闭图形时,需要用到画刷。MFCGDI画刷封装在CBrush类中。画刷分三种基本类型:纯色画刷、阴影画刷和图案画刷。

纯色画刷绘图使用单色来定义,颜色由RGB()函数来确定。纯色画刷可以采用直接声明的方法,例如:

CBrush Brush(RGB(255,0,0)); 创建一个红色画刷。

 也可以采用分步方法,由CreateSolidBrush()函数创建。

        CBrush  Brush;

        Brush->Create->CreateSolidBrush(RGB(255,0,0));

  Windows预定义了七种画刷,包括:BLACK_BRUSHDKGRAY_BRUSHGRAY_BRUSHLTGRAY_BRUSHHOLLOW_BRUSHNULL_BRUSHWHITE_BRUSH。可以参照CPen类的方法,采用CreateStockObject()来使用预定义的画刷。

阴影画刷使用预定义的六种阴影样式进行绘图。表3.3列出了六种阴影样式。

                 3.3六种阴影样式

阴影样式

说明

HS_BDIAGONAL

45度向下阴影线(从左到右)

HS_CROSS

水平线与垂直线交叉阴影

HS_DIAGCROSS

45度方向的交叉阴影线

HS_FDIAGONAL

45度向上阴影线(从左到右)

HS_HORIZONTAL

水平阴影线

HS_VERTICAL

垂直阴影线

 

 

 

 

 

 

 

     

  创建阴影画刷的方法与纯色画刷的创建方法相似,例如创建一个45度方向的交叉阴影线的画刷,方法如下:

      CBrush  Brush(HS_DIAGCROSS,RGB(255,0,0));

或者

      CBrush  Brush;

      Brush->CreateHatchBrush(HS_DIAGCROSS,RGB(255,0,0));

函数中有两个参数,第一个参数是画刷的阴影样式,第二个参数是阴影线的颜色。

示例:绘制缺省画刷的矩形,纯色画刷矩形和绘制100单位的矩形,并且用白色45度交叉线阴影将其填充,程序如下:

//画刷程序

pDC->Rectangle(300,300,400,400); //缺省的画刷,白色

//纯色画刷

CBrush *pNewBrush1;

CBrush *pOldBrush1;

pNewBrush1=new CBrush;

if (pNewBrush1->CreateSolidBrush(RGB(255,0,0)))

{

//选择新画刷

    pOldBrush1=pDC->SelectObject(pNewBrush1);

//绘制矩形

    pDC->Rectangle(200,200,300,400);

//恢复原有画刷

    pDC->SelectObject(pOldBrush1);   

}

delete  pNewBrush1;

//阴影画刷

CBrush Brush(HS_DIAGCROSS,RGB(255,255,255));

CBrush *pOldBrush;

pOldBrush=pDC->SelectObject(&Brush);

pDC->SetBkColor(RGB(192,192,192));

pDC->Rectangle(0,0,100,100);

pDC->SelectObject(pOldBrush);

3.2.4 文本显示

   Windows可以显示很多数据,包括在窗口中显示文本信息。由于文本是以图像的形式显

示在窗口中的,因此需要处理设备描述表(DC),另外还需要对文本字体的处理,包括:文本的显示、文本的颜色、字符的间距和文本的对齐方式等。

 

1)文本显示

     在拥有一个设备描述表以后,就可以调用TextOut()函数来显示文本行。例如:

     pDC->TextOut(20,20,”This is a line of text.”);

 TextOut()函数的三个参数分别是输出文本的X坐标和Y坐标以及输出文本串。

2)设置文本颜色

     在默认情况下,Windows绘制黑色文本。可以通过SetTextColor()函数改变文本的颜色。例如:

        CDC *pDC=GetDC();     //声明一个设备描述表pDC1

        pDC->SetTextColor(RGB(255,0,0));  //设置文本颜色为红色

     可以通过GetTextColor()函数检索到当前文本的颜色,例如:

        COLORREF color=pDC->GetTextColor();

   SetBkColor()GetBkColor()函数用于设置背景颜色和获取当前的背景颜色。

 

2)设置字符间距

SetTextCharacterExtra()函数用来设置文本字符的间距,GetTextCharacterExtra()用来获得当前文本字符的间距,函数说明如下:

   pDC-> SetTextCharacterExtra(space);

   int space=pDC-> GetTextCharacterExtra();

其中,space表示在文本字符之间使用的额外空间的像素数。

 

3)设置文本的对齐方式

    SetTextAlign()函数用于设置显示文本的对齐方式,函数说明如下:

   pDC->SetTextAlign(alignment);

其中,alignment参数取值:TA_LEFTTA_CENTERTA_RIGHT,分别表示左对齐、居中方法和右对齐。Alignment参数取值:TA_TOPTA_BOTTOMTA_BASELINE分别表示文本在垂直方向的对齐方式,上对齐、下对齐和字符的基线对齐。

3.3  鼠标编程

在图形操作系统中,鼠标是最重要的输入设备之一。Windows系统为用户提供了统一的鼠标编程接口,而不必过多了解其底层的知识。Windows是基于消息传递、事件驱动的操作系统,当用户移动鼠标、按下或释放鼠标键时都会产生鼠标消息。应用程序可以接收10种鼠标消息,表3.3列出了这些鼠标消息和它们的描述。

                        3.3鼠标消息和描述

消  息

描  述

WM_LBUTTONDBLCLK

鼠标左键被双击

WM_LBUTTONDOWN

鼠标左键被按下

WM_LBUTTONUP

鼠标左键被释放

WM_MBUTTONDBLCLK

鼠标中键被双击

WM_MBUTTONDOWN

鼠标中键被按下

WM_MBUTTONUP

鼠标中键被释放

WM_MOUSEMOVE

鼠标移动穿过对象区域

WM_RBUTTONDBLCLK

鼠标右键被双击

WM_RBUTTONDOWN

鼠标右键被按下

WM_RBUTTONUP

鼠标右键被释放

 

 

 

 

 

 

 

 

 

 

 

 

3.3.1  鼠标消息处理

MFC把鼠标消息处理函数封装在CView类中,它们分别是:

     OnMouseMove(UINT nFlags, CPoint  point);

     OnLButtonDblclk(UINT nFlags, CPoint  point);

     OnLButtonDown(UINT nFlags, CPoint  point);

     OnLButtonUp(UINT nFlags, CPoint  point);

     ……

分别对应表3.310个鼠标消息。在鼠标处理函数中,point参数代表鼠标热点处的坐标位置,point.x为横坐标,point.y为纵坐标。默认坐标原点(00)位于窗口的左上角。由于应用程序要求自动捕获鼠标事件,因此应当采用Windows事件处理函数,而不是成员函数,具体使用方法参见3.3.3节示例程序。

nFlags参数中包含了鼠标按钮和键盘组合使用标志,用来描述鼠标按钮和键盘上的Shift键和Ctrl键的组合状态。nFlag参数取值范围:

(1) MK_LBUTTON:鼠标左键被按下;

(2) MK_RBUTTON:鼠标右键被按下;

(3) MK_MBUTTON:鼠标中键被按下;

(4) MK_SHIFT:键盘上的Shift键被按下;

(5) MK_CONTROL:键盘上的Ctrl键被按下;

如果想知道某个键是否被按下,可用对应的位屏蔽值与nFlags参数作按位逻辑“与”运算,所的结果若为非零值,则表示该按钮被按下,例如:

 

 

if   (nFlags & LBUTTON)

   AfxMessageBox(“LButton is pressed down!”)

Else

   AfxMessageBox(“LButton is pressed Up!”);

如何区分两次单击和一次双击,这取决于两次按下按钮之间的时间间隔,只有当时间间隔小于一定值时才被认为是一次双击。Windows默认的时间为500ms。可以用SetDoubleClickTime()函数来重新设置时间间隔值。

若要使窗口函数能接收到鼠标双击产生的消息,在注册窗口类时,必须指明该窗口具有CS_DBLCLKS风格,否则,即使进行了双击操作,该窗口也只能收到两条“WM_LBUTTONDOWN”和“WM_LBUTTONUP”消息,例如:

wndclass.style=CS_HREDRAW|CS_VREDRAW|CS_DBLCLKS;

3.3.2  捕捉鼠标

在交互式图形程序设计中,经常要使用鼠标的位置拾取、拖动或拖放,这些动作必须进行鼠标的捕捉。

鼠标捕捉只需要调用CWnd::SetCapture()函数。用户完成鼠标捕捉工作后一般是响应一个鼠标按下信息,要释放鼠标捕捉则是调用CWnd::ReleaseCapture()函数。释放被捕捉鼠标的最好时间是在响应鼠标弹起的时候(WM_LBUTTON)。

 3.3.3  鼠标编程综合示例

示例1:在窗口中以文本的形式给出鼠标的状态,即当鼠标移动时,给出鼠标的位置;当鼠标按下鼠标左、右键时显示出鼠标按键状态。例如,当鼠标左键按下时,显示LBUTTON DOWN!”。

第一步:建立一个myMouse工程文件;

第二步:添加鼠标事件处理函数

鼠标右击视图类(如CmyMouseView),选择“add windows message handler…”,弹出事件处理函数列表窗口,如图3-11所示

 

                     3-11    Windows事件处理函数列表窗口

从左边事件消息列表中选择WM_LBUTTONDOWN”,然后单击“Add and Edit”按钮,即加入鼠标左键按下事件函数,并要求编辑事件处理程序。

第三步:输入事件处理程序

  void CMymouseView::OnLButtonDown(UINT nFlags, CPoint point)

{

// TODO: Add your message handler code here and/or call default

//获得pDC

CDC* pDC=GetDC();

pDC->TextOut(20,40,”LBUTTONDOWM!”);  // 输出显示信息

 

CView::OnLButtonDown(nFlags, point);

}

其中,阴影部分是用户输入的程序,其它内容都是自动生成的内容。

第四步:重复第二步和第三步,分别添加WM_LBUTTONUPWM_MOUSEMOVEWM_RBUTTONDOWNWM_RBUTTONUPWM_LBUTTONDBCLKWM_RBUTTONDBCLK鼠标事件,并输入以下程序:

void CMouseView::OnLButtonUp(UINT nFlags, CPoint point)

{

// TODO: Add your message handler code here and/or call default

CDC *pDC=GetDC();

    pDC->TextOut(20,40,"LButton UP!");

    CView::OnLButtonUp(nFlags, point);

}

 

void CMouseView::OnRButtonDown(UINT nFlags, CPoint point)

{

// TODO: Add your message handler code here and/or call default

  CDC *pDC=GetDC();

      pDC->TextOut(20,60,"RButton Down!");

  CView::OnRButtonDown(nFlags, point);

}

 

void CMouseView::OnRButtonUp(UINT nFlags, CPoint point)

{

// TODO: Add your message handler code here and/or call default

CDC *pDC=GetDC();

        pDC->TextOut(20,40,"RButton UP!");

    CView::OnRButtonUp(nFlags, point);

}

 

void CMouseView::OnMouseMove(UINT nFlags, CPoint point)

{

// TODO: Add your message handler code here and/or call default

CDC *pDC=GetDC();

    char tbuf[80];

sprintf(tbuf,"Position:(%3d,%3d)",point.x,point.y);

// 输出鼠标当前位置

    pDC->TextOut(20,20,tbuf);

CView::OnMouseMove(nFlags, point);

}

 

void CMouseView::OnLButtonDblClk(UINT nFlags, CPoint point)

{

// TODO: Add your message handler code here and/or call default

CDC *pDC=GetDC();

    pDC->TextOut(20,80,"LButton is double clicked!");

CView::OnLButtonDblClk(nFlags, point);

}

 

void CMouseView::OnRButtonDblClk(UINT nFlags, CPoint point)

{

// TODO: Add your message handler code here and/or call default

CDC *pDC=GetDC();

    pDC->TextOut(20,80,"RButton is double clicked!");

CView::OnRButtonDblClk(nFlags, point);

}

第五步:编译程序,并验证执行结果。

 

示例2:采用鼠标橡皮筋技术画圆

鼠标橡皮筋技术画圆就是采用圆心和圆周上任一点画圆技术(简称C+P方法),首先用鼠标左击选择圆心位置,然后移动鼠标,圆随鼠标移动而扩大或缩小,当再次单击鼠标左键时,确定圆周上的一点,从而画出相应的圆。直线、矩形等基本图形都可以采用橡皮筋技术。

第一步:建立MouseSpring工程文件;

第二步:向视图类中添加自定义的成员变量

   用鼠标右键单击视图类,选择Add Member Variable…”,添加下面三个成员变量。

proctected :

     CPoint  m_bO;  // 圆心

     CPoint  m_bR;  //圆上的点

     int      m_ist;  //圆心与圆周上点的区别,m_ist=0,表示鼠标左击点为圆心,

                    //m_ist=1,表示鼠标左击点为圆周上的点

 操作方法如图3-13所示,分别添加上述三个成员变量。

 

                  3-13   添加成员变量

   第三步:向视图类中添加自定义的成员函数原型:

      public:

          void DrawCircle(CDC* pDC, CPoint cenp, CPoint ardp);

          int  ComputeRadius(CPoint cenp,CPoint ardp);

具体操作方法:用鼠标右键单击视图类,选择Add Member Function…”,如图3-14所示。分别添加上述两个成员函数,分别用于画圆和计算圆的半径。

      

                   3-14    添加成员函数

第三步:在视图类CPP文件的构造函数中初始化成员变量。

     视图类的构造函数名与该视图类的名字相同。在视图类中选择构造函数,如:CMouseSpringView(),用鼠标左键双击,输入下面程序代码:

CMouseSpringView:: CMouseSpringView()

{

   //TODO: add construction code here

   m_bO.x=0;  m_bO.y=0;  //圆心

   m_bR.x=0;  m_bR.y=0;  //圆上的点

   m_ist=0;   //圆心与圆上的点区别

}

第四步:在视图类的OnDraw()函数中加入下列代码,实现视图绘图。

  void CMouseSpringView::OnDraw(CDC* pDC)

{

CMouseSpringDoc* pDoc = GetDocument();

ASSERT_VALID(pDoc);

    

 

// TODO: add draw code for native data here

pDC->SelectStockObject(NULL_BRUSH);

DrawCircle(pDC,m_bO,m_bR);  // 调用自定义的成员函数画圆

}

第五步:向视图类中添加两个鼠标消息响应函数,并输入鼠标处理程序代码。

    具体操作方法与鼠标示例1方法相同。一个是OnLButtonDown()函数,另一个是OnMouseMove()函数。程序如下:

void CMouseSpringView::OnLButtonDown(UINT nFlags, CPoint point)

{

// TODO: Add your message handler code here and/or call default

CDC *pDC=GetDC();

    pDC->SelectStockObject(NULL_BRUSH);

if (!m_ist)  //绘制圆

{

m_bO=m_bR=point; //纪录第一次单击鼠标位置,定圆心

m_ist++;

}

else

{

m_bR=point;  //记录第二次单击鼠标的位置,定圆周上的点

m_ist--;   // 为新绘图作准备

DrawCircle(pDC,m_bO,m_bR);  //绘制新圆

}

ReleaseDC(pDC); //释放设备环境

CView::OnLButtonDown(nFlags, point);

}

 

void CMouseSpringView::OnMouseMove(UINT nFlags, CPoint point)

{

// TODO: Add your message handler code here and/or call default

CDC *pDC=GetDC();

    int nDrawmode=pDC->SetROP2(R2_NOT); //设置异或绘图模式,并保存原来绘图模式

pDC->SelectStockObject(NULL_BRUSH);

if(m_ist==1)

{

CPoint prePnt,curPnt;

    prePnt=m_bR;  //获得鼠标所在的前一位置

curPnt=point;

//绘制橡皮筋线

DrawCircle(pDC,m_bO,prePnt);  //用异或模式重复画圆,擦出所画的圆

        DrawCircle(pDC,m_bO,curPnt);  //用当前位置作为圆周上的点画圆

m_bR=point;

    }

pDC->SetROP2(nDrawmode);  //恢复原绘图模式

ReleaseDC(pDC);  //释放设备环境

CView::OnMouseMove(nFlags, point);

}

 

第六步:添加成员函数的程序代码。

  分别为两个成员函数DrawCircle()ComputeRadius()添加程序代码,程序如下:

void CMouseSpringView::DrawCircle(CDC *pDC, CPoint cenp, CPoint ardp)

{

  int radius=ComputeRadius(cenp,ardp);

  // 由圆心确定所画圆的外切区域

  CRect rc(cenp.x-radius,cenp.y-radius,cenp.x+radius,cenp.y+radius);

  pDC->Ellipse(rc);  //画出一个整圆

}

 

int CMouseSpringView::ComputeRadius(CPoint cenp, CPoint ardp)

{

  int dx=cenp.x-ardp.x;

  int dy=cenp.y-ardp.y;

  //sqrt()函数的调用,在头文件中加入#include "math.h"

  return (int)sqrt(dx*dx+dy*dy);

}

 

第七步:编译运行程序,验证运行结果。

3.4  菜单程序设计

Windows应用程序设计中,菜单是重要的用户界面对象和交互手段。Windows支持三种类型的菜单,他们分别是菜单栏(主菜单)、弹出式菜单和上下文菜单(单击鼠标右键弹出的浮动菜单)。本节主要介绍如何对菜单进行编辑、如何响应菜单的消息、如何运用菜单的UI机制、如何动态地改变菜单以及如何处理上下文菜单。

3.4.1  菜单编辑器

   菜单编辑器用来创建并编辑菜单资源,是一个可视化设计工具。对于MDI应用程序(多文档应用程序),AppWizard自动生成两个菜单资源:IDR_MAINFRAMEIDR_PrjNameTYPE (PrjName是应用程序工程名)。在MDI子窗口打开之前系统显示IDR_MAINFRAME菜单,在MDI子窗口打开之后系统显示IDR_ PrjNameTYPE菜单。对于SDI应用程序,AppWizard只生成一个菜单资源:IDR_MAINFRAME

  在一个SDI文档工程项目中,在工作区窗口种选择ResourceView标签,列出工程项目的所有资源,选择Menu,双击IDR_MAINFRAME,弹出菜单编辑器窗口,如图3-15所示。

 

                          3-15  菜单编辑器

1)创建菜单和菜单选项

     在图3-15中,可以创建主菜单,也可以创建菜单选项。可以通过Tab键(向右移)、Shift+Tab键(向左移),或鼠标定位,通过Ins键在某一菜单前插入新的菜单。另外,用鼠标拖动菜单方框可以改变菜单项的相对位置。例如,在查看菜单前插入一个“绘图”菜单,包括直线、圆、矩形和颜色四个菜单项。

  步骤1:定位到“查看”菜单,按下Ins键或Insert键,插入一个空菜单项;通过Delete

键删除一个菜单项;

  步骤2:双击空菜单项,弹出菜单项对话框,并输入菜单信息,如图3-16所示。

       

                       3-16   菜单对话框

步骤3:添加菜单项条目。

      双击“绘图”菜单下的空菜单项,弹出菜单项对话框。如图3-17所示。

 

3-17  菜单项对话框

   步骤4:重复第3步,完成菜单设计。

在菜单设计中,可以为菜单或菜单项定义助记符,方法是在响应的字符前加符号&。菜单项的ID号,可以选取已有的ID号,也可以自定义ID号,如果不输入ID号,则系统自动生成一个ID号。另外,在菜单项对话框中还可以为菜单项指定风格。另外,还可以为菜单项定义快捷键,方法是在标题后直接输入,转义符\t表示快捷键左对齐。

 

(2) 弹出菜单的设计

弹出菜单就是主菜单项的子菜单,也称为级联菜单。

创建级联菜单的方法如下:选择级联菜单项,在该菜单项属性对话框中选中“弹出”(Pop-up)复选项,于是该项便被标记级联菜单符(),且在该项的右侧出现新的菜单项空方框。添加级联菜单项的方法与上述方法相同。如图3-18所示。

 

             3-18   级联菜单设计

3)上下文菜单

单击鼠标右键将弹出相应的上下文菜单。为了在应用程序中使用上下文菜单,首先要创建菜单本身,然后将其与应用程序代码链接。创建上下文菜单的步骤如下:

步骤1:创建带空标题的菜单栏。右击Menu,选择“Insert,创建一个空的菜单栏;

步骤2:输入菜单标题和菜单项,并保存菜单资源,默认为IDR_MENI1

步骤3:在源文件中添加下列程序代码:

    CMenu  menu;

// 装载并验证菜单资源;

VERIFY(menu.LoadMenu(IDR_MENU1));

CMenu *pPopup=menu.GetSubMenu(0);

ASSERT(pPopup!=NULL);

 

//显示菜单内容

pPopup->TrackPopupMenu(TPM_LEFTALIGN|TPM_RIGHTBUTTON,

x,y,AfxGetMainWnd());

    在创建上下文菜单资源后,应用程序代码装载菜单资源并使用函数TrackPopupMenu()来显示菜单内容。

3.4.2  菜单消息响应

Windows应用程序是通过消息传递机制运行的。为菜单项添加相应功能函数的方法步骤:

步骤1:右击所选菜单项,从弹出的菜单中选择“建立类向导…”,弹出类向导对话框,如图3-19所示;

 

                   3-19   建立类向导对话框

步骤2:选择工程名(Project:),并在类名(Class name:)中选择视图类,在Object IDs:列表中选择菜单项的ID号,在Messages:列表中选择COMMAND

步骤3:单击“Add Function…”,添加成员函数;

步骤4:选择该成员函数,单击“Edit Code”输入或编辑程序代码。

3.4.3  综合示例

利用菜单资源编辑器在默认的菜单中添加“字体”菜单项。在程序运行过程中改变菜单项的显示状态。

步骤1:创建Mymenu应用程序工程文件,选择单文档应程序;

步骤2:利用Resource View设计菜单,如图3-20所示;

 

3-20  菜单设计示例

菜单

菜单项

选项

格式(&S

颜色(&C

Pop-up=Checked

格式(&S

字体(&I)

Pop-up=Checked

 

菜 单

菜单项

ID

提示(Prompt

颜色(&C

红色

ID_FONTCOLOR1

红色字体

颜色(&C

绿色

ID_FONTCOLOR2

绿色字体

颜色(&C

蓝色

ID_FONTCOLOR3

蓝色字体

 

步骤3:在CMymenuView视图类中添加消息映射函数;

对象

消息

函数

ID_FONTCOLOR1

COMMAND

OnFontcolor1

ID_FONTCOLOR2

COMMAND

OnFontcolor2

ID_FONTCOLOR3

COMMAND

OnFontcolor3

添加方法:选择View\ClassWizard菜单项,弹出如图3-19所示的创建类对话框,从中选择工程名(Projects)和类名(Class name),并从Object IDs列表框中选择ID_FONTCOLOR1项,在Messages列表框中选择COMMAND,然后,单击“Add Function”按钮,弹出加入成员函数的对话框,输入成员函数名OnFontcolor1,确定后就添加了OnFontcolor1消息映射函数。

参照以上方法,添加上表中其他的函数。

 

步骤4:在CMymenuView类中添加成员变量和成员函数

变量类型

变量名称

访问权限

 COLORREF

m_FontColor

protected

 void

Redraw(CDC *pDC)

protected

   

    方法参见鼠标编程中的示例2,在CMymenuView类中添加上述的成员变量和成员函数。

 

步骤5:编写CTestMenuView:: CMymenuView构造函数

CTestMenuView::CTestMenuView()

{

// TODO: add construction code here

    m_FontColor=RGB(0,0,0);   //设置默认的颜色

}

 

步骤6:编写CMymenuView::OnDraw()函数。

void CTestMenuView::OnDraw(CDC* pDC)

{

CTestMenuDoc* pDoc = GetDocument();

ASSERT_VALID(pDoc);

// TODO: add draw code for native data here

Redraw(pDC);

}

 

步骤7:分别编写步骤3添加的3个函数,程序如下:

 

void CMymenuView::OnFontcolor1()

{

// TODO: Add your command handler code here

m_FontColor=RGB(250,0,0);

CDC * pDC=GetDC();

Redraw(pDC);

}

 

void CMymenuView::OnFontcolor2()

{

// TODO: Add your command handler code here

m_FontColor=RGB(0,250,0);

CDC * pDC=GetDC();

Redraw(pDC);

}

 

void CMymenuView::OnFontcolor3()

{

// TODO: Add your command handler code here

m_FontColor=RGB(0,0,250);

CDC * pDC=GetDC();

Redraw(pDC);

}

 

步骤8:编写CTestMenuView::Redraw()函数

void CMymenuView::Redraw(CDC *pDC)

{

//设置文本颜色,显示测试内容

    pDC->SetTextColor(m_FontColor);

pDC->TextOut(30,30,"菜单测试程序!");

}

 

步骤9:编译和运行程序,查看程序运行结果。

四、实验总结

1. 总结VC++ 6.0图形程序设计的基本方法和所涉及的基本内容。

2. 分析实验所得到的结果,你可以提出哪些改进?

 

 

补充:

1:导入位图资源获取位图资源号

选择菜单栏->插入->资源,弹出对话框,选择导入按钮,将文件类型改成所有文件,选择想要显示bmp位 图,导入。这样工程的资源位图中,导入的位图默认的ID(资源号)IDB_BITMAP1

2:对话框编程:

查看补充资料


VC6.0常见错误总结

1. 说明哪个function非法的时候,就是符号不匹配(比如说{}(),等等。

2. 用到PI的时候需要在头文件进行宏定义,比如需要在头文件里面宏定义 #define PI 3.1415926

3. error C2065: 'PS_SOLLD' : undeclared identifier

4. error C2065: 'IDB_BITMAP2' : undeclared identifier

5. error C2143: syntax error : missing ',' before '::'

6. error C2589: 'constant' : illegal token on right side of '::'error C2859: g:\

7. error C2859: c:\users\administrator\desktop\1401150220\debug\vc60.pdb is not the pdb file that was used when this precom

解决方法:Rebuild all

8. error C2258: illegal pure syntax, must be '= 0'

原因:1)静态的整型(比如intlongshortenum等)类成员变量可以在定义时直接赋值,可惜VC++6.0太旧了

2)VC++6.0,在类中声明为static 的变量只能在类外面进行赋值

解决方法:

9. error C2018: unknown character '0xb2'

原因:可能是//”注释出错了,只打了一个“/”。

解决办法:修正//”。

10. error C2065: 'CInputD1g' : undeclared identifier

原因:把数字1”和字母“l”混乱在一起了。

11. error C2039: 'CreatPen' : is not a member of 'CPen'

原因:CreatePen拼写错误,也就是说以后要是有这种情况,也可以考虑一下是不是代码拼写错误了

12. error C2065: 'Round' : undeclared identifier

13.  error C2065: 'wxl' : undeclared identifier

14. error C2065: 'poldPen' : undeclared identifier

原因:和11 一样

15. error C2373: 'Round' : redefinition; different type modifiers

原因:定义了两个Round但是,为什么我只要inline const int Round(const double x) {

return ((int)(x + 0.5));

} ,而单独要inline double Round(double d)

{

    return floor(d+0.5);

}

就可以呢?

16.         error C2065: 'Rect' : undeclared identifier

原因:Rect没有定义,用CRect    Rect;就可以了。

 

17. fatal error C1083: Cannot open precompiled header file: 'Debug/1401150326.pch': No such file or directory

解决方法:可以使用右键点击项目工程中的该cpp文件,选择setting,在c/c++栏,选择PreCompiled   headers,然后设置第一选项,选择不使用预编译头,解决这个问题

18.

error LNK2001: unresolved external symbol "protected: void _thiscall CMy1401150326View::OnContextMenu(class CWnd *,class CPoint)" (?OnContextMenu@CMy1401150326View@@IAEXPAVCWnd@@VCPoint@@@Z)

 

原因:我的错误原因就是,我在MFC中定义了几个函数,但是都没有运用这几个函数,所以产生错误。

解决方法:把这几个没用的函数删去。

 

19. 如果报错信息中有关于“位图”的错误,则应该在Resource.h里面添加相关信息:

#define IDD_ABOUTBOX                    100

#define IDR_MAINFRAME                   128

#define IDR_TESTTYPE                    129

#define IDI_ICON1                       130

#define IDI_ICON2                       131

#define IDI_ICON3                       132

#define IDI_ICON4                       133

#define IDB_BITMAP1                     134

#define IDI_ICON5                       135

#define IDB_BITMAP                      136

#define IDB_BITMAP2                     137

#define ID_MENUAntiliasing              32774

#define ID_MENUDrawLine                 32775

#define ID_MENUClip                     32776

#define ID_BUTTON32778                  32778

 

20. 使用位图的时候,需要创建绘图画刷函数,CBrush::CreatePatternBrush

 函数原型:bool CreatePatternBrush(CBitmap* pBitmap);

21. 使用画笔的时候需要创建画笔函数,

原型:bool CreatePen(int nPenStyle,int nWidth,COLORREF crColor)

22. 在用VS2013运行代码的时候为什么会出现闪屏?

  原因:建立的是空项目

  解决方法: 1、在主程序后面加:getchar();语句;
                   结果:黑窗口保留,无任何文字提示;
                   2、在主程序后面加:system("pause");语句。结果:黑窗口保留,出现”请按任意键继续”提示。

 

23.--------------------Configuration: 1exe - Win32 Debug--------------------

Linking...

LIBCD.lib(wincrt0.obj) : error LNK2001: unresolved external symbol _WinMain@16

Debug/1exe.exe : fatal error LNK1120: 1 unresolved externals

Error executing link.exe.

 

1exe.exe - 2 error(s), 0 warning(s)

 

出错原因:在project设置中出错了。在project->setting->Link, Project options中将 /subsystem:console改为/subsystem:windows,而我的是,在Project options中将 /subsystem:console改为/subsystem:windows,我也不知道怎么回事,把/subsystem:windows改为/sub/system:windows反而运行得出结果!



注意:未经允许不可转载!侵犯版权,后果自负!

你可能感兴趣的:(计算机图形学)