_tWinMain函数在APPMODUL.CPP中(我们用的WinMain函数)
AfxWinMain函数在WINMAIN.CPP 中,不要因为文件名为WINMAIN而被迷惑。
AfxEndDeferRegisterClass函数在 WINCORE.CPP中。
CWinApp函数在 APPCORE.CPP 中
PreCreateWindow函数在WINFRM.CPP中
AfxDeferRegisterClass在AFXIMPL.H中
第三课MFC主要讲述MFC AppWizard的原理与MFC程序框架的剖析。AppWizard是一个源代码生成工具,是计算机辅助程序设计工具,WinMain在MFC程序中是如何从源程序中被隐藏的,theApp全局变量是如何被分配的,MFC框架中的几个类的作用与相互关系,MFC框架窗口是如何产生和销毁的,对窗口类的PreCreateWidow和OnCreate两个函数的着重分析,Windows窗口与C++中的CWnd类的关系。
MFC是微软提供的一套基础类库,是一套面向对象的函数库,以类的方式提供给我们使用。利用这些类可以有效的帮助我们完成基于windows的应用程序的开发。
以下例开始:
新建一个工程,具体过程如下:
FILE->NEW->PROJECTS->MGC AppWizard[exe]->Projece name: 中填写工程的名称“******”;
Execute Programe 后运行的结果为下图:
红方框中为view类子窗口。 |
AppWizard 是辅助我们生成源代码的工具。不同的选择定制生成不同的代码。
按照刚才的方式建立的工程一行代码也没有写,不过已经是一个完整的程序了。这个程序就是按照应用向导生成的。
生成的类:
class CAboutDlg : public CDialog
class CMainFrame : public CFrameWnd
class CWinnie2_LiApp : public CWinApp
class CWinnie2_LiDoc : public CDocument
class CWinnie2_LiView : public CView
拷贝 CFrameWnd 到MSDN 在Microsoft Foundation Class Library and Templates进行查看。在右边的最下边找到Hierarchy Chart(层次图表)中查看
Hierarchy Chart Categories
l class CAboutDlg : public CDialog
l class CMainFrame : public CFrameWnd
l class CWinnie2_LiApp : public CWinApp
l class CWinnie2_LiDoc : public CDocument
l class CWinnie2_LiView : public CView
对上述的说明:CDialog、CFrameWnd、CView 都来自CWnd 。CWnd封装了跟窗口操作相关的类。
这里边没有WinMain函数,但是这里边的也要有WinMain函数,只是在编译链接由连接器链接到这个函数里边。在VC源代码中查找入口函数WinMain。查找地址为:*\microsoft visual studio\VC98\MFC\SRC ,在这里边用饱含文字的方式进行搜索WinMain,在搜索到APPMODUL.CPP包含了要找的WINMAIN 。
extern "C" int WINAPI
_tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPTSTR lpCmdLine, int nCmdShow)
{
// call shared/exported WinMain
return AfxWinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow);
}
这里边有_tWinMain函数。在此设置断点,按F5(Go)就发现程序会到这个断点里,说明这个APPMODUL.CPP会被函数调用。
#define _tWinMain WinMain 可见_tWinMain 是一个宏。
WinMain()的字母的大小写是有严格规定的,否者编译器找不到需要函数。
SRC里边的内容就是MFC的源代码。
_tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) { // call shared/exported WinMain return AfxWinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow); } |
在三个地方设置断点,Go之后的执行顺序如下:
CWinnie2_LiApp::CWinnie2_LiApp() { // TODO: add construction code here, // Place all significant initialization in InitInstance } |
CWinnie2_LiApp theApp; -> ->
之所以这样我们再打开一个工程来进行说明:
#include <iostream.h>
int a=6;
void main()
l { //在此设置断点;
cout<<a<<endl;
}
调试运行,发现在运行到断点的时候a的值已完成赋值了。即a在main调用之前就已经给全局变量赋了初值。
如下例:
#include <iostream.h>
Class example
l { //1
Public:
example(){}
}
l example ex; //2
main()
l {} //3
执行的顺序是2、1
- liqiangzk982:谢谢大家
- 大虫归来:加油!你一定会实现你的愿望!
- ahyo555:我也要参加自考,加油,向你学习
- ltyjyufo:vc6.0去掉兼容对话框就可以用了,不影响的。。。。
- Muyoo:VS2010跟2008比到底好在哪了呢?
- xiaodong5800:什么叫扫盲贴啊