【MFC 程序框架】MFC程序框架/VC 程序运行框架/VC运行顺序 从哪运行

1:程序的“导火索”---theApp
CmyApp theApp;
在声明对象的同时,调用其构造函数。按C++的语法,首先要调用其基类Cwinapp的构造函数. 这个文件主要用于应用程序的一些初始化操作。
class CWinApp : public CWinThread
{
    DECLARE_DYNAMIC(CWinApp)
public:
// Constructor
    CWinApp(LPCTSTR lpszAppName = NULL); 
…………
}
CWinApp::CWinApp(LPCTSTR lpszAppName)
{
    if (lpszAppName != NULL)
       m_pszAppName = _tcsdup(lpszAppName);
    else
       m_pszAppName = NULL;
    // initialize CWinThread state
    AFX_MODULE_STATE* pModuleState = _AFX_CMDTARGET_GETSTATE();
    AFX_MODULE_THREAD_STATE* pThreadState = pModuleState->m_thread;
    ASSERT(AfxGetThread() == NULL);
    pThreadState->m_pCurrentWinThread = this;
    ASSERT(AfxGetThread() == this);
    m_hThread = ::GetCurrentThread();
    m_nThreadID = ::GetCurrentThreadId();
    // initialize CWinApp state
    ASSERT(afxCurrentWinApp == NULL); // only one CWinApp object please
    pModuleState->m_pCurrentWinApp = this;
    ASSERT(AfxGetApp() == this);
    // in non-running state until WinMain
    m_hInstance = NULL;
    m_hLangResourceDLL = NULL;
    m_pszHelpFilePath = NULL;
    m_pszProfileName = NULL;
    m_pszRegistryKey = NULL;
    m_pszExeName = NULL;
    m_pRecentFileList = NULL;
    m_pDocManager = NULL;
    m_atomApp = m_atomSystemTopic = NULL;
    m_lpCmdLine = NULL;
    m_pCmdInfo = NULL;
    // initialize wait cursor state
    m_nWaitCursorCount = 0;
    m_hcurWaitCursorRestore = NULL;
    // initialize current printer state
    m_hDevMode = NULL;
    m_hDevNames = NULL;
    m_nNumPreviewPages = 0;     // not specified (defaults to 1)
    // initialize DAO state
    m_lpfnDaoTerm = NULL;   // will be set if AfxDaoInit called
    // other initialization
    m_bHelpMode = FALSE;
    m_eHelpType = afxWinHelp;
    m_nSafetyPoolSize = 512;        // default size
}
2:theApp之后的隐藏代码,由他控制整个程序的流程。
_tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
    LPTSTR lpCmdLine, int nCmdShow)
{
    // call shared/exported WinMain
    return AfxWinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow);
}
其中有宏定义:#define _tWinMain   wWinMain
int AFXAPI AfxWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
    LPTSTR lpCmdLine, int nCmdShow)
{
    ASSERT(hPrevInstance == NULL);
    int nReturnCode = -1;
    CWinThread* pThread = AfxGetThread();;// CWinApp是从CWinThread派生的,
    CWinApp* pApp = AfxGetApp();  //实质上就是pThread==pApp
    // AFX internal initialization
    if (!AfxWinInit(hInstance, hPrevInstance, lpCmdLine, nCmdShow))  //用于初始化
       goto InitFailure;
    // App global initializations (rare)
    if (pApp != NULL && !pApp->InitApplication())   //用于初始化
       goto InitFailure;
    // Perform specific initializations
    if (!pThread->InitInstance())   //注意多态性  virtual BOOL InitInstance();
                                   //又因为pThread==pApp,所以调用pApp->InitInstance()
    {
       if (pThread->m_pMainWnd != NULL)
       {
           TRACE(traceAppMsg, 0, "Warning: Destroying non-NULL m_pMainWnd/n");
           pThread->m_pMainWnd->DestroyWindow();
       }
       nReturnCode = pThread->ExitInstance();
       goto InitFailure;
    }
    nReturnCode = pThread->Run();  //控制消息循环
InitFailure:
#ifdef _DEBUG
    // Check for missing AfxLockTempMap calls
    if (AfxGetModuleThreadState()->m_nTempMapLock != 0)
    {
       TRACE(traceAppMsg, 0, "Warning: Temp map lock count non-zero (%ld)./n",
           AfxGetModuleThreadState()->m_nTempMapLock);
    }
    AfxLockTempMaps();
    AfxUnlockTempMaps(-1);
#endif
    AfxWinTerm();
    return nReturnCode;
}
由上面的程序可以看到几个很重要的函数
(1)AfxWinInit(hInstance, hPrevInstance, lpCmdLine, nCmdShow))
       goto InitFailure;
 (2) pApp->InitApplication())
 (3) pThread->InitInstance()
 (4) pThread->Run()
其中1,2 也是完成程序的一些初始化工作,4 主要是为了处理消息,3呢,很关键,我们运行时看到的窗口就是从这里产生。下面一一介绍
3:程序自动产生的InitInstance()函数
以下是自动生成的InitInstance()源程序:
BOOL CmyApp::InitInstance()
    {
    // 如果一个运行在 Windows XP 上的应用程序清单指定要
    // 使用 ComCtl32.dll 版本 6 或更高版本来启用可视化方式,
    //则需要 InitCommonControls()。否则,将无法创建窗口。
    InitCommonControls();
    CWinApp::InitInstance();
    // 初始化 OLE 库
    if (!AfxOleInit())
    {
       AfxMessageBox(IDP_OLE_INIT_FAILED);
       return FALSE;
    }
    AfxEnableControlContainer();
    // 标准初始化
    // 如果未使用这些功能并希望减小
    // 最终可执行文件的大小,则应移除下列
    // 不需要的特定初始化例程
    // 更改用于存储设置的注册表项
    // TODO: 应适当修改该字符串,
    // 例如修改为公司或组织名
    SetRegistryKey(_T("应用程序向导生成的本地应用程序"));
    LoadStdProfileSettings(4);  // 加载标准 INI 文件选项(包括 MRU)
    // 注册应用程序的文档模板。文档模板
    // 将用作文档、框架窗口和视图之间的连接
    CMultiDocTemplate* pDocTemplate;
    pDocTemplate = new CMultiDocTemplate(IDR_myTYPE,
       RUNTIME_CLASS(CmyDoc),
       RUNTIME_CLASS(CChildFrame), // 自定义 MDI 子框架
       RUNTIME_CLASS(CmyView));
    if (!pDocTemplate)
       return FALSE;
    AddDocTemplate(pDocTemplate);
    // 创建主 MDI 框架窗口
    CMainFrame* pMainFrame = new CMainFrame;
    if (!pMainFrame || !pMainFrame->LoadFrame(IDR_MAINFRAME))
       return FALSE;
    m_pMainWnd = pMainFrame;
    // 仅当具有后缀时才调用 DragAcceptFiles
    //  在 MDI 应用程序中,这应在设置 m_pMainWnd 之后立即发生
    // 分析标准外壳命令、DDE、打开文件操作的命令行
    CCommandLineInfo cmdInfo;
    ParseCommandLine(cmdInfo);
    // 调度在命令行中指定的命令。如果
    // 用 /RegServer、/Register、/Unregserver 或 /Unregister 启动应用程序,则返回FALSE。
    if (!ProcessShellCommand(cmdInfo))   //引发窗口注册
       return FALSE;
    // 主窗口已初始化,因此显示它并对其进行更新
    pMainFrame->ShowWindow(m_nCmdShow);
    pMainFrame->UpdateWindow();
    return TRUE;
}
其中,注册窗口用到了一下函数,比较长,如下:
BOOL AFXAPI AfxEndDeferRegisterClass(LONG fToRegister)
{
    // mask off all classes that are already registered
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值