MFC编程基础 2.docx
- 文档编号:13903321
- 上传时间:2023-06-19
- 格式:DOCX
- 页数:40
- 大小:211.05KB
MFC编程基础 2.docx
《MFC编程基础 2.docx》由会员分享,可在线阅读,更多相关《MFC编程基础 2.docx(40页珍藏版)》请在冰点文库上搜索。
MFC编程基础2
第2章文档/视图结构应用程序
1.文档/视图结构的思想是将数据的管理与显示分离,其中文档用于管理应用程序的数据,而视图是用户界面,用于显示、打印文档中的数据,并管理与用户的交互。
2.SDI具有文档/视图结构的应用程序框架,该框架包括应用程序类、窗口框架类、文档类和视图类,编程的任务是在文档类和视图类中添加适当的代码。
其中文档类中一个重要的成员函数是OnNewDocument(),用户在此添加代码完成对数据的初始化;而视图类中最重要的成员函数是OnDraw(),通过在该函数中添加代码实现窗口内容的输出。
3.通过介绍几种SDI结构的典型应用程序来了解其结构及设计方法,典型应用包括:
• 利用画笔、画刷等工具及位图处理的方法实现文字和图形的输出。
• 利用定时器控件制作动画程序。
• 对鼠标和键盘进行编程的基本方法。
• 文件、字体、颜色等几种通用对话框的使用方法及自定义对话框的设计、调用方法。
• 菜单的设计方法。
2.1文档/视图结构
SDI应用程序由AppWizard创建好后,即使没有编写一行代码,仍然可以运行,并且具有一个标准Windows应用程序所需要的组成成份,程序员的工作就是往这个框架添加必要的代码。
以下通过一个简单实例说明文档/视图结构应用程序的创建过程。
【例2.1】创建一个如图所示的应用程序,在窗口中显示一个矩形框,框中显示“同舟共济自强不息”。
假定本例的工程名为TEST,程序创建过程如下:
(1)利用AppWizard创建一个SDI应用程序框架。
(2)文档类是存放数据的主要地方,本例在其中说明一个存放矩形框数据的CRect类对象r和一个存放字符串的CString对象s,方法为:
在工作区的“ClassView”中,双击CTESTDoc类,在该类代码中添加如下代码:
public:
CRectr;
CStrings;
说明:
CRect是MFC定义的一个类,有4个数据成员:
left、top、right和bottom。
(left,top)和(right,bottom)分别表示一个矩形左上角坐标和右下角坐标。
(3)在文档类的成员函数OnNewDocument()中完成数据成员的初始化。
方法为:
在工作区的ClassView中展开CTESTDoc类,找到其成员函数OnNewDocument(),在其中添加代码:
BOOLCTESTDoc:
:
OnNewDocument()
{if(!
Cdocument:
:
OnNewDocument())
returnFALSE;
//TODO:
addreinitializationcodehere
//(SDIdocumentswillreusethisdocument)
r=CRect(100,60,260,100);
s=”同舟共济自强不息”;
returnTRUE;
} 说明:
阴影部分为添加的代码。
(4)在工作区的“ClassView”中展开视图类CTESTView类,找到其成员函数OnDraw(),添加输出矩形框和文字的代码:
voidCTESTView:
:
OnDraw(CDC*pDC)
{CTESTDoc*pDoc=GetDocument();
ASSERT_VALID(pDoc);
//TODO:
adddrawcodefornativedatahere
pDC->Rectangle(pDoc->r);
pDC->TextOut(110,70,pDoc->s);
}
说明:
①GetDocument()是视图类的一个重要成员函数,其返回值是指向当前文档的指针。
视图类中的成员函数通过它访问文档类的公有数据成员。
②函数OnDraw()是实现输出的关键函数,绝大多数的显示工作都是在这个函数中完成的。
其参数pDC指向窗口中央的客户区对象,程序使用了客户区对象的Rectangle和TextOut函数绘制矩形和输出文字。
(5)运行程序,结果如图所示。
(一)SDI应用程序框架
1.应用程序类
每个应用程序类必须从CWinApp派生出自己的应用程序类,该类封装了包括初始化、运行和结束的整个过程,其名称是AppWizard根据工程名称自动命名的,规则如下:
(1)如果工程名符合标识符的命名规则,则应用程序类名由字母C、工程名和App三部分组成。
例如,工程名为TEST,则应用程序类名为CTESTApp。
(2)如果工程名以数字开始,则应用程序类名由字母Cmy、工程名和App三部分组成。
例如,工程名为1TEST,则应用程序类名为CMy1TESTApp。
(3)忽略工程名的汉字。
文档类和视图类的命名规则与应用程序类类似,区别在于在后面分别添加了Doc和View。
2.窗口框架类
从CMainWnd派生,提供了一个SDI窗口的所有功能,如显示一个标题、一个菜单栏、一个工具栏等。
所有SDI应用程序窗口框架类都是CMainFrame,但是性质是有区别的。
3.文档类
从CDocument类派生出来,是应用程序进行数据定义和初始化的地方。
文档类的数据成员只有被说明成公有成员才能被视图类中的成员函数访问,其重要成员函数是OnNewDocument(),是进行数据成员初始化的地方。
程序开始时会自动调用该函数。
4.视图类
从CView中派生出来,是程序的用户界面,用于显示、打印存储在文档类对象中的数据,并管理与用户的交互。
重要成员函数有:
(1)GetDocument()函数
该函数的返回值是指向与当前视图相关联的文档对象的指针,因而通过它可以访问文档类对象中的公有私有成员。
其一般使用形式为:
CTESTDoc*pDoc=GetDocument();
说明:
①在不同的应用程序中,pDoc所指向的文档类对象的名称是不一样的。
若工程名称为TEST,则文档类的名称为CTESTDoc,若工程名为ABC,则文档类名为CABCDoc,则应用CABCDoc*pDoc定义。
②在OnDraw函数中,这个语句是自动生成的。
在用户自定义的视图类成员函数中,如果需要访问文档类对象的公有数据成员,则应添加这样的语句。
(2)OnDraw()函数
在视图类中,OnDraw()是一个很重要的成员函数,用于实现输出。
一般来说,窗口中的内容都是OnDraw()输出的。
初始的OnDraw()函数如下:
voidCTESTView:
:
OnDraw(CDC*pDC)
{CTESTDoc*pDoc=GetDocument();//获得指向文档类对象的指针
ASSERT_VALID(pDoc);//检查pDoc是否有效,若无效结束程序
//TODO:
adddrawcodefornativedatahere
}
说明:
OnDraw()函数有两种调方法:
①自动调用:
当窗口发生变化视图需要重新绘制时,应用程序会自动调用该函数。
②手工调用:
当程序中的数据改变了需要重新显示时,可以通过调用Invalidate()和InvalidateRect()函数,引发对Ondraw()的调用。
需要注意的是,不是直接调用Ondraw()函数。
Invalidate(TRUE)//擦除窗口原有的内容,重新绘制。
Invalidate(FALSE)//窗口原有的内容保留,再进行绘制。
InvalidateRect(矩形,TRUE)//擦除矩形区域内原有内容,重新绘制这个区域。
InvalidateRect(矩形,FALSE)//矩形区域内原有内容保留,再绘制这个区域。
2.2图形和文字的输出
窗口中央的客户区是一个输出文字和图形的区域。
简单的文字和图形输出
文字输出
形式:
BOOLTextOut(intx,inty,LPCTSTRlpszString,intnCount);
说明:
从坐标(x,y)开始显示lpszString字符串,其中参数nCount指定字符串中的字节数。
画点
形式:
COLORREFSetPixel(intx,inty,COLORREFcrColor);
COLORREFSetPixel(POINTpoint,COLORREFcrColor);
说明:
①POINT是MFC定义的结构类型,表示平面上的一个点。
它的两个重要元素是x和y,分别表示一个点的x坐标值和y坐标值。
与POINT类似的是CPoint类,两个数据成员也是x和y。
②COLORREF是一个32位整数类型,用于表示颜色,其第0、1、2字节分别存放了一种颜色的红、绿、蓝的值。
用三种颜色合成一种颜色的函数是RGB,例如:
COLORREFC1=RGB(0,0,0);//合成黑色
COLORREFC2=RGB(255,255,255);//合成白色
COLORREFC3=RGB(255,0,0);//合成红色
COLORREFC4=RGB(0,255,0);//合成绿色
COLORREFC5=RGB(0,0,255);//合成蓝色
COLORREFC6=RGB(255,255,0);//合成亮黄色
COLORREFC7=RGB(0,255,255);//合成青色
COLORREFC8=RGB(255,0,255);//合成品红色
COLORREFC9=RGB(0,0,128);//合成深蓝色
COLORREFC10=RGB(0,128,0);//合成深绿色
COLORREFC11=RGB(128,128,128);//合成深灰色
COLORREFC12=RGB(128,128,128);//合成浅灰色
③使用指定颜色crColor在坐标(x,y)或点point处画一个点,返回用于画点的颜色。
画线
画线需要调用两个函数:
首先调用MoveTo函数确定线段的起点,然是调用LineTo确定线段的终点。
形式:
CPointMoveTo(intx,inty);
CPointMoveTo(POINTpoint);
BOOLLineTo(intx,inty);
BOOLLineTo(POINTpoint);
说明:
(x,y)或point是线段的起点或终点坐标。
画矩形
形式:
BOOLRectangle(intx1,inty1,intx2,inty2);
BOOLRectangle(LPCRECTlpRect);
说明:
(x1,y1)和(x2,y2)是所画矩形的左上角和右下角坐标,lpRect是指向矩形的指针。
画椭圆
形式:
BOOLEllipse(intx1,inty1,intx2,inty2);
BOOLEllipse(LPCRECTlpRect);
说明:
(x1,y1)和(x2,y2)是椭圆外接矩形的左上角和右下角坐标,lpRect是指向外接矩形的指针。
获取客户区的大小
使用Wnd类的成员函数GetClientRect可以将客户区的坐标放入一个CRect类的对象中,然后调用成员函数计算到高度和宽度。
形式:
voidGetClientRect(LPRECTlpRect)const;
【例2.2】改变窗口时,矩形框和文字总是显示在窗口的中央
voidCTESTView:
:
OnDraw(CDC*pDC)
{
CTESTDoc*pDoc=GetDocument();
ASSERT_VALID(pDoc);
//TODO:
adddrawcodefornativedatahere
CRecta,b;
intw=160;
inth=40;
GetClientRect(&a);
b.left=(a.Width()-w)/2;
b.top=(a.Height()-h)/2;
b.right=b.left+w;
b.bottom=b.top+h;
pDC->Rectangle(b);
pDC->TextOut(b.left+10,b.top+10,"同舟共济、自强不息!
");
}
【例2.3】编写一个程序,绘制如图所示的-2π~2π之间的sin曲线。
因为需要使用sin()函数,所以在TEST.CPP的开始添加文件包含命令。
#include"math.h"
程序代码:
…………………………………………………………
voidCTESTView:
:
OnDraw(CDC*pDC)
{CTESTDoc*pDoc=GetDocument();
ASSERT_VALID(pDoc);
//TODO:
adddrawcodefornativedatahere
CRectrect;
GetClientRect(rect);
intx0=rect.Width()/2;
inty0=rect.Height()/2;
pDC->MoveTo(20,y0);
pDC->LineTo(rect.Width()-20,y0);
pDC->MoveTo(x0,20);
pDC->LineTo(x0,rect.Height()-20);
doublestep=3.14159/100;
for(inti=-200;i<200;i++)
pDC->SetPixel(x0+(i/300.0)*rect.Width()/2,y0-sin(step*i)*rect.Height()/4,RGB(255,0,0));
}
…………………………………………………………
去掉窗口的“无标题”及设置新标题
BOOLCMainFrame:
:
PreCreateWindow(CREATESTRUCT&cs)
{
if(!
CFrameWnd:
:
PreCreateWindow(cs))
returnFALSE;
//TODO:
ModifytheWindowclassorstylesherebymodifying
//theCREATESTRUCTcs
cs.style&=~FWS_ADDTOTITLE;//去掉无标题
m_strTitle="绘制sin曲线";//设置新标题
returnTRUE;
}
画笔和画刷
自定义画笔
CPen是MFC中的一个类,它封装了一个WinndowsGDI画笔,并提供了用于操作画笔的若干函数。
画笔的创建和使用过程一般为:
CPenpen,*oldpen;//定义画笔pen和指向画笔的指针oldpen
pen.CreatePen(PS_SOLID,3,RGB(255,0,0));//创建一支红色能画实线3号粗细的画笔
oldpen=pDC->SelectObject(&pen);//选用新的画笔pen,让oldpen指向旧的画笔
pDC->MoveTo(10,10);
pDC->LineTo(50,50);
pDC->SelectObject(oldpen);//恢复使用旧的画笔
说明:
(1)CreatePen()是CPen的成员函数,用于创建画笔。
其使用形式为:
BOOLCreatePen(intnPenStyle,intnWidth,COLORREFcrColor);
其中:
nPenStyle为所画线的样式,其取值见表;nWidth线的宽度;crColor为线的颜色。
(2)SelectObject()是CDC类的成员函数,其作用是将一个新的GDI对象选入到设备环境中,新选用的对象取代原来的对象,然后返回指向原对象的指针。
函数原型为:
CPen*SelectObject(Cpen*pPen);//选用新的画笔
Cbrush*SelectObject(Cbrush*pBrush);//选用新的画刷
virtualCfont*SelectObject(Cfont*pFont);//选用新的字体
Cbitmap*SelectObject(Cbitmap*pBitmap);//选用新的位图
自定义画刷
画刷是用来填充图形的工具。
CBrush是MFC中的一个类,它封装了一个WindowsGDI画刷,并提供了用于操作画刷对象的若干方法。
画刷的创建和使用过程一般为:
CBrushbrush;//定义画刷对象brush
brush.CreateHatchBrush(HS_CROSS,RGB(0,255,0));//构造绿色十字线风格的画刷
pDC->SelectObject(&brush);//选择一个新的画刷
pDC->Ellipse(100,10,200,110);//用新的画刷画圆
说明:
(1)CreateHatchBrush()是CBrush的成员函数,用于创建画刷。
其使用形式为:
BOOLCreateHatchBrush(intnIndex,COLORREFcrColor);
其中:
nIndex指定了阴影风格,其取值见表;crColor为画刷的颜色。
(2)创建画刷的另一个函数是CreateSolidBrush(),其作用是创建用单一颜色填充的画刷。
其函数原形为:
BOOLCreateSolidBrush(COLORREFcrColor);
【例2.4】编写一个程序,输出如图所示的图形。
…………………………………………………………
voidCTESTView:
:
OnDraw(CDC*pDC)
{CTESTDoc*pDoc=GetDocument();
ASSERT_VALID(pDoc);
//TODO:
adddrawcodefornativedatahere
CPenpen,*oldpen;
pen.CreatePen(PS_SOLID,3,RGB(255,0,0));
oldpen=pDC->SelectObject(&pen);
pDC->MoveTo(10,10);
pDC->LineTo(100,100);
pDC->Ellipse(100,10,200,110);
Cbrushbrush;
brush.CreateHatchBrush(HS_CROSS,RGB(0,255,0));
pDC->SelectObject(&brush);
pDC->Ellipse(220,10,320,110);
pDC->SelectObject(oldpen);
pDC->MoveTo(320,100);
pDC->LineTo(410,10);
pen.DeleteObject();//释放画笔资源
brush.DeleteObject();
}
…………………………………………………………
位图处理
CBitmap是MFC中的一个类,它封装了WinndowsGDI的位图处理,其成员函数主要是装载和操作位图。
通过一个实例说明显示位图的一般过程。
【例2.5】编一程序显示Windows主目录中的SoapBubbles.bmp,如图所示。
(1)导入位图
导入位图就是把存放在磁盘上的位图文件作为资源导入到应用程序中,方法是:
选择“插入|资源”命令,在弹出的“插入资源”对话框中,选定“Bitmap”,然后选择“导入”命令导入SoapBubbles.bmp。
(2)装载位图
装载位图就是把应用程序位图资源装载到一个Cbitmap对象中。
CBitmapb;
b.LoadBitmap(IDB_BITMAP1);//LoadBitmap将位图资源装载到CBitmap对象
(3)读取位图信息
BITMAPbm;//说明bm为BITMAP结构类型的变量
b.GetBitmap(&bm);//把位图的大小等信息读入bm中
intw=bm.bmWidth;//把位图的宽度赋给w
inth=bm.bmHeight;//把位图的高度赋给h
(4)构造内存设备环境,并将位图装入该设备环境
CDCm;
m.CreateCompatibleDC(NULL);
m.SelectObject(&b);
(5)将位图从内存设备环境复制到真正的设备环境中
pDC->StretchBlt(0,0,(int)w*f,(int)h*f,&m,0,0,w,h,SRCCOPY);
说明:
BitBlt是CDC类的成员函数,用于复制位图到真正的设备环境中。
其函数原型为:
BOOLBitBlt(intx,inty,intnWidth,intnHeight,CDC*pSrcDC,intxSrc,intySrc,DWORDdwRop);
其中:
(x,y)为位图显示区域左上角的坐标;nWidth和nHeight是显示区域的宽度和高度;pSrcDC指向内存设备环境;(x
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- MFC编程基础 MFC 编程 基础