c++_孙鑫mfc视频03_学习

转自:

http://blog.sina.com.cn/s/blog_8f708f490100vxh5.html

孙鑫VC++视频教程笔记-(3)MFC程序框架的剖析 附1-SDI程序流程图


1,寻找WinMain人口:

    在安装目录下找到MFC文件夹下的SRC文件夹,SRC下是MFC源代码。

    路径:MFC|SRC|APPMODUL.CPP

_tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,

 LPTSTR lpCmdLine, int nCmdShow)

{

 // call shared/exported WinMain

 return AfxWinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow);

}

注意:(#define _tWinMain   WinMain

2,对于全局对象或全局变量来说,在程序运行即WINMAIN函数加载的时候,已经为全局对象或全局变量分配了内存和赋初值。

所以:CTEApp theApp;->CTEApp ::CTEApp(){}->_tWinMain(){}

    说明:每一个MFC程序,有且只有一个从WinApp类派生的类(应用程序类),也只有一个从应用程序类所事例化的对象,表示应用程序本身

。在WIN32程序当中,表示应用程序是通过WINMAIN入口函数来表示的(通过一个应用程序的一个事例号这一个标识来表示的)。在基于MFC应用

程序中,是通过产生一个应用程序对象,用它来唯一的表示了应用程序。

3,通过构造应用程序对象过程中调用基类CWinApp的构造函数,在CWinApp的构造函数中对程序包括运行时一些初始化工作完成了。

CWinApp构造函数:MFC|SRC|APPCORE.CPP

CWinApp::CWinApp(LPCTSTR lpszAppName){...}//带参数,而CTEApp构造函数没有显式向父类传参,难道CWinApp()有默认参数?见下:

(在CWinApp类定义中, CWinApp(LPCTSTR lpszAppName NULL); 

注意:CWinApp()函数中:

pThreadState->m_pCurrentWinThread this;

pModuleState->m_pCurrentWinApp this

this指向的是派生类CTEApp对象,即theApp

调试:CWinApp::CWinApp();->CTEApp theApp;->CTEApp ::CTEApp()->CWinApp::CWinApp()->CTEApp ::CTEApp()->_tWinMain(){}

4,_tWinMain函数中通过调用AfxWinMain()函数来完成它要完成的功能。(Afx*前缀代表这是应用程序框架函数,是一些全局函数,应用程序

框架是一套辅助生成应用程序的框架模型,把一些类做一些有机的集成,我们可根据这些类函数来设计自己的应用程序)。

AfxWinMain()函数路径:MFC|SRC|WINMAIN.CPP

AfxWinMain()函数中:

CWinApp* pApp AfxGetApp();

说明:pApp存储的是指向WinApp派生类对象(theApp)的指针。

//_AFXWIN_INLINE CWinApp* AFXAPI AfxGetApp()

// return afxCurrentWinApp; }

调用pThread->InitInstance()

说明:pThread也指向theApp,由于基类中virtual BOOL InitApplication()定义为虚函数,所以调用pThread->InitInstance()时候,调用的是

派生类CTEAppInitInstance()函数。

nReturnCode pThread->Run();

说明:pThread->Run()完成了消息循环。

5,注册窗口类:AfxEndDeferRegisterClass();

    AfxEndDeferRegisterClass()函数所在文件:MFC|SRC|APPCORE.CPP

    BOOL AFXAPI AfxEndDeferRegisterClass(LONG fToRegister){...}

    说明:设计窗口类:在MFC中事先设计好了几种缺省的窗口类,根据不同的应用程序的选择,调用AfxEndDeferRegisterClass()函数注册所选择的窗口类。

    调试:

CWinApp::CWinApp();->CTEApp theApp;->CTEApp ::CTEApp()->CWinApp::CWinApp()->CTEApp ::CTEApp()->_tWinMain(){}//进入程序

->AfxWinMain();->pApp->InitApplication()->pThread->InitInstance()//父类InitInstance虚函数;

->CTEApp::InitInstance()//子类实现函数;

->AfxEndDeferRegisterClass(LONG fToRegister)//注册所选择的窗口类(出于文档管理,注册提前,正常的应在PreCreateWindow中进行注册

//之后进入创建窗口阶段(以下再不做调试)

6,PreCreateWindow()//主要是注册窗口类

BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)

{

 if( !CFrameWnd::PreCreateWindow(cs) )

  return FALSE;

 return TRUE;

}

说明:

CFrameWnd::PreCreateWindow()函数所在文件:MFC|SRC|WINFRM.CPP

BOOL CFrameWnd::PreCreateWindow(CREATESTRUCT& cs)

{

 if (cs.lpszClass == NULL)

 {

  VERIFY(AfxDeferRegisterClass(AFX_WNDFRAMEORVIEW_REG));

   //判断AFX_WNDFRAMEORVIEW_REG型号窗口类是否注册,如果没有注册则注册

  cs.lpszClass _afxWndFrameOrView;  // COLOR_WINDOW background

   //把注册后的窗口类名赋给cs.lpszClass

 }

 if ((cs.style FWS_ADDTOTITLE) && afxData.bWin4)

  cs.style |= FWS_PREFIXTITLE;

 if (afxData.bWin4)

  cs.dwExStyle |= WS_EX_CLIENTEDGE;

 return TRUE;

}

其中:

virtual BOOL PreCreateWindow(CREATESTRUCT& cs);//PreCreateWindow()是个虚函数,如果子类有则调用子类的。

#define VERIFY(f)          ASSERT(f)

#define AfxDeferRegisterClass(fClass) AfxEndDeferRegisterClass(fClass)

define AFX_WNDFRAMEORVIEW_REG          0x00008

const TCHAR _afxWndFrameOrView[] AFX_WNDFRAMEORVIEW;//WINCORE.CPP文件中,定义为全局数组。

//#define AFX_WNDFRAMEORVIEW  AFX_WNDCLASS("FrameOrView")

7,创建窗口:

Create()函数路径:MFC|SRC|WINFRM.CPP:

CFrameWnd::Create(...){

 ...

 CreateEx(...);//从父类继承来的,调用CWnd::CreateEx().

 ...

}

CWnd::CreateEx()函数路径:MFC|SRC|WINCORE.CPP

BOOL CWnd::CreateEx(...){

 ...

 if (!PreCreateWindow(cs))//虚函数,如果子类有调用子类的。

 {

  PostNcDestroy();

  return FALSE;

 }

 ...

 HWND hWnd ::CreateWindowEx(cs.dwExStyle, cs.lpszClass,

  cs.lpszName, cs.style, cs.x, cs.y, cs.cx, cs.cy,

  cs.hwndParent, cs.hMenu, cs.hInstance, cs.lpCreateParams);

 ...

}

说明:CreateWindowEx()函数与CREATESTRUCT结构体参数的对应关系,使我们在创建窗口之前通过可PreCreateWindow(cs)修改cs结构体成员来

修改所要的窗口外观。PreCreateWindow(cs))//是虚函数,如果子类有调用子类的。

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        

);

typedef struct tagCREATESTRUCT // cs 

    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; 

8,显示和更新窗口:

CTEApp类,TEApp.cpp

m_pMainWnd->ShowWindow(SW_SHOW);//显示窗口,m_pMainWnd指向框架窗口

m_pMainWnd->UpdateWindow();//更新窗口

说明:

class CTEApp public CWinApp{...}

class CWinApp public CWinThread{...}

class CWinThread public CCmdTarget

...

public:

 CWnd* m_pMainWnd;

 ...}

9,消息循环:

int AFXAPI AfxWinMain()

...

 // Perform specific initializations

 if (!pThread->InitInstance()){...}

 //完成窗口初始化工作,完成窗口的注册,完成窗口的创建,显示和更新。

 nReturnCode pThread->Run();

 //继承基类Run()方法,调用CWinThread::Run()来完成消息循环 ...

}

CWinThread::Run()方法路径:MFC|SRC|THRDCORE.CPP

int CWinThread::Run()

...

  // phase2: pump messages while available

  do//消息循环

  {

   // pump message, but quit on WM_QUIT

   if (!PumpMessage())//取消息并处理

    return ExitInstance(); ...

  while (::PeekMessage(&m_msgCur, NULL, NULL, NULL, PM_NOREMOVE));

 ...

}

说明:

BOOL PeekMessage(,,,,)函数说明

The PeekMessage function checks thread message queue for message and places the message (if any) in the specified 

structure.

If message is available, the return value is nonzero.

If no messages are available, the return value is zero. 

/

BOOL CWinThread::PumpMessage()

...

 if (!::GetMessage(&m_msgCur, NULL, NULL, NULL))//取消息

 {...} ...

 // process this message

 if (m_msgCur.message != WM_KICKIDLE && !PreTranslateMessage(&m_msgCur))

 {

  ::TranslateMessage(&m_msgCur);//进行消息(如键盘消息)转换

  ::DispatchMessage(&m_msgCur);//分派消息到窗口的回调函数处理(实际上分派的消息经过消息映射,交由消息响应函数进行处理。)

 }

 return TRUE;

}

10,文档与视结构:

可以认为View类窗口是CMainFram类窗口的子窗口。

DOCument类是文档类。

DOC-VIEW结构将数据本身与它的显示分离开。

文档类:数据的存储,加载

视类:数据的显示,修改

11,文档类,视类,框架类的有机结合:

CTEAppCTEApp::InitInstance()函数中通过文档模板将文档类,视类,框架类的有机组织一起。...

CSingleDocTemplate* pDocTemplate;

pDocTemplate new CSingleDocTemplate(

 IDR_MAINFRAME,

 RUNTIME_CLASS(CTEDoc),

 RUNTIME_CLASS(CMainFrame),       // main SDI frame window

 RUNTIME_CLASS(CTEView));

AddDocTemplate(pDocTemplate);//增加到模板...

----------------------------------------------------------------------------->

//AfxWinMain()函数在WINMAIN.CPP文件中,它主要调用以下函数

AfxWinInit();

pApp->InitApplication();    //内部初始化管理

pThread->InitInstance();    //调用子类中的InitInstance()

CTestApp::InitInstance();

┣━ProcessShellCommand(cmdInfo);        //对命令行进行解释

┃        CTestDoc::CTestDoc();        //构造文档类对象

┃        CMainFrame::CMainFrame();    //构造框架窗口对象

┃            CFrameWnd::LoadFrame();    //WINFRM.CPP

┃            ┣━AfxEndDeferRegisterClass();    //WINCORE.CPP,注册窗口类

┃            ┃        AfxRegisterClass();    //WINCORE.CPP

┃            ┣━CMainFrame::PreCreateWindow();

┃            ┃        CFrameWnd::PreCreateWindow();

┃            ┃            AfxEndDeferRegisterClass();

┃            ┣━AfxRegisterClass();

┃            ┗━CFrameWnd::Create();        //创建CMainFrame窗口

┃                    CWnd::CreateEx();

┃                        CMainFrame::PreCreateWindow();

┃                            CFrameWnd::PreCreateWindow();

┃                        CTestView::CTestView();    //构造CTestView对象

┃                        CWnd::CreateEx();        //创建CTestView窗口

┃                            AfxEndDeferRegisterClass();

┃                        AfxEndDeferRegisterClass();

┃                        CWnd::CreateEx();        //创建CToolBar工具栏

┃                        AfxEndDeferRegisterClass();

┃                        CWnd::CreateEx();        //创建CStatusBar状态栏

┃                        AfxEndDeferRegisterClass();

┃                            AfxRegisterClass();

┃                        CWnd::CreateEx();        //创建CDockBar

┃                        AfxEndDeferRegisterClass();

┃                        CWnd::CreateEx();        //创建CDockBar

┃                        AfxEndDeferRegisterClass();

┃                        CWnd::CreateEx();        //创建CDockBar

┃                        AfxEndDeferRegisterClass();

┃                        CWnd::CreateEx();        //创建CDockBar

┣━m_pMainWnd->ShowWindow(SW_SHOW);    //显示窗口

┗━m_pMainWnd->UpdateWindow();        //更新窗口

nReturnCode pThread->Run();    //进入消息循环

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值