C++博客 联系 聚合 管理  

Blog Stats

文章分类(17)

收藏夹(2)

文章档案(18)

相册

Blogs

citywanderer

使用MFC向导,生成一个对话框的应用程序。通过调试、设置断点的方式解析MFC程序。下面只是给出主要的源代码以及它们所在文件的名字。
  1/*
  2    Noun Explain: 
  3    1、CRT: C run-time
  4    you can refer to C运行库到底是什么东西?它和操作系统有没有关系?
  5    http://tech.cixiong.com/t/200406/17/0229562.html
  6*/

  7//在此之前调用了__DllMainCRTStartup, VC\crt\src\crtdll.c 464, 还有一个重要的crtlib.c文件
  8//you can refer to MFC技术内幕系列http://www.mx68.com/WebDeveloper/2006-03-10/WebDeveloper_26756.shtml
  9/*
 10    seq1 VC\crt\src\crtexe.c , main function
 11*/

 12/***
 13*mainCRTStartup(void)
 14*wmainCRTStartup(void)
 15*WinMainCRTStartup(void)
 16*wWinMainCRTStartup(void)
 17*
 18*Purpose:
 19*       These routines do the C runtime initialization, call the appropriate
 20*       user entry function, and handle termination cleanup.  For a managed
 21*       app, they then return the exit code back to the calling routine, which
 22*       is the managed startup code.  For an unmanaged app, they call exit and
 23*       never return.
 24*
 25*       Function:               User entry called:
 26*       mainCRTStartup          main
 27*       wmainCRTStartup         wmain
 28*       WinMainCRTStartup       WinMain
 29*       wWinMainCRTStartup      wWinMain
 30*
 31*Entry:
 32*
 33*Exit:
 34*       Managed app: return value from main() et al, or the exception code if
 35*                 execution was terminated by the __except guarding the call
 36*                 to main().
 37*       Unmanaged app: never return.
 38*
 39*******************************************************************************/

 40int WinMainCRTStartup(void)
 41{
 42    return __tmainCRTStartup();
 43}

 44
 45/*
 46    seq2 
 47*/

 48int __tmainCRTStartup(void)
 49{
 50    STARTUPINFO StartupInfo;
 51    /*
 52    The API GetStartupInfo function retrieves the contents of the STARTUPINFO structure that was specified 
 53    when the calling process was created.
 54
 55    The STARTUPINFO structure is used with the CreateProcess, CreateProcessAsUser, and 
 56    CreateProcessWithLogonW functions to specify the window station, desktop, standard handles, and 
 57    appearance of the main window for the new process.
 58
 59    Before run GetStartupInfo(), it must call CreateProcess. but i don't know how make break point 
 60    and in witch file make break point.
 61    在这之前应该调用了CreateProcess函数,因为运行GetStartupInfo之后,StartupInfo结构被填充了:包括进程的路径、
 62    名称……
 63    */

 64    GetStartupInfo( &StartupInfo );
 65
 66    /*
 67    * do C++ constructors (initializers) specific to this EXE
 68    */

 69    if (__native_startup_state == __initializing)
 70    {
 71        /*    
 72         * pointers to initialization sections
 73        extern _CRTALLOC(".CRT$XIA") _PIFV __xi_a[];
 74        extern _CRTALLOC(".CRT$XIZ") _PIFV __xi_z[];    // C initializers 
 75        extern _CRTALLOC(".CRT$XCA") _PVFV __xc_a[];
 76        extern _CRTALLOC(".CRT$XCZ") _PVFV __xc_z[];    // C++ initializers 
 77        extern _CRTALLOC(".CRT$XPA") _PVFV __xp_a[];
 78        extern _CRTALLOC(".CRT$XPZ") _PVFV __xp_z[];   // C pre-terminators 
 79        extern _CRTALLOC(".CRT$XTA") _PVFV __xt_a[];
 80        extern _CRTALLOC(".CRT$XTZ") _PVFV __xt_z[];    // C terminators 
 81        */

 82        _initterm( __xc_a, __xc_z );//please see seq3
 83    }

 84     /*
 85     * Skip past program name (first token in command line).
 86     * Check for and handle quoted program name.
 87     */

 88    #ifdef WPRFLAG
 89                /* OS may not support "W" flavors */
 90                if (_wcmdln == NULL)
 91                    return 255;
 92                lpszCommandLine = (wchar_t *)_wcmdln;
 93    #else  /* WPRFLAG */
 94    //can get the application's complete name:
 95    //lpszCommandLine    0x00020724 ""e:\……\debug\CapturePacket.exe
 96    //_acmdln's definition is in C:\Program Files\Microsoft Visual Studio 8\VC\crt\src\crtlib.c, it is initialized
 97    //by _acmdln = (char *)GetCommandLineA() in function __CRTDLL_INIT Line317
 98    //GetCommandLineA在winbase.h、Kernel32.lib中定义的SDKapi
 99                lpszCommandLine = (unsigned char *)_acmdln;
100    #endif  /* WPRFLAG */
101
102    mainret = WinMain(
103                       (HINSTANCE)&__ImageBase,
104                       NULL,
105                       lpszCommandLine,
106                       StartupInfo.dwFlags & STARTF_USESHOWWINDOW
107                        ? StartupInfo.wShowWindow
108                        : SW_SHOWDEFAULT
109                      );//see seq4
110}

111
112/*
113    seq3
114    VC\crt\src\crt0dat.c , main function
115    you can refer to 静态对象、全局对象与程序的运行机制 http://dev.csdn.net/Develop/article/28/61880.shtm
116
117    在函数指针表中不断循环找到所有函数的入口(内存地址)(在WinMainCRTStartup启动函数之前就把所有的函数入口
118    地址保存了?这项工作是在创建Process的时候做的?)
119*/

120/***
121* static void _initterm(_PVFV * pfbegin, _PVFV * pfend) - call entries in
122*       function pointer table
123*
124*Purpose:
125*       Walk a table of function pointers, calling each entry, as follows:
126*
127*           1. walk from beginning to end, pfunctbl is assumed to point
128*              to the beginning of the table, which is currently a null entry,
129*              as is the end entry.
130*           2. skip NULL entries
131*           3. stop walking when the end of the table is encountered
132*
133*Entry:
134*       _PVFV *pfbegin  - pointer to the beginning of the table (first
135*                         valid entry).
136*       _PVFV *pfend    - pointer to the end of the table (after last
137*                         valid entry).
138*
139*Exit:
140*       No return value
141*
142*Notes:
143*       This routine must be exported in the CRT DLL model so that the client
144*       EXE and client DLL(s) can call it to initialize their C++ constructors.
145*
146*Exceptions:
147*       If either pfbegin or pfend is NULL, or invalid, all bets are off!
148*
149*******************************************************************************/

150
151void __cdecl _initterm (_PVFV * pfbegin, _PVFV * pfend)
152{
153    /*
154    在此设置断点,可以看到pfbegin、pfend的类型为void(void)**(空函数指针的指针?0x0041d000-0x0041d41c),循环指向函数入口地址。
155    Call Stack中可以看到msvcr80d.dll(和kernel32.dll)
156    */

157     /*
158     * walk the table of function pointers from the bottom up, until
159     * the end is encountered.  Do not skip the first entry.  The initial
160     * value of pfbegin points to the first valid entry.  Do not try to
161     * execute what pfend points to.  Only entries before pfend are valid.
162     */

163    while ( pfbegin < pfend )
164    {
165        /*
166         * if current table entry is non-NULL, call thru it.
167         */

168        if ( *pfbegin != NULL )
169        /*
170            第1次、在0x0041d104 pcppinit
171                0x00414340 pre_cpp_init(void)进入
172            第2次、在0x0041d208 _afxInitAppState$initializer$
173                0x00419fe0 'dynamic initializer for '_afxInitAppState"(void)进入
174            第3次、在0x0041d30c theApp$initializer$ 对象的定义(构造函数)
175                0x00419fe0 'dynamic initializer for 'theApp"(void)进入
176            第4次、在0x0041d310 clash$initializer$
177                0x00419f20 Inconsistent_definition_of_symbol__ATL_MIXED::`dynamic initializer for 'clash''(void)进入
178            第5次、在0x0041d314 clash$initializer$
179                0x00419f60 Define_the_symbol__ATL_MIXED::`dynamic initializer for 'clash''(void)进入
180        */

181            (**pfbegin)();//指针的指针
182        ++pfbegin;
183    }

184}

185
186/***
187    seq3.1
188*pre_cpp_init(void) crtexe.c Line295
189*
190*Purpose:
191*       The code in mainCRTStartup that was executed after C initializers and
192*       before C++ initializers is shifted in this function. Also this funciton
193*       is the first thing that is executed in C++ init section.
194*
195*Entry:
196*
197*Exit:
198*
199*******************************************************************************/

200
201static void __cdecl pre_cpp_init(void)
202{
203#ifdef _RTC
204    atexit(_RTC_Terminate);
205#endif  /* _RTC */
206
207    /*
208     * Get the arguments for the call to main. Note this must be
209     * done explicitly, rather than as part of the dll's
210     * initialization, to implement optional expansion of wild
211     * card chars in filename args
212     */

213
214    startinfo.newmode = _newmode;
215
216
217#ifdef WPRFLAG
218    argret = __wgetmainargs(&argc, &argv, &envp,
219                            _dowildcard, &startinfo);
220#else  /* WPRFLAG */
221    argret = __getmainargs(&argc, &argv, &envp,
222                           _dowildcard, &startinfo);
223#endif  /* WPRFLAG */
224
225#ifndef _SYSCRT
226    if (argret < 0)
227        _amsg_exit(_RT_SPACEARG);
228#endif  /* _SYSCRT */
229}

230/*
231    seq3.2
232    \Microsoft Visual Studio 8\VC\atlmfc\src\mfc\appmodul.cpp Line70
233*/

234char _afxInitAppState = (char)(AfxInitialize(FALSE, _MFC_VER));
235
236/////////////////////////////////////////////////////////////////////////////
237//seq3.2.1
238// initialize app state such that it points to this module's core state
239//\Microsoft Visual Studio 8\VC\atlmfc\src\mfc\appmodul.cpp Line31
240
241BOOL AFXAPI AfxInitialize(BOOL bDLL, DWORD dwVersion)
242{
243    //AfxGetModuleState:c:\program files\microsoft visual studio 8\vc\atlmfc\include\afxstat_.h Line206
244    /*
245    CWinApp* m_pCurrentWinApp;              //0x00000000
246    HINSTANCE m_hCurrentInstanceHandle;        //0x00000000
247    HINSTANCE m_hCurrentResourceHandle;        //0x00000000
248    LPCTSTR m_lpszCurrentAppName;            //0x00000000
249    BYTE m_bDLL;    // TRUE if module is a DLL, FALSE if it is an EXE  //1
250    BYTE m_bSystem; // TRUE if module is a "system" module, FALSE if not  //0
251    BYTE m_bReserved[2]; // padding
252
253    DWORD m_fRegisteredClasses; // flags for registered window classes
254    ……
255    */

256    AFX_MODULE_STATE* pModuleState = AfxGetModuleState();
257    pModuleState->m_bDLL = (BYTE)bDLL;
258    ASSERT(dwVersion <= _MFC_VER);
259    UNUSED(dwVersion);  // not used in release build
260#ifdef _AFXDLL
261    pModuleState->m_dwVersion = dwVersion;
262#endif
263#ifdef _MBCS
264    // set correct multi-byte code-page for Win32 apps
265    if (!bDLL)
266        _setmbcp(_MB_CP_ANSI);
267#endif //_MBCS
268    return TRUE;
269}

270
271/*
272    seq3.3.1
273    My dialog class:CCapturePacketApp
274*/

275CCapturePacketApp theApp;
276/*
277    seq3.3.1.5
278    先调用父类CWinApp的constructor
279*/

280CCapturePacketApp::CCapturePacketApp()
281{
282}

283/*
284    seq3.3.1.4
285    C:\Program Files\Microsoft Visual Studio 8\VC\atlmfc\src\mfc\appcore.cpp Line401
286    先调用父类CWinThread的constructor
287    函数中的变量如m_pszAppName、m_hThread、m_nThreadID、m_hInstance……都在
288    c:\program files\microsoft visual studio 8\vc\atlmfc\include\afxwin.h中定义
289*/

290CWinApp::CWinApp(LPCTSTR lpszAppName)
291{
292    if (lpszAppName != NULL)
293        m_pszAppName = _tcsdup(lpszAppName);
294    else
295        m_pszAppName = NULL;
296
297    // initialize CWinThread state
298    AFX_MODULE_STATE* pModuleState = _AFX_CMDTARGET_GETSTATE();
299    ENSURE(pModuleState);
300    AFX_MODULE_THREAD_STATE* pThreadState = pModuleState->m_thread;
301    ENSURE(pThreadState);
302    ASSERT(AfxGetThread() == NULL);
303    pThreadState->m_pCurrentWinThread = this;
304    ASSERT(AfxGetThread() == this);
305    //Platform SDK Kernel32.dll
306    //The GetCurrentThread function retrieves a pseudo handle for the current thread.
307    m_hThread = ::GetCurrentThread();
308    m_nThreadID = ::GetCurrentThreadId();
309
310    // initialize CWinApp state
311    ASSERT(afxCurrentWinApp == NULL); // only one CWinApp object please
312    //its value:0x00421340 class CCapturePacketApp theApp {CWinApp <Bad Ptr>}
313    pModuleState->m_pCurrentWinApp = this;
314    ASSERT(AfxGetApp() == this);
315
316    // in non-running state until WinMain
317    m_hInstance = NULL;
318    m_hLangResourceDLL = NULL;
319    m_pszHelpFilePath = NULL;
320    m_pszProfileName = NULL;
321    m_pszRegistryKey = NULL;
322    m_pszExeName = NULL;
323    m_pRecentFileList = NULL;
324    m_pDocManager = NULL;
325    m_atomApp = m_atomSystemTopic = NULL;
326    m_lpCmdLine = NULL;
327    m_pCmdInfo = NULL;
328
329    // initialize wait cursor state
330    m_nWaitCursorCount = 0;
331    m_hcurWaitCursorRestore = NULL;
332
333    // initialize current printer state
334    m_hDevMode = NULL;
335    m_hDevNames = NULL;
336    m_nNumPreviewPages = 0;     // not specified (defaults to 1)
337
338    // initialize DAO state
339    m_lpfnDaoTerm = NULL;   // will be set if AfxDaoInit called
340
341    // other initialization
342    m_bHelpMode = FALSE;
343    m_eHelpType = afxWinHelp;
344    m_nSafetyPoolSize = 512;        // default size
345}

346/*
347    seq3.3.1.3
348    C:\Program Files\Microsoft Visual Studio 8\VC\atlmfc\src\mfc\thrdcore.cpp Line474
349    先调用父类CCmdTarget的constructor
350*/

351CWinThread::CWinThread()
352{
353    m_pThreadParams = NULL;
354    m_pfnThreadProc = NULL;
355
356    CommonConstruct();
357}

358
359/*
360    seq3.3.1..2
361    C:\Program Files\Microsoft Visual Studio 8\VC\atlmfc\src\mfc\cmdtarg.cpp Line21
362    先调用父类CObject的constructor
363    函数中的变量如m_pModuleState、m_dwRef等都在c:\program files\microsoft visual studio 8\vc\atlmfc\include\afxwin.h
364    中定义
365*/

366CCmdTarget::CCmdTarget()
367{
368    // capture module state where object was constructed
369    /*
370        value:0x001544a0
371    CWinApp* m_pCurrentWinApp;              //0x00000000
372    HINSTANCE m_hCurrentInstanceHandle;        //0x00000000
373    HINSTANCE m_hCurrentResourceHandle;        //0x00000000
374    LPCTSTR m_lpszCurrentAppName;            //0x00000000
375    BYTE m_bDLL;    // TRUE if module is a DLL, FALSE if it is an EXE  //0
376    BYTE m_bSystem; // TRUE if module is a "system" module, FALSE if not  //0
377    BYTE m_bReserved[2]; // padding
378
379    DWORD m_fRegisteredClasses; // flags for registered window classes //0
380    ……
381    */

382    m_pModuleState = AfxGetModuleState();
383    ASSERT(m_pModuleState != NULL);
384
385    // initialize state
386#ifndef _AFX_NO_OLE_SUPPORT
387    m_dwRef = 1;
388    m_pOuterUnknown = NULL;
389    m_xInnerUnknown = 0;
390    m_xDispatch.m_vtbl = 0;
391    m_bResultExpected = TRUE;
392    m_xConnPtContainer.m_vtbl = 0;
393#endif
394}

395/*
396    seq3.3.1..1
397    C:\Program Files\Microsoft Visual Studio 8\VC\atlmfc\include\afx.inl Line91
398*/

399_AFX_INLINE CObject::CObject()
400{
401}

402
403/*
404    seq3.3.1.6
405    C:\Program Files\Microsoft Visual Studio 8\VC\crt\src\atonexit.c Line123
406*/

407int __cdecl atexit (
408        _PVFV func
409        )
410{
411        return (_onexit((_onexit_t)func) == NULL) ? -1 : 0;
412}

413
414/*
415    seq3.4
416    c:\program files\microsoft visual studio 8\vc\atlmfc\include\atldef.h Line55
417*/

418__declspec(selectany) _Please_define_it_the_same_throughout_your_project clash = _Please_define_it_the_same_throughout_your_project ();
419
420/*
421    seq3.5
422    c:\program files\microsoft visual studio 8\vc\atlmfc\include\atldef.h Line71
423*/

424__declspec(selectany) Thank_you clash = Thank_you();
425
426/*
427    seq4
428    C:\Program Files\Microsoft Visual Studio 8\VC\atlmfc\src\mfc\appmodul.cpp Line23
429*/

430extern "C" int WINAPI
431_tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
432    __in LPTSTR lpCmdLine, int nCmdShow)
433{
434    // call shared/exported WinMain
435    return AfxWinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow);
436}

437
438/*
439    seq4.1
440    C:\Program Files\Microsoft Visual Studio 8\VC\atlmfc\src\mfc\winmain.cpp Line19
441*/

442int AFXAPI AfxWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
443    __in LPTSTR lpCmdLine, int nCmdShow)
444{
445    int nReturnCode = -1;
446    //C:\Program Files\Microsoft Visual Studio 8\VC\atlmfc\src\mfc\thrdcore.cpp Line134
447    /*
448        CWinThread* AFXAPI AfxGetThread()
449        {
450            // check for current thread in module thread state
451            AFX_MODULE_THREAD_STATE* pState = AfxGetModuleThreadState();
452            CWinThread* pThread = pState->m_pCurrentWinThread;
453            return pThread;
454        }
455    */

456    //#define afxCurrentWinApp    AfxGetModuleState()->m_pCurrentWinApp:
457    CWinThread* pThread = AfxGetThread();
458    CWinApp* pApp = AfxGetApp();
459
460    // AFX internal initialization
461    //see seq4.1.1
462    if (!AfxWinInit(hInstance, hPrevInstance, lpCmdLine, nCmdShow));
463
464    // App global initializations (rare)
465    //see seq4.1.2
466    if (pApp != NULL && !pApp->InitApplication());
467
468    // Perform specific initializations
469    //see seq4.1.3
470    if (!pThread->InitInstance())
471    {
472        if (pThread->m_pMainWnd != NULL)
473        {
474            TRACE(traceAppMsg, 0"Warning: Destroying non-NULL m_pMainWnd\n");
475            pThread->m_pMainWnd->DestroyWindow();
476        }

477        nReturnCode = pThread->ExitInstance();
478        goto InitFailure;
479    }

480    nReturnCode = pThread->Run();
481
482InitFailure:
483#ifdef _DEBUG
484    // Check for missing AfxLockTempMap calls
485    if (AfxGetModuleThreadState()->m_nTempMapLock != 0)
486    {
487        TRACE(traceAppMsg, 0"Warning: Temp map lock count non-zero (%ld).\n",
488            AfxGetModuleThreadState()->m_nTempMapLock);
489    }

490    AfxLockTempMaps();
491    AfxUnlockTempMaps(-1);
492#endif
493
494    AfxWinTerm();
495    return nReturnCode;
496}

497
498/*
499    seq4.1.1
500    C:\Program Files\Microsoft Visual Studio 8\VC\atlmfc\src\mfc\appinit.cpp Line19
501*/

502BOOL AFXAPI AfxWinInit(HINSTANCE hInstance, HINSTANCE hPrevInstance,
503    __in LPTSTR lpCmdLine, int nCmdShow)
504{
505    ASSERT(hPrevInstance == NULL);
506
507
508    // handle critical errors and avoid Windows message boxes
509    SetErrorMode(SetErrorMode(0|
510        SEM_FAILCRITICALERRORS|SEM_NOOPENFILEERRORBOX);
511
512    // set resource handles
513    AFX_MODULE_STATE* pModuleState = AfxGetModuleState();
514    pModuleState->m_hCurrentInstanceHandle = hInstance;
515    pModuleState->m_hCurrentResourceHandle = hInstance;
516    pModuleState->CreateActivationContext();
517
518    // fill in the initial state for the application
519    CWinApp* pApp = AfxGetApp();
520    if (pApp != NULL)
521    {
522        // Windows specific initialization (not done if no CWinApp)
523        pApp->m_hInstance = hInstance;
524        hPrevInstance; // Obsolete.
525        pApp->m_lpCmdLine = lpCmdLine;
526        pApp->m_nCmdShow = nCmdShow;
527        pApp->SetCurrentHandles();
528    }

529
530    // initialize thread specific data (for main thread)
531    if (!afxContextIsDLL)
532        AfxInitThread();
533
534    // Initialize CWnd::m_pfnNotifyWinEvent
535    HMODULE hModule = ::GetModuleHandle(_T("user32.dll"));
536    if (hModule != NULL)
537    {
538        CWnd::m_pfnNotifyWinEvent = (CWnd::PFNNOTIFYWINEVENT)::GetProcAddress(hModule, "NotifyWinEvent");
539    }

540
541    return TRUE;
542}

543/*
544    seq4.1.2
545    C:\Program Files\Microsoft Visual Studio 8\VC\atlmfc\src\mfc\appcore.cpp Line563
546*/

547BOOL CWinApp::InitApplication()
548{
549    if (CDocManager::pStaticDocManager != NULL)
550    {
551        if (m_pDocManager == NULL)
552            m_pDocManager = CDocManager::pStaticDocManager;
553        CDocManager::pStaticDocManager = NULL;
554    }

555
556    if (m_pDocManager != NULL)
557        m_pDocManager->AddDocTemplate(NULL);
558    else
559        CDocManager::bStaticInit = FALSE;
560
561    LoadSysPolicies();
562
563    return TRUE;
564}

565/*
566    seq4.1.2.1
567    C:\Program Files\Microsoft Visual Studio 8\VC\atlmfc\src\mfc\appcore.cpp Line460
568*/

569// This function is not exception safe - will leak a registry key if exceptions are thrown from some places
570// To reduce risk of leaks, I've declared the whole function throw(). This despite the fact that its callers have
571// no dependency on non-throwing.
572BOOL CWinApp::_LoadSysPolicies() throw()
573{
574}

575
576/*
577    seq4.1.3
578    ……\CapturePacket.cpp 
579*/

580BOOL CCapturePacketApp::InitInstance()
581{
582    // InitCommonControlsEx() is required on Windows XP if an application
583    // manifest specifies use of ComCtl32.dll version 6 or later to enable
584    // visual styles.  Otherwise, any window creation will fail.
585    INITCOMMONCONTROLSEX InitCtrls;
586    InitCtrls.dwSize = sizeof(InitCtrls);
587    // Set this to include all the common control classes you want to use
588    // in your application.
589    InitCtrls.dwICC = ICC_WIN95_CLASSES;
590    InitCommonControlsEx(&InitCtrls);
591
592    CWinApp::InitInstance();
593
594    AfxEnableControlContainer();
595
596    // Standard initialization
597    // If you are not using these features and wish to reduce the size
598    // of your final executable, you should remove from the following
599    // the specific initialization routines you do not need
600    // Change the registry key under which our settings are stored
601    // TODO: You should modify this string to be something appropriate
602    // such as the name of your company or organization
603    SetRegistryKey(_T("Local AppWizard-Generated Applications"));
604
605    CCapturePacketDlg dlg;
606    m_pMainWnd = &dlg;
607    //message loop here:
608    /*
609        !!see seq4.1.3.1
610    */

611    INT_PTR nResponse = dlg.DoModal();
612    if (nResponse == IDOK)
613    {
614        // TODO: Place code here to handle when the dialog is
615        //  dismissed with OK
616    }

617    else if (nResponse == IDCANCEL)
618    {
619        // TODO: Place code here to handle when the dialog is
620        //  dismissed with Cancel
621    }

622
623    // Since the dialog has been closed, return FALSE so that we exit the
624    //  application, rather than start the application's message pump.
625
626    
627    return FALSE;
628}

629
630/*
631    seq4.1.3.1
632    C:\Program Files\Microsoft Visual Studio 8\VC\atlmfc\src\mfc\dlgcore.cpp Line483
633*/

634INT_PTR CDialog::DoModal()
635{
636    //……
637    //see seq4.1.3.1.1
638    VERIFY(RunModalLoop(dwFlags) == m_nModalResult);
639    //……
640}

641/*
642    seq4.1.3.1.1
643    C:\Program Files\Microsoft Visual Studio 8\VC\atlmfc\src\mfc\wincore.cpp Line4270
644*/

645int CWnd::RunModalLoop(DWORD dwFlags)
646{
647    //……
648    for (;;)
649    {
650        //……
651        // phase1: check to see if we can do idle work
652        while (bIdle &&
653            !::PeekMessage(pMsg, NULL, NULL, NULL, PM_NOREMOVE))
654        {
655            //……
656        }

657        // phase2: pump messages while available
658        do
659        {
660            //……
661            if (!ContinueModal())
662                goto ExitModal;
663        }
while (::PeekMessage(pMsg, NULL, NULL, NULL, PM_NOREMOVE));
664    }

665    ExitModal:
666    m_nFlags &= ~(WF_MODALLOOP|WF_CONTINUEMODAL);
667    return m_nModalResult;
668}

posted on 2006-06-19 17:51 citywanderer 阅读(6113) 评论(1)  编辑 收藏 引用 所属分类: C++

评论

# re: 剖析MFC内幕 2008-08-25 19:35 ewour
最近在学习mfc,有个问题:mfc将winmain函数隐藏在框架内。
查资料说,exe程序启动时操作系统会先调用c运行库的启动函数,启动函数再调用winmain。mfc中的winmain函数为_twinmain,在appmoudl.cpp中,但是工程中并未有该文件,mfc到底如何将appmoudl.cpp加载进来?
我的猜测是编译时由vc连接进来,到底流程是怎样的,还请能说一下。谢谢  回复  更多评论
  


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理