一个“什么都不作的MFC程序”的启动过程分析如下:
1。声明全局变量theApp此实例名是规定的,但类是用户写的。继承自WinApp
2。执行用户类的构造函数,构造函数里。
SetRegistryKey(_T("Local AppWizard-Generated Applications"));  //什么意思,做什么的?LoadStdProfileSettings();//这个读取的是配置么?配置在哪
// Load standard INI file options (including MRU) 这个不明白
CSingleDocTemplate* pDocTemplate;//生成默认模板,按照单文档模板生成//使用构造函数,按构造函数的参数,传递:菜单,文档类,框架类,主视图类
pDocTemplate = new CSingleDocTemplate(
IDR_MAINFRAME,//菜单
RUNTIME_CLASS(CTestEnumDoc),//文档类,如果多个怎么办?
RUNTIME_CLASS(CMainFrame),       // main SDI frame window
RUNTIME_CLASS(CTestEnumView));//视图类,多个视图类呢?
                  //用的时候再看具体的调用和生成的生存期是么?AddDocTemplate(pDocTemplate);//不懂,是个虚函数,我只管找也没找到函数体,可能应藏在Target类里了。反正看不到。这句什么意思?什么作用?//运行参数
CCommandLineInfo cmdInfo;
ParseCommandLine(cmdInfo);
if (!ProcessShellCommand(cmdInfo)) return FALSE;  //不许不要参数,没参数就退出?m_pMainWnd->ShowWindow(SW_SHOW);//显示模式,最小化,最大化,隐藏……
m_pMainWnd->UpdateWindow();//更新显示return TRUE;//结束构造函数,进入连接的WinMain
之后,应该是被隐藏了的WinMain执行,这里执行似乎就到了我看书的尽头。因为WinMain里包含了消息循环,那么之后呢?程序运行到哪里去了?执行什么了?(似乎是个愚蠢的问题)
//自我理解:进入消息循环后,就不用逐句的按过程化的思路去读程序了。是看可能。比如,被遮挡,就会系统给我们的程序发送“无效”的函数,使程序需要执行OnDraw(),如果单击…… 等所有的执行顺序就不一定了。就看收到消息的顺序了。只要对可能的消息写好响应和相关代码了。
各位给我解答一下我上面没有理解的,和我理解对不对?感谢帮助我的高手和关心我学习的你。

解决方案 »

  1.   

    SetRegistryKey 写注册表的 程序初始化时候用到 比如你把窗体移动到左下角关掉 你下次打开的时候还想程序出现在那里就必须用这个 不过这个函数只是刚开始 后面还要写很多),//文档类,如果多个怎么办? 
    好象有且只有一个Doc的派生类与框架类关联吧));//视图类,多个视图类呢?
    如果是多视图 用RUNTIME_CLASS(CChildFrame)改框架类型 CTestEnumView不变//用的时候再看具体的调用和生成的生存期是么?
    不懂 RUNTIME_CLASS作用是类的类型识别AddDocTemplate 不是虚函数 既然新建一个文档摸板 当然还加入啊 用侯老大一句话就是 把他们粘在一起
      

  2.   

    哎 敲累了 
    消息循环在CWinThread 被遮挡
    程序发送“无效”的函数
    是产生无效区域用Invalidate函数产生WM_PAINT消息 进行重画 响应函数是OnPaint 不是OnDraw()
    OnDraw()是文档类用的消息的传递顺序是从派生类到基类 一个WM_COMMAND消息是先从视图类->文档->框架类最后到那儿了??我也不大清楚 哈哈 应该是CWinThread 中去了吧 我不是高手也是初学 大家交流交流 不知道那地方有没有说错 那位高手帮忙看看
      

  3.   

    最早还是从_tWinMain开始的,_tWinMain调用AfxWinMain,int AFXAPI AfxWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
    LPTSTR lpCmdLine, int nCmdShow)
    {
    ASSERT(hPrevInstance == NULL); int nReturnCode = -1;
    CWinThread* pThread = AfxGetThread();
    CWinApp* pApp = AfxGetApp(); // 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())
    {
    if (pThread->m_pMainWnd != NULL)
    {
    TRACE0("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)
    {
    TRACE1("Warning: Temp map lock count non-zero (%ld).\n",
    AfxGetModuleThreadState()->m_nTempMapLock);
    }
    AfxLockTempMaps();
    AfxUnlockTempMaps(-1);
    #endif AfxWinTerm();
    return nReturnCode;
    }很简单吧,这就是为什么要把启动代码放在CWinApp::InitInstance中的原因了
      

  4.   

    “之后,应该是被隐藏了的WinMain执行”错!
    源码:
    APPMODUL.CPP Ln24:
    extern "C" int WINAPI
    _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
    LPTSTR lpCmdLine, int nCmdShow)
    {
    // call shared/exported WinMain
    return AfxWinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow);
    }WINMAIN.CPP Ln21:
    int AFXAPI AfxWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
    LPTSTR lpCmdLine, int nCmdShow)
    {
    ...
    CWinApp* pApp = AfxGetApp(); // 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()) //<---这就是你看的那个函数
    {
    ...
    nReturnCode = pThread->ExitInstance();
    goto InitFailure;
    }
    nReturnCode = pThread->Run();InitFailure:
    ...
    AfxWinTerm();
    return nReturnCode;
    }
    建议你去仔细看jjHou的《深入浅出MFC》