VC++ 之MFC内部机制二

 

二、

 

  完成WinMain函数主要完成窗口产生过程,即:

  设计窗口,注册窗口,构造窗口,显示窗口,更新窗口,消息循环,处理消息。

 

1.CWinApp内部运行机制

  CWinApp---在appmodul.cpp中

  具体的可以参考CWinApp函数。

1)

  pThreadState->m_pCurrentWinThread = this;

  这里的this指针是指向CWinApp子类CTestApp对象theApp的指针;

2)

  CWinApp运行完成,即基类构造函数完成,从而基子类CTestApp构造函数也初始化完成,然后

为子类CTestApp对象theApp分配完内存空间。接下来,进入入口函数WinMain中。

 

CWinApp在appcore.cpp中--全局对象theApp--子类构造函数调用CTestApp()--基类构造函数调用CWinApp()在appcore.cpp中

 

2.WinMain 即(_tWinMain()函数)函数

WinMain函数---在appcore.cpp中

AfxWinMain函数---在winmain.cpp中

(以Afx开头的是全局函数,可以被其它对象调用)

 

WinMain函数主要完成窗口产生过程,即:

  设计窗口,注册窗口,构造窗口,显示窗口,更新窗口,消息循环,处理消息。

 

1)注册窗口前的初始化工作

  由pThread->InitInstance()完成

 

  AfxWinMain函数下面方法:

CWinThread* pThread = AfxGetThread();

CWinApp* pApp = AfxGetApp();

 

AfxGetThread()和 AfxGetApp() 都是获得在CWinApp中构造函数内赋给 pThreadState->m_pCurrentWinThread 对象

的this指针,也即是获得指向子类CTestApp对象theApp的指针,保存在pThread与pApp中。所以实际上pThread与pApp

都是保存的theApp指针。

 

  pThread与pApp 共调用了三个方法,即子类对象theApp调用了三个方法:

 

  pApp->InitApplication() MFC内部初始化管理所调用的函数 

  pThread->InitInstance() 因CWinThread类中InitInstance()为虚函数,由多态原理,所以这里调用的是子类CTestApp中的InitInstance()

  pThread->Run()          完成消息循环

 

  其中

  pThread->InitInstance() 初始化完成后,即开始注册窗口

 

  CWinApp在appcore.cpp中--全局对象theApp--子类构造函数调用CTestApp()--基类构造函数调用CWinApp()在appcore.cpp中

--_tWinMain()在appmodul.cpp中--AfxWinMain()中的pThread->InitInstance()在winmain.cpp中--调用CTestApp::InitInstance()在当前项目

  --设计注册窗口

 

2)设计窗口

 AfxEndDeferRegisterClass()完成(有很多if语句中).

  AfxEndDeferRegisterClass()---在wincore.cpp中.

  MFC中默认定义了几种窗口类,只是调用函数AfxEndDeferRegisterClass()就可以完成设计窗口过程。

  在里面会根据应用程序要求的不同窗口类型设计不同的窗口,在很多if条件语句中。

 

 

3)注册窗口

  在AfxEndDeferRegisterClass()函数中,由AfxRegisterClass()完成.

  AfxEndDeferRegisterClass()---在wincore.cpp中.

 

  在AfxRegisterClass()函数中

  AfxCtxGetClassInfo() 判断要注册的窗口是否已经注册.

 

  注意:

  单文档结构和多文档结构在注册窗口上有不同的顺序.

  单文档结构:先就调用AfxEndDeferRegisterClass() 进行窗口注册

  多文档结构:先调用 

             子类CMainFrame::PreCreateWindow(CREATESTRUCT& cs) 

             再调用基类CFrameWnd::PreCreateWindow(CREATESTRUCT& cs) 

             再调用AfxEndDeferRegisterClass()进行窗口注册

 

4)产生窗口之前

  (单文档结构)     

  CWinApp在appcore.cpp中--全局对象theApp--子类构造函数调用CTestApp()--基类构造函数调用CWinApp()在appcore.cpp中

--_tWinMain()在appmodul.cpp中--AfxWinMain()中的pThread->InitInstance()在winmain.cpp中--调用CTestApp::InitInstance()在当前项目

--设计窗口AfxEndDeferRegisterClass()在wincore.cpp中--注册窗口AfxEndDeferRegisterClass()中的AfxRegisterClass()在wincore.cpp中

  --产生窗口之前调用子类CMainFrame::PreCreateWindow(CREATESTRUCT& cs)在MainFrm.cpp中--产生窗口之前调用基类CFrameWnd::PreCreateWindow(CREATESTRUCT& cs)在winfrm.cpp中

  --注册窗口AfxDeferRegisterClass(AFX_WNDFRAMEORVIEW_REG)在wincore.cpp中

 

 

  BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs) 在当前工程的MainFrm.cpp中

  BOOL CFrameWnd::PreCreateWindow(CREATESTRUCT& cs)  在winfrm.cpp中

 

  调用AfxDeferRegisterClass(AFX_WNDFRAMEORVIEW_REG) 判断当然窗口类型有没有注册,实际是调用AfxDeferRegisterClass(fClass)

  AfxDeferRegisterClass(AFX_WNDFRAMEORVIEW_REG)--在afximpl.h中

  #define AfxDeferRegisterClass(fClass) AfxEndDeferRegisterClass(fClass) 是一个宏

 

  产生两个窗口:CMainFrame和子窗口CTestView

  CMainFrame--CFrameWnd--CWnd 凡是从CWnd派生出来的类都是窗口类

  子窗口CTestView--CView--CWnd 子窗口也是一个窗口类

 

  CMainFrame产生的窗口是框架窗口,其内部还可以有子窗口.

 

5)创建窗口 

 

CreateWindow Function

CreateWindowEx Function

 

  BOOL CWnd::CreateEx(DWORD dwExStyle,

LPCTSTR lpszClassName,

LPCTSTR lpszWindowName, DWORD dwStyle,

int x, int y, int nWidth, int nHeight,

HWND hWndParent, HMENU nIDorHMenu, LPVOID lpParam

)

在wincore.cpp中

 

BOOL CFrameWnd::Create(LPCTSTR lpszClassName,

LPCTSTR lpszWindowName,

DWORD dwStyle,

const RECT& rect,

CWnd* pParentWnd,

LPCTSTR lpszMenuName,

DWORD dwExStyle,

CCreateContext* pContext

)

在winfrm.cpp中

 

CWinApp在appcore.cpp中--全局对象theApp--子类构造函数调用CTestApp()--基类构造函数调用CWinApp()在appcore.cpp中

--_tWinMain()在appmodul.cpp中--AfxWinMain()中的pThread->InitInstance()在winmain.cpp中--调用CTestApp::InitInstance()在当前项目

--设计窗口AfxEndDeferRegisterClass()在wincore.cpp中--注册窗口AfxEndDeferRegisterClass()中的AfxRegisterClass()在wincore.cpp中

  --产生窗口之前调用子类CMainFrame::PreCreateWindow(CREATESTRUCT& cs)在MainFrm.cpp中--产生窗口之前调用基类CFrameWnd::PreCreateWindow(CREATESTRUCT& cs)在winfrm.cpp中

  --注册窗口AfxDeferRegisterClass(AFX_WNDFRAMEORVIEW_REG)在wincore.cpp中

  --创建窗口调用子类BOOL CFrameWnd::Create()在winfrm.cpp中--创建窗口调用基类BOOL CWnd::CreateEx()在wincore.cpp中(--循环产生窗口--)

 

  BOOL CWnd::CreateEx()在wincore.cpp中,调用PreCreateWindow(cs)和::AfxCtxCreateWindowEx(),为了在创建窗口之前,有机会修改窗口的外观样式.

 

  PreCreateWindow在afxwn.h中定义为:

  virtual BOOL PreCreateWindow(CREATESTRUCT& cs);

  所以这里调用的是子类的BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs),

 

  AfxCtxCreateWindowEx是宏:

  #define AfxCtxCreateWindowEx AfxCtxCreateWindowExW 在afxcomctl32.h中

  在afxcomctl32.h中,AFX_ISOLATIONAWARE_STATICLINK_FUNC(HWND ,CreateWindowExW,(DWORD dwExStyle,LPCWSTR lpClassName,LPCWSTR lpWindowName,DWORD dwStyle,int X,int Y,int nWidth,int nHeight,HWND hWndParent,HMENU hMenu,HINSTANCE hInstance,LPVOID lpParam),(dwExStyle,lpClassName,lpWindowName,dwStyle,X,Y,nWidth,nHeight,hWndParent,hMenu,hInstance,lpParam),NULL)

  CreateWindowEx也是宏:

#define CreateWindowEx  CreateWindowExW

 

  CREATESTRUCT与CreateWindowEx的定义:

typedef struct tagCREATESTRUCT { 

  LPVOID lpCreateParams; 

  HINSTANCE hInstance; 

  HMENU hMenu; 

  HWND hwndParent; 

  int cy; 

  int cx; 

  int y; 

  int x; 

  LONG style; 

  LPCTSTR lpszName; 

  LPCTSTR lpszClass; 

  DWORD dwExStyle; 

} CREATESTRUCT;

 

HWND CreateWindowEx(

  DWORD dwExStyle, 

  LPCTSTR lpClassName, 

  LPCTSTR lpWindowName, 

  DWORD dwStyle, 

  int x, 

  int y, 

  int nWidth, 

  int nHeight, 

  HWND hWndParent, 

  HMENU hMenu, 

  HINSTANCE hInstance, 

  LPVOID lpParam 

);

 

  CREATESTRUCT中成员变量与CreateWindowEx中的参数是一致的,不过顺序相反.

  利用CREATESTRUCT结构体主要为了产生窗口之前,有机会修改窗口外观.

 

6)显示窗口和更新窗口

在Test.cpp中的BOOL CTestApp::InitInstance()中.

当Test.cpp中ProcessShellCommand(cmdInfo)成功执行完后,表示窗口创建已经完成.

 

再通过:

m_pMainWnd->ShowWindow(SW_SHOW);

m_pMainWnd->UpdateWindow();

来完成窗口显示和窗口更新

m_pMainWnd是指向CMainFrm框架窗口对象的一个指针

 

 

7)消息循环

CWinThread::Run在THRDCORE.CPP中.

 

do while中的PumpMessage()--->CWinThread::PumpMessage()-->BOOL AFXAPI AfxInternalPumpMessage()再重复do while中的PumpMessage()

 

CWinApp在appcore.cpp中--全局对象theApp--子类构造函数调用CTestApp()--基类构造函数调用CWinApp()在appcore.cpp中

--_tWinMain()在appmodul.cpp中--AfxWinMain()中的pThread->InitInstance()在winmain.cpp中--调用CTestApp::InitInstance()在当前项目

--设计窗口AfxEndDeferRegisterClass()在wincore.cpp中--注册窗口AfxEndDeferRegisterClass()中的AfxRegisterClass()在wincore.cpp中

  --产生窗口之前调用子类CMainFrame::PreCreateWindow(CREATESTRUCT& cs)在MainFrm.cpp中--产生窗口之前调用基类CFrameWnd::PreCreateWindow(CREATESTRUCT& cs)在winfrm.cpp中

  --注册窗口AfxDeferRegisterClass(AFX_WNDFRAMEORVIEW_REG)在wincore.cpp中

  --创建窗口调用子类BOOL CFrameWnd::Create()在winfrm.cpp中--创建窗口调用基类BOOL CWnd::CreateEx()在wincore.cpp中(--循环产生窗口--)

  --显示窗口调用BOOL CTestApp::InitInstance()中的m_pMainWnd->ShowWindow(SW_SHOW)在Test.cpp(应用程序类)中;

  --更新窗口调用BOOL CTestApp::InitInstance()中的m_pMainWnd->UpdateWindow()在Test.cpp(应用程序类)中;

  --do while中的PumpMessage()--->CWinThread::PumpMessage()-->BOOL AFXAPI AfxInternalPumpMessage()(--再重复do while中的PumpMessage()--)

 

 

 

 

 

 

 

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值