单文档应用程序的创建过程

在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:

[c-sharp] view plain copy print ?
  1. class CWnd : public CCmdTarget  
  2. {  
  3. …………  
  4. public:  
  5.     // advanced creation (allows access to extended styles)   
  6.     BOOL CreateEx(DWORD dwExStyle, LPCTSTR lpszClassName,  
  7.         LPCTSTR lpszWindowName, DWORD dwStyle,  
  8.         int x, int y, int nWidth, int nHeight,  
  9.         HWND hWndParent, HMENU nIDorHMenu, LPVOID lpParam = NULL);  
  10. …………  
  11. }  

      CFrameWnd类有两个函数成员:Create和LoadFrame:

  1. class CFrameWnd : public CWnd  
  2. {  
  3. …………  
  4. public:  
  5.     BOOL Create(LPCTSTR lpszClassName,  
  6.                 LPCTSTR lpszWindowName,  
  7.                 DWORD dwStyle = WS_OVERLAPPEDWINDOW,  
  8.                 const RECT& rect = rectDefault,  
  9.                 CWnd* pParentWnd = NULL,        // != NULL for popups   
  10.                 LPCTSTR lpszMenuName = NULL,  
  11.                 DWORD dwExStyle = 0,  
  12.                 CCreateContext* pContext = NULL);  
  13.     // dynamic creation - load frame and associated resources   
  14.     virtual BOOL LoadFrame(UINT nIDResource,  
  15.                 DWORD dwDefaultStyle = WS_OVERLAPPEDWINDOW | FWS_ADDTOTITLE,  
  16.                 CWnd* pParentWnd = NULL,  
  17.                 CCreateContext* pContext = NULL);  
  18. …………  
  19. }  

      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类的一个变量成员是:

  1. class CWinThread : public CCmdTarget  
  2. {  
  3. …………  
  4. public:  
  5.     CWnd* m_pMainWnd;   
  6. …………  
  7. }  

      这个变量的类型是CWnd类型。
      CWnd类的声明在AFXWin.h文件中:class CWnd : public CCmdTarget
                      定义在WINCore.cpp文件中:CWnd::CWnd()
      CWnd类的两个函数成员是:

[c-sharp] view plain copy print ?
  1. class CWnd : public CCmdTarget  
  2. {  
  3. …………  
  4. public:  
  5.     BOOL ShowWindow(int nCmdShow);  
  6.     void UpdateWindow();  
  7. …………  
  8. }  

      CWinApp类以public的方式继承CWinThread类,CTestApp类以public的方式继承CWinApp类,所以在CTestApp类中仍然可以访问这个变量成员,而且m_pMainWnd这个变量成员的对外访问属性仍然为public。而m_pMainWnd变量是CWnd类型的,所以这个变量具有ShowWindow()和UpdateWindow()两种属性。在CTestApp类的InitInstance函数中如下代码:

  1. // The one and only window has been initialized, so show and update it.   
  2.  m_pMainWnd->ShowWindow(SW_SHOW);  
  3.  m_pMainWnd->UpdateWindow();  

5.进入消息循环:涉及到CWinThread类,CWinApp类,和CTestApp类
      CWinThread类有两个函数成员:

  1. class CWinThread : public CCmdTarget  
  2. {  
  3. …………  
  4. public:  
  5.     virtual int Run();  
  6.     virtual BOOL PumpMessage();     // low level message pump   
  7. …………  
  8. }  

      CWinApp类以public方式继承CWinThread类之后,重写了Run()函数,但没有重写PumpMessage()函数。

  1. class CWinApp : public CWinThread  
  2. {  
  3. …………  
  4. public:  
  5.     virtual int Run();  
  6. …………  
  7. }     

      CWinThread类的Run()函数就是完成消息循环这一任务的,该函数是在AfxWinMain()函数中被调用的:nReturnCode = pThread->Run();。
      虽然CTestApp类以public方式继承了CWinApp类,但是CTestApp类并没有重写Run()函数。所以这里调用的Run()函数是CWinApp类中的函数成员。其实在CWinApp类的Run()函数内部还调用了CWinThread类的Run()函数,呵呵。CWinThread类的Run()函数内部还调用了一个PumpMessage()函数,这个函数中就包括了win32SDK中的GetMessage(),TranslateMessage(),DispatchMessage()函数等。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值