序界面左侧面板上的File View。
OutputWnd.h和OutputWnd.cpp:由CDockablePane类派生出COutputWnd类,用于实现应用程序界面下侧面板Output。
PropertiesWnd.h和PropertiesWnd.cpp:由CDockablePane类派生出CPropertiesWnd类,用于实现应用程序界面右侧面板Properties。
ViewTree.h和ViewTree.cpp:由CTreeCtrl类派生出CViewTree类,用于实现出现在ClassView和FileView等中的树视图。
4.资源文件
一般我们使用MFC生成窗口程序都会有对话框、图标、菜单等资源,应用程序向导会生成资源相关文件:res目录、HelloWorld.rc文件和Resource.h文件。
res目录:工程文件夹下的res目录中含有应用程序默认图标、工具栏使用图标等图标文件。 HelloWorld.rc:包含默认菜单定义、字符串表和加速键表,指定了默认的About对话框和应用程序默认图标文件等。
Resource.h:含有各种资源的ID定义。
5.预编译头文件
几乎所有的MFC程序的文件都要包含afxwin.h等文件,如果每次都编译一次则会大大减慢编译速度。所以把常用的MFC头文件都放到了stdafx.h文件中,然后由stdafx.cpp包含stdafx.h文件,编译器对stdafx.cpp只编译一次,并生成编译之后的预编译头HelloWorld.pch,大大提高了编译效率。
6.编译链接生成文件
如果是Debug方式编译,则会在解决方案文件夹和工程文件夹下都生成Debug子文件夹,而如果是Release方式编译则生成Release子文件夹。
工程文件夹下的Debug或Release子文件夹中包含了编译链接时产生的中间文件,解决方案文件夹下的Debug或Release子文件夹中主要包含有应用程序的可执行文件。 关于应用程序工程文件的组成结构鸡啄米就先讲到这了。其中包含了很多专有名词,以后大
家会慢慢熟悉的。欢迎来鸡啄米博客交流。谢谢。
VS2010/MFC编程入门之四(MFC应用程序框架分析)
分类标签: 编程入门 VC++ MFC VS2010
上一讲鸡啄米讲的是VS2010应用程序工程中文件的组成结构,可能大家对工程的运行原理还是很模糊,理不出头绪,毕竟跟C++编程入门系列中的例程差别太大。这一节鸡啄米就为大家分析下MFC应用程序框架的运行流程。
一.SDK应用程序与MFC应用程序运行过程的对比
程序运行都要有入口函数,在之前的C++教程中都是main函数,而Windows应用程序的入口函数是WinMain函数,MFC程序也是从WinMain函数开始的。下面鸡啄米就给出用Windows SDK写的“HelloWorld”程序,与应用程序框架进行对比,这样能更好的了解框架是怎样运行的。Windows SDK开发程序就是不使用MFC类库,直接用Windows API函数进行软件开发。鸡啄米不是要讲解SDK开发,只是为了对比而简单介绍,至于SDK开发可以在大家学完MFC以后选择是否要研究,一般来说有简单了解就可以了。 SDK应用程序
首先,给出Windows SDK应用程序“HelloWorld”的源码:
C++代码
? ?
include
? int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR
szCmdLine, int iCmdShow) ? ? ? ? ? ?
{
const static TCHAR appName[] = TEXT(\ WNDCLASSEX myWin;
myWin.cbSize = sizeof(myWin);
myWin.style = CS_HREDRAW | CS_VREDRAW; myWin.lpfnWndProc = myWndProc;
?? myWin.cbClsExtra = 0; ?? myWin.cbWndExtra = 0;
?? myWin.hInstance = hInstance; ?? myWin.hIcon = 0; ?? myWin.hIconSm = 0; ?? myWin.hCursor = 0;
?? myWin.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); ?? myWin.lpszMenuName = 0;
?? myWin.lpszClassName = appName; ?? //Register
?? if (!RegisterClassEx(&myWin)) return 0; ?? const HWND hWindow = CreateWindow( ?? appName, ?? appName,
?? WS_OVERLAPPEDWINDOW, ?? CW_USEDEFAULT, ?? CW_USEDEFAULT, ?? CW_USEDEFAULT, ?? CW_USEDEFAULT, ?? 0, ?? 0,
?? hInstance, ?? 0);
?? ShowWindow(hWindow,iCmdShow); ?? UpdateWindow(hWindow); ?? {
?? MSG msg;
?? while(GetMessage(&msg,0,0,0)) ?? {
?? TranslateMessage(&msg); ?? DispatchMessage(&msg); ?? }
?? return (int)msg.wParam; ?? } ?? } ??
?? LRESULT CALLBACK myWndProc(HWND hWindow, UINT msg, WPARAM wParam,
LPARAM lParam) ?? {
?? if (msg==WM_PAINT) ?? {
?? PAINTSTRUCT ps;
?? const HDC hDC = BeginPaint(hWindow,&ps); ?? RECT rect;
?? GetClientRect(hWindow,&rect);
?? DrawText(hDC,TEXT(\WORLD\DT_SINGLELINE | DT_CENTER | DT_VCENTER);
?? EndPaint(hWindow,&ps); ?? return 0; ?? }
?? else if (msg==WM_DESTROY) ?? {
?? PostQuitMessage(0); ?? return 0; ?? }
?? return DefWindowProc(hWindow,msg,wParam,lParam); ?? }
上面的程序运行的流程是:进入WinMain函数->初始化WNDCLASSEX,调用RegisterClassEx函数注册窗口类->调用ShowWindow和UpdateWindow函数显示并更新窗口->进入消息循环。关于消息循环再简单说下,Windows应用程序是消息驱动的,系统或用户让应用程序进行某项操作或完成某个任务时会发送消息,进入程序的消息队列,然后消息循环会将消息队列中的消息取出,交予相应的窗口过程处理,此程序的窗口过程函数就是myWndProc函数,窗口过程函数处理完消息就完成了某项操作或任务。本例是要显示“HELLO WORLD”字符串,UpdateWindow函数会发送WM_PAINT消息,但是此消息不经过消息队列而是直接送到窗口过程处理,在窗口过程函数中最终绘制了“HELLO WORLD”字符串。
MFC应用程序
下面是MFC应用程序的运行流程,通过MFC库中代码进行分析:
首先在HelloWorld.cpp中定义全局对象theApp:CHelloWorldApp theApp;。调用CWinApp和CHelloWorldApp的构造函数后,进入WinMain函数(位于appmodul.cpp中)。
C++代码
?? extern \int WINAPI
?? _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, ?? _In_ LPTSTR lpCmdLine, int nCmdShow) ?? #pragma warning(suppress: 4985) ?? {
?? // call shared/exported WinMain
?? return AfxWinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow); ?? }
在TCHAR.h中,有此定义:#define _tWinMain WinMain,所以这里的_tWinMain就是WinMain函数。它调用了AfxWinMain函数(位于WinMain.cpp中)。
C++代码
?? int AFXAPI AfxWinMain(HINSTANCE hInstance, HINSTANCE
hPrevInstance,LPTSTR lpCmdLine, int nCmdShow) ?? {