VC++实验报告1.docx
《VC++实验报告1.docx》由会员分享,可在线阅读,更多相关《VC++实验报告1.docx(23页珍藏版)》请在冰豆网上搜索。
![VC++实验报告1.docx](https://file1.bdocx.com/fileroot1/2023-6/9/a22d0475-dace-4691-b5b1-b2b9ec133c03/a22d0475-dace-4691-b5b1-b2b9ec133c031.gif)
VC++实验报告1
实验一、HelloWorld在VC上的实现
姓名:
郭殷蓉学号:
E10700102班级:
10数媒1班
1.1实验目的
●掌握Windows程序基本的运行原理。
●学会编写简单的Windows程序。
1.2实验平台
●WindowsXPprofessional操作系统。
●VC6.0集成开发环境。
1.3实验内容
●用WindowsAPI(SDK)实现图形化HellowWorld程序。
●用MFC类库实现图形化HellowWorld程序。
1.4实验原理
●Windows操作介绍
Windows是一种基于图形界面的多任务操作系统。
对于普通用户来说,Windows图形化界面友好、操作简单,用户不需要花费长时间学习如何使用计算机和新程序,因为所有的Windows应用程序都具相近的外观和感觉;对于程序员来说,标准化的图形用户界面来自于Windows构造菜单和对话框的内置程序,这些工作由Windows处理,与应用程序无关,使程序员可以编写出易于用户操作的程序。
●Windows编程模型
Windows程序采用如下图所示的事件驱动编程模型,应用程序通过处理操作系统发送出来的消息来响应事件。
消息处理是所有Windows应用程序的的核心。
Windows程序的进入点是WinMain函数,但大多时候操作是在成为窗口过程的函数中进行的。
窗口过程函数处理发送给窗口的消息。
WinMain创建该窗口并进入消息循环,即获取消息或将其调度给窗口过程。
消息被检索之前处于消息队列中等待。
ØWindows定义了成百上千个不同的消息类型。
大多数消息的开始字符为“WM”并带有下划线;
Ø操作系统是通过消息机制(Message)来实现将事件传递给应用程序的。
操作系统将每个事件都包装成一个称为消息的结构体MSG来传递给应用程序(详见MSDN)。
Ø操作系统把它所能够完成的功能以函数的形式提供给应用程序使用,应用程序对这些函数的调用就叫做系统调用,这些函数的集合就是Windows操作系统提供给应用程序编程的接口(ApplicationProgrammingInterface),简称WindowsAPI(C函数)。
●MFC简介
MFC(MicrosoftFoundationClass)是微软公司提供的专门用于Windows编程的基础类库,它大约包含了200个C++类,这些类库实际上是对WindowsAPI的一次C++的封装。
这些类可以处理许多标准的Windows编程任务。
MFC框架结构如下图所示:
1.CObject类
CObject类是MFC类库的根类,它几乎描述了MFC类的一些公共特性。
2.CCmdTarget类
CCmdTarget类是MFC的消息映射基础类,MFC为该类设计了许多的成员变量及函数以解决消息映射的问题。
派生于CCmdTarget的类可用于处理当用户选择菜单或单击按钮等操作时所产生的Command消息。
3.CWinThread类
CWinThread类是MFC中用于封装线程的类,它的成员函数可以使MFC应用程序创建和管理包括UI及工作者在内的线程。
每个MFC应用程序都至少应该使用一个从CWinThread派生的类,应用程序类CWinApp就是一个代表。
4.CWinApp类
CWinApp类通常代表应用程序自己,它封装了应用程序的初始化、运行及终止的过程。
基于框架的应用程序必须有且仅有一个派生于CWinApp的类的对象,并在完成窗口的创建工作之前执行对该对象的构造。
应用程序类的对象需要完成以下工作:
初始化应用程序。
建立文档模板结构。
循环检索消息队列中的消息并将这些消息发送到指定的地方。
执行应用程序退出时的清理工作。
5.CDocument类
CDocument类是在使用文档/视图结构的应用程序中文档对象的基类,它为应用程序的文档对象提供了基本的功能,包括新建、串行化数据等。
6.CWnd类
CWnd类是所有MFC窗口的基类,它封装了窗口的基本操作,包括窗口的创建、销毁、设置窗口风格等,以及窗口对大部分消息的默认响应。
开发人员可以直接从CWnd派生其他类,但通常情况下我们并不这么做,而是通过继承CWnd的派生类生成新类。
7.CView类
CView类是在使用文档/视图结构的应用程序中视图对象的基类,它是用户的主要操作界面。
在应用程序中,一个视图对象通常只对应一个文档对象,但一个文档对象却可以关联多个视图对象,并且每个视图对象都以不同的形式来显示文档中的数据。
8.CFrameWnd类
CFrameWnd类往往用于创建应用程序的主窗口,并定义了大量管理视图和文档对象的成员函数及变量。
在编写文档/视图结构的应用程序时,视图对象等将作为CFrameWnd的子窗口实现对客户区的共享,并被CFrameWnd有序排列。
9.CDocTemplate类
CDocTemplate类是AppWizard生成的文档模板类。
●MFC应用程序执行过程:
MFC应用程序启动时,首先创建应用程序对象theApp。
这时将自动调用应用程序类
的构造函数初始化对象theApp,然后由应用程序框架调用MFC提供的AfxWinMain()主函数。
在AfxWinMain()主函数中,首先通过调用全局函数AfxGetApp()来获取theApp的指针pApp,然后通过该指针调用theApp的成员函数InitInstance()来初始化应用程序。
在应用程序的初始化过程中,同时还构造了文档模板,产生最初的文档、视图和主框架窗口,并生成工具栏和状态栏。
当InitInstance()函数执行完毕后,WinMain()函数将调用成员函数Run(),进入消息处理循环,直到函数Run()收到WM_QUIT消息。
MFC首先调用CWinApp类的成员函数ExitInstance(),然后调用静态对象的析构函数,包括CWinApp对象,最后退出应用程序,将控制权交给操作系统。
任何—个对象都可以通过调用全局函数AfxGetApp()或AfxGetInstanceHandle()来获取应用程序对象;通过调用全局函数AfxGetMainWnd()来获得程序主窗口。
●消息映射与消息处理
消息映射是将消息处理函数与它要处理的特定消息连接起来的一种机制。
消息映射是应用MFC方法进行Windows编程的主要组成部分。
Windows消息主要有3种类型,即标准Windows消息、控件消息和命令消息。
1.标准Windows消息
除WM_COMMAND以外,所有以“WM_”为前缀的消息都是标准Windows消息。
标准的Windows消息由窗口类或视图类处理。
标准Windows消息都有默认的处理函数,这些函数在CWnd类中进行了预定义。
MFC类库以消息名为基础形成这些处理函数的名称,这些函数的名称都以前缀“On”开始。
有的处理函数不带参数,有的带几个参数。
这些消息处理函数的说明一般都有“afx_msg”的前缀,用于把处理函数与其他的窗口成员函数区分开来,这些函数都是通过消息映射实现的。
标准的Windows消息又分为3类:
键盘消息、鼠标消息和窗口消息:
a)键盘消息
键盘消息与键盘某个键的动作相关联。
常见的键盘消息有以下几种。
WM_KEYDOWN、WM_KEYUP:
按下、释放非系统键产生的消息。
WM_CHAR:
输入非系统字符时产生的消息。
所有键盘消息处理函数的原型都很相似。
我们以WM_CHAR消息的处理函数OnChar()为例来进行说明。
此函数的原型如下:
afx_msgvoidOnChar(UINTnChar,UINTnRepCnt,UINTnFlags);
其中,参数nChar是所按键的字符代码值;nRepCnt表示用户重复击键的次数;nFlags表示扫描码、先前键状态和键转换状态等,其具体含义见下表:
b)鼠标消息
常用的鼠标消息有以下几种。
WM_MOUSEMOVE:
鼠标移动时产生的消息。
WM_RBUTTONDOWN:
鼠标右键按下时产生的消息。
WM_LBUTTONDOWN:
鼠标左键按下时产生的消息。
WM_LBUTTONDBLCLICK:
鼠标双击时产生的消息。
所有鼠标操作的处理函数都有很相似的原型,它们都有两个参数。
我们以处理鼠标左键按下消息的函数OnLButtonDown()为例来进行说明。
此函数的原型如下:
afx_msgvoidOnLButtonDown(UINTnFlags,CPointpoint);
其中参数point是鼠标事件发生时鼠标光标所在的位置。
它是相对于窗口左上角的水平X坐标和垂直的Y坐标而言的。
参数nFlags指明鼠标按键的状态以及鼠标事件发生时键盘上某些键的状态,每一状态都可以用nFlags的一位来表示,具体含义见下表:
c)窗口消息
窗口消息一般与创建窗口、绘制窗口、移动窗口和销毁窗口等动作有关。
在MFC应用程序中,窗口消息是由视图类、窗口类及它们的派生类处理的。
常见的窗口消息如下。
WM_PAINT:
当客户区产生移动或者显示事件,当用户窗口产生改变大小事件,当产生下拉菜单关闭并需要恢复被覆盖部分事件,当产生Windows清除对话框或者消息框并需要恢复被覆盖部分事件时,会产生WM_PAINT消息。
它的消息处理函数原型为:
afx_msgvoidOnPaint();
WM_TIMER:
每当计时器被触发时,系统就发送WM_TIMER消息。
它的消息处理函数原型为:
afx_msgvoidOnTimer(UNITnIDEvent);
其中,参数nIDEvent是计时器的标识符。
2.控件消息
控件消息是指控件或其他子窗口向父窗口发送的WM_COMMAND消息。
发送控件消息的控件使用唯一的ID号来识别,使用控件类来操纵。
从控件传给系统的消息,它的前缀的最后一个字符为N;由系统发送给控件的消息,其前缀的最后一个字符为M。
3.命令消息
命令消息是由菜单项、工具栏按钮、快捷键等用户界面对象发出的WM_COMMAND消息。
命令消息与其他消息不同,它可被更广泛的对象如文档、文档模板、应用程序对象、窗口和视图等处理。
●MFC消息映射机制
MFC采用消息映射来处理消息。
这种消息映射机制包括一组消息映射宏,用于把一个Windows消息和其消息处理函数联系起来。
MFC应用程序框架提供了消息映射功能,所有从CCmdTarget类派生出来的类都能够拥有自己的消息映射。
与MFC消息映射机制有关的宏有以下3个:
DECLARE_MESSAGE_MAP()宏、BEGIN_MESSAGE_MAP(MyClass,MybaseClass)宏和END_MESSAGE_MAP()宏。
为了使用消息映射宏,首先在类定义的结尾用DECLARE_MESSAGE_MAP()宏来声明使用消息映射,该宏表示在为各个处理函数所写的类声明之后存在消息映射条目,这些函数是该类的成员函数。
然后在类的实现源文件中用BEGIN_MESSAGE_MAP()和END_MESSAGE_MAP()宏来定义消息映射。
MFC应用程序MESSAG_MAP消息映射的形式如下所示:
BEGIN_MESSAGE_MAP(theclass,thebaseclass)
//{{AFX_MSG_MAP(MyClass)//ClassWizard维护消息映射宏的标记
ON_...//MFC预定义消息映射宏
ON_MESSAGE(message,memberFun)//用户自定义消息映射宏
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
其中,MyClass是拥有消息映射的派生类名,MybaseClass是其基类名。
对于不同类型的消息,消息映射宏的格式及参数是不同的,见下表:
●Windows编程帮助文档
MSDN的全称是MicrosoftDeveloperNetwork,这是微软公司面向软件开发者的一种信息服务,涵盖了微软全套可开发产品线的技术开发文档和科技文献(部分包括源代码)。
在编写Windows应用程序时候可以借助MSDN查阅相关WindowsAPI(PlatformSDK)和MFC基础类(MicrosoftFoundationClassLibrary)的详细用法。
1.5实验步骤
●用WindowsAPI(SDK)实现HellowWorld程序
Ø打开VC6.0,从File菜单中选择New,单击Project标签,选择Win32Application,输入项目名称和工程存放目录,点击确定后出现3中选择,在此选择创建一个空的工程,点击工程的FileView,向SourceFiles中添加源文件,然后编写代码。
ØWindows程序的入口函数:
我们编写过Win32控制台程序,这种程序的唯一入口为main()函数,那么对于Windows应用程序,它的入口函数为WinMain(),由操作系统调用。
它的函数原型如下:
intWINAPIWinMain(
HINSTANCEhInstance,//handletocurrentinstance
HINSTANCEhPrevInstance,//handletopreviousinstance
LPSTRlpCmdLine,//commandline
intnCmdShow//showstate
);
Ø窗口的创建
创建一个完整的窗口需要经过下面四个操作步骤:
●设计一个窗口类:
Windows已经为程序员定义了一个窗口应该具有的基本属性,即WNDCLASS类(结构体),定义如下:
typedefstruct_WNDCLASS{
UINTstyle;//窗口风格
WNDPROClpfnWndProc;//窗口过程
intcbClsExtra;//扩展空间
intcbWndExtra;//扩展空间
HINSTANCEhInstance;//实例句柄
HICONhIcon;//图标设置
HCURSORhCursor;//光标设置
HBRUSHhbrBackground;//窗口背景颜色
LPCTSTRlpszMenuName;//窗口类菜单
LPCTSTRlpszClassName;//窗口类文本名称
}WNDCLASS,*PWNDCLASS;
用WNDCLASS定义一个窗口变量,然后依次初始化起它的每一个成员,注意:
第二个成员变量lpfnWndProc指定了这一类型窗口的过程函数(函数名可以作为该函数的首地址),也称回调函数。
每一种不同类型的窗口都有自己专用的回调函数。
●注册窗口类:
调用RegisterClass()函数注册窗口,函数原型如下:
ATOMRegisterClass(CONSTWNDCLASS*lpWndClass);
●创建窗口:
调用CreateWindow()函数创建窗口,函数原型如下:
HWNDCreateWindow(
LPCTSTRlpClassName,//registeredclassname
LPCTSTRlpWindowName,//windowname
DWORDdwStyle,//windowstyle
intx,//horizontalpositionofwindow
inty,//verticalpositionofwindow
intnWidth,//windowwidth
intnHeight,//windowheight
HWNDhWndParent,//handletoparentorownerwindow
HMENUhMenu,//menuhandleorchildidentifier
HINSTANCEhInstance,//handletoapplicationinstance
LPVOIDlpParam//window-creationdata
);
●显示及更新窗口:
在CreateWindow()调用返回后,Windows已经分配了一块内存,用于保存创建窗口的全部信息,然而窗口并未在显示器上显示,所以需要调用ShowWindow()函数显示窗口和UpdateWindow()更新窗口,两个函数原型分别为:
BOOLShowWindow(
HWNDhWnd,//handletowindow
intnCmdShow//showstate
);
更新窗口函数原型:
BOOLUpdateWindow(
HWNDhWnd//handletowindow
);
Ø消息循环
当窗口显示在显示器上后,程序必须准备读入用户用键盘和鼠标输入的数据。
Windows为每一个应用程序维护一个“消息队列”,当发生输入事件后,Windows将事件转化成一个消息,并将消息放入程序的消息队列中。
程序通过执行以下一段代码从消息队列中取出消息:
while(GetMessage(&msg,NULL,0,0))//获取消息
{
TranslateMessage(&msg);//消息翻译
DispatchMessage(&msg);//发送消息给窗口过程
}
Msg变量为MSG结构体类型,类型定义如下:
typedefstructtagMSG{
HWNDhwnd;
UINTmessage;
WPARAMwParam;
LPARAMlParam;
DWORDtime;
POINTpt;
}MSG,*PMSG;
Ø头文件包含
在每一个Windows程序C语言编写的Windows程序都可以看到#include。
Windows.h是主要的包含文件,它包含的windows的其它头文件,这些头文件中最重要和最基本的是:
1.WINDEF.H基本类型定义
2.WINNT.H支持Unicode类型定义
3.WINBASE.H内核函数
4.WINUSER.H用户接口函数
5.WINGDI.H图形设备接口函数
上面程序使用到得Windows系统调用函数均在MSDN中平台SDK文档中说明,并在不同的头文件中声明,其中绝大多数是在WINUSER.H中声明的。
●用MFC类库实现HellowWorld程序
Ø打开VC6.0,从File菜单中选择New,单击Project标签,选择Win32Application,输入项目名称和工程存放目录,选择创建一个空的工程,点击工程的FileView,在HeadFiles中添加Hello.h文件,将类的定义均放在头文件里,需要定义两个类:
应用程序类CMyApp类从CWinApp类继承;窗口类CMainWindow类从CFrameWnd类继承;向SourceFiles中加入Hello.cpp文件,输入类的成员函数定义。
选择菜单Project/settings(或Alt+F7),在ProjectSettings对话框中的General页中的MicrosoftFoundationClasses:
选择UseMFCinaStaticLibrary或UseMFCinaSharedDLL,然后编译运行。
1.6实验程序实现
●SDK实现代码:
#include
#include
//窗口过程函数声明:
LRESULTCALLBACKWinLiuProc(
HWNDhwnd,//handletowindow
UINTuMsg,//messageidentifier
WPARAMwParam,//firstmessageparameter
LPARAMlParam//secondmessageparameter
);
intWINAPIWinMain(
HINSTANCEhInstance,//handletocurrentinstance
HINSTANCEhPrevInstance,//handletopreviousinstance
LPSTRlpCmdLine,//pointertocommandline
intnCmdShow//showstateofwindow
)
{
HWNDhwnd;//窗口句柄
MSGmsg;//消息
//声明一个窗口类
WNDCLASSwndcls;
//设置窗口类的属性:
wndcls.cbClsExtra=0;
wndcls.cbWndExtra=0;
wndcls.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);
wndcls.hCursor=LoadCursor(hInstance,IDC_ARROW);
wndcls.hIcon=LoadIcon(hInstance,IDI_APPLICATION);
wndcls.hInstance=hInstance;
wndcls.lpfnWndProc=WinLiuProc;
wndcls.lpszClassName="Windowsprogtest";
wndcls.lpszMenuName=NULL;
wndcls.style=CS_HREDRAW|CS_VREDRAW;
//注册窗口类
RegisterClass(&wndcls);
//创建窗口
hwnd=CreateWindow("Windowsprogtest",TEXT("TheHelloProgram,SDKstyle"),WS_OVERLAPPEDWINDOW|WS_VISIBLE,
CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,
NULL,NULL,hInstance,NULL);
//显示窗口
ShowWindow(hwnd,SW_SHOWNORMAL);
//更新窗口
UpdateWindow(hwnd);
/*消息循环*/
//从消息队列中循环读取有效消息,如果是有效消息,则复制到msg中,然后从队列中删除该消息
while(GetMessage(&msg,NULL,0,0))//当接收到一个WM_QUIT消息后,退出消息循环
{
//将一个指示字符键的键盘消息转化为容易使用的WM_CHAR消息
TranslateMessage(&msg);
//将消息发送给窗口过程
DispatchMessage(&msg);
}
return0;
}
LRESULTCALLBACKWinLiuProc(
HWNDhwnd,//handletowindo