孙鑫VC学习笔记:第三讲 MFC应用程序框架

MFC框架

--------------------------------------------------------------------------
CTestApp theApp;  //全局对象                                 //Breakpoint3
--------------------------------------------------------------------------

------------------------------------------------------------------------
CTestApp::CTestApp()
{   
                                                          //Breakpoint2
}

--------------------------APPMODUL.CPP文件中-------------------------
extern "C" int WINAPI
_tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
 LPTSTR lpCmdLine, int nCmdShow)
{                                                            //Breakpoint1
 // call shared/exported WinMain
 return AfxWinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow);
}
-------------------#define _tWinMain   WinMain---------------------
运行顺序: Breakpoint3->Breakpoint2->Breakpoint1


……


<1> 定义全局对象  CTestApp theApp;    (Breakpoint3)
<2> 构造全局对象  CTestApp::CTestApp()(Breakpoint2)
<3> 构造基类对象   即CWinThread
<4> 进入_tWinMain函数                 (Breakpoint1)
<5> 到达AfxWinMain函数(MFC全局函数)
     if (!pThread->InitInstance())     (Breakpoint4)
<6> 到达CTestApp::InitInstance()      (Breakpoint5)


And then^

  • 注册窗口类

  AfxEndDeferRegisterClass函数
  WINCORE.CPP中                       (注册窗口类应该在PreCreateWindow中调用)
  由于是单文档应用程序的原因,事先调用AfxEndDeferRegisterClass函数注册窗口

-------------------------------------------------------------------------------------
BOOL AFXAPI AfxEndDeferRegisterClass(LONG fToRegister)           (Breakpoint6)

  • 产生窗口
BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)        (Breakpoint7)
先是主框架窗口,然后是视图窗口
BOOL CFrameWnd::PreCreateWindow(CREATESTRUCT& cs)         (Breakpoint8)


调用Creat函数:

------------------WINFRM.CPP---------------------------------------------
BOOL CFrameWnd::Create(LPCTSTR lpszClassName,
 LPCTSTR lpszWindowName,
 DWORD dwStyle,
 const RECT& rect,
 CWnd* pParentWnd,
 LPCTSTR lpszMenuName,
 DWORD dwExStyle,
 CCreateContext* pContext)
{                                                                      
 ..........................
 if (!CreateEx(dwExStyle, lpszClassName, lpszWindowName, dwStyle,
  rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top,
  pParentWnd->GetSafeHwnd(), hMenu, (LPVOID)pContext)) //调用上面的
 {                                                            //CreateEx函数
  TRACE0("Warning: failed to create CFrameWnd./n");
  if (hMenu != NULL)
   DestroyMenu(hMenu);
  return FALSE;
 }
 ....................................................
}
-----------------------------------------------------------------------

  • 显示更新窗口
------------------------- Test.CPP-----------------------------------------
 m_pMainWnd->ShowWindow(SW_SHOW);
 m_pMainWnd->UpdateWindow();      //m_pMainWnd指向框架窗口对象的指针
---------------------------------------------------------------------------


  • 消息循环

 

-----------------------------THRDCORE.CPP------------------------------------------
int CWinThread::Run()
{
 ASSERT_VALID(this);

 // for tracking the idle time state
 BOOL bIdle = TRUE;
 LONG lIdleCount = 0;

 // acquire and dispatch messages until a WM_QUIT message is received.
 for (;;)
 {
  // phase1: check to see if we can do idle work
  while (bIdle &&
   !::PeekMessage(&m_msgCur, NULL, NULL, NULL, PM_NOREMOVE))
  {
   // call OnIdle while in bIdle state
   if (!OnIdle(lIdleCount++))
    bIdle = FALSE; // assume "no idle" state
  }

  // phase2: pump messages while available
  do
  {
   // pump message, but quit on WM_QUIT
   if (!PumpMessage())
    return ExitInstance();

   // reset "no idle" state after pumping "normal" message
   if (IsIdleMessage(&m_msgCur))
   {
    bIdle = TRUE;
    lIdleCount = 0;
   }

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

 ASSERT(FALSE);  // not reachable
}
------------------------------------------------------------------------------------
BOOL CWinThread::PumpMessage()
{
 ASSERT_VALID(this);

 if (!::GetMessage(&m_msgCur, NULL, NULL, NULL))
 {
#ifdef _DEBUG
  if (afxTraceFlags & traceAppMsg)
   TRACE0("CWinThread::PumpMessage - Received WM_QUIT./n");
  m_nDisablePumpCount++; // application must die
   // Note: prevents calling message loop things in 'ExitInstance'
   // will never be decremented
#endif
  return FALSE;
 }

#ifdef _DEBUG
 if (m_nDisablePumpCount != 0)
 {
  TRACE0("Error: CWinThread::PumpMessage called when not permitted./n");
  ASSERT(FALSE);
 }
#endif

#ifdef _DEBUG
 if (afxTraceFlags & traceAppMsg)
  _AfxTraceMsg(_T("PumpMessage"), &m_msgCur);
#endif

 // process this message

 if (m_msgCur.message != WM_KICKIDLE && !PreTranslateMessage(&m_msgCur))
 {
  ::TranslateMessage(&m_msgCur);
  ::DispatchMessage(&m_msgCur);
 }
 return TRUE;
}
----------------------------------------------------------------------------------

                   

  • 窗口过程 (在AfxEndDeferRegisterClass函数中设置)
wndcls.lpfnWndProc = DefWindowProc;   //缺省的窗口过程

At least:

在MFC如何整合CMainFrm类,CTestView类,CTestDoc类?

 BOOL CTestApp::InitInstance()中:

------------------------------------------------------------------------------------
CSingleDocTemplate* pDocTemplate;     //定义一个单文档的类模板
 pDocTemplate = new CSingleDocTemplate(
  IDR_MAINFRAME,
  RUNTIME_CLASS(CTestDoc),       //通过单文档的模板组合在一起
  RUNTIME_CLASS(CMainFrame),       // main SDI frame window
  RUNTIME_CLASS(CTestView));
 AddDocTemplate(pDocTemplate);           //增加到文档模板中
-------------------------------------------------------------------------------------



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值