在Win32 SKD应用程序编程中,创建一个窗口程序的简单过程如下:1.设计一个窗口类;2.注册该窗口类;3.创建一个基于该类的窗口;4.显示及更新窗口;5.进入消息循环。另外还要编写窗口过程函数。在MFC编程中,其实也是有这些步骤的,就是比较隐蔽罢了。以创建一个MFC单文档应用程序为例进行说明。
P66 对于一个单文档应用程序,都有一个CMainFrame类,一个以"C+工程名+App"为名字的类,一个以"C+工程名+Doc"为名字的类和一个以"C+工程名+View"为名字的类。假设建立一个名字为 Test 的工程,肯定会包含下面几个类:CMainFrame类,CTestApp类,CTestDoc类,CTestView类。如下图所示:
在ClassView标签页的类名上双击,右边工作区窗格就会打开定义该类的头文件。
CTestView类派生于CView类,而CView类是由CWnd类派生出来的。
CMainFrame类派生于CFrameWnd类,而CFrameWnd类是由CWnd类派生出来的。
P68 WinMain()函数在APPMODUL.CPP文件中。
P69 CTestApp类派生于CWinApp类,后者表示应用程序类。
P73 为什么要定义一个全局对象theApp,让它在WinMain()函数之前执行呢?该对象的作用是什么呢?该对象就表示了应用程序本身。
使用Win32SDK编写应用程序时,应用程序的句柄由实例句柄来标识。而使用MFC编写应用程序时,应用程序的句柄由一个应用程序类的对象来唯一标识。
P75 AfxWinMain()函数在WINMAIN.CPP文件中。
Afx前缀的函数代表应用程序框架(Application Framework)函数。在MFC中,以Afx为前缀的函数都是全局函数,可以在程序的任何地方调用它们。
P76 CWinApp类派生于CWinThread类
AfxGetThread()函数在THRDCORE.CPP文件中。
P77 AfxGetApp()函数位于AFXWIN1.INL中。
afxCurrentWinApp宏的定义在AFXWIN.H文件中。
1.设计一个窗口类
P78 MFC已经为我们预定义了一些默认的标准窗口类,只需要选择所需的窗口类,然后注册窗口就可以了。所以就不需要再设计窗口类了。
2.注册该窗口类
P78 窗口类的注册是由AfxEndDeferRegisterClass()函数完成的,该函数的定义在WINCORE.CPP文件中。
P80 上面的那个函数内部是调用AfxRegisterClass()函数来注册窗口类的,这个函数的定义在WINCORE.CPP文件中。
P81 AfxRegisterClass()函数最终还是会调用RegisterClass()函数来注册窗口类,这就是Win32 SDK中的函数。
到此为止,就注册了窗口了。
3.创建一个窗口:涉及到CWnd类,CFrameWnd类,CMainFrame类
CFrameWnd类的声明在AFXWin.h文件中:class CFrameWnd : public CWnd
定义在WinFrm.cpp文件中:CFrameWnd::CFrameWnd()
CMainFrame类的声明在AFXWin.h文件中:class CMainFrame : public CFrameWnd
定义在MainFrm.cpp文件中:CMainFrame::CMainFrame()
CWnd类有一个函数成员CreateEx:
CFrameWnd类有两个函数成员:Create和LoadFrame:
CFrameWnd类的LoadFrame()函数会调用Create()函数,而Create()函数又会调用CWnd类的CreateEx()函数。
P82 窗口的创建功能是有CWnd类的CreateEx函数实现的。
P81 我们创建的这个MFC应用程序Test,实际上有两个窗口。
P81 CMainFrame()类有一个PreCreateWindow()函数。
P81 该函数首先会调用CFrameWnd的PreCreateWindow函数,后者在WINFRM.CPP文件中。
4.显示及更新窗口:涉及到CWinThread类,CWinApp类,和CTestApp类;CWnd类。
CWinThread类的声明在AFXWin.h文件中:class CWinThread : public CCmdTarget
定义在ThrdCore.cpp文件中:CWinThread::CWinThread(AFX_THREADPROC pfnThreadProc,LPVOID pParam)
CWinApp类的声明在AFXWin.h文件中:class CWinApp : public CWinThread
定义在AppCore.cpp文件中:CWinApp::CWinApp(LPCTSTR lpszAppName)
CTestApp类的声明在Test.h文件中:class CTestApp : public CWinApp
定义在Test.cpp文件中:CTestApp::CTestApp()
CWinThread类的一个变量成员是:
这个变量的类型是CWnd类型。
CWnd类的声明在AFXWin.h文件中:class CWnd : public CCmdTarget
定义在WINCore.cpp文件中:CWnd::CWnd()
CWnd类的两个函数成员是:
CWinApp类以public的方式继承CWinThread类,CTestApp类以public的方式继承CWinApp类,所以在CTestApp类中仍然可以访问这个变量成员,而且m_pMainWnd这个变量成员的对外访问属性仍然为public。而m_pMainWnd变量是CWnd类型的,所以这个变量具有ShowWindow()和UpdateWindow()两种属性。在CTestApp类的InitInstance函数中如下代码:
5.进入消息循环:涉及到CWinThread类,CWinApp类,和CTestApp类
CWinThread类有两个函数成员:
CWinApp类以public方式继承CWinThread类之后,重写了Run()函数,但没有重写PumpMessage()函数。
CWinThread类的Run()函数就是完成消息循环这一任务的,该函数是在AfxWinMain()函数中被调用的:nReturnCode = pThread->Run();。
虽然CTestApp类以public方式继承了CWinApp类,但是CTestApp类并没有重写Run()函数。所以这里调用的Run()函数是CWinApp类中的函数成员。其实在CWinApp类的Run()函数内部还调用了CWinThread类的Run()函数,呵呵。CWinThread类的Run()函数内部还调用了一个PumpMessage()函数,这个函数中就包括了win32SDK中的GetMessage(),TranslateMessage(),DispatchMessage()函数等。
参考:http://blog.csdn.net/subfly/archive/2010/08/11/5805283.aspx
http://blog.csdn.net/huahuamoon/archive/2008/01/02/2010269.aspx