theApp(theApp())->//应用程序全局对象的构造和内存分配 WinMain()->//进入主函数 AfxWinMain()->//调用API InitAplacation()(应用程序的内部管理)->//用于应用程序的内部管理的初始化 Initinstance()(theApp)->//初始化应用程序对象 应用程序的Initinstance()->//应用程序的初始化(创建和注册窗口类、显示和更新应用程序框架) 注册窗口类-> AfxEndDeferRegisterClass ()(该函数根据不同的应用程序注册不同的窗口类)-> AfxRegisterClass()-> CMainFrame::PreCreateWindow()-> CFrameWnd::PreCreateWindow()-> AfxDeferRegisterClass()(如果没有注册,就注册窗口类;它实际上是AfxEndRegisterClass()的宏)(一般都是在这里注册窗口类,由于文档窗口涉及到文档视图类的管理)-> LoadFrame()->//载入框架 CFrameWnd::Create()->/ CWnd::CreateEx()->//创建应用程序窗口 CMainFrame::PreCreateWindow()(实际上该函数是一个虚函数,也就是说如果子类为应用程序定义了该函数,那么它将调用子类的函数,因此,我们可以重载该函数来修改应用程序框架的外观)->//在框架窗口显示之前调用 ShowWindow()->UpdateWindow()->//显示和更新 消息循环:-> CwinThread::Run()-> do-while()循环(->PumpMessage()->GetMessage()->TranslateMessage()->DispatchMessage()) |
简单的说就是初始化全局对象进入主函数再进行窗口类的创建和注册并显示,然后进入消息循环。
theApp:全局变量或是类对象在程序运行前初始化。即分配内存空间,初始成员。(每一个MFC应用程序都只有一个全局对象theApp对象,我们用该全局对象唯一的表示该应用程序。)
下面我们给出这些函数如何跟踪(我的是装在C:盘下的他们都在。。\MFC\SRC\下)
WinMain()函数(C:\Program Files\Microsoft Visual Studio\VC98\MFC\SRC\APPMODUL.CPP) WinApp(C:\Program Files\Microsoft Visual Studio\VC98\MFC\SRC\THRDCORE.CPP) AfxWinMain()(C:\Program Files\Microsoft Visual Studio\VC98\MFC\SRC\WINMAIN.CPP) 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()) // C:\Program Files\Microsoft Visual Studio\VC98\MFC\include\AFXWIN.H) goto InitFailure; // Perform specific initializations if (!pThread->InitInstance()) // C:\Program Files\Microsoft Visual Studio\VC98\MFC\include\AFXWIN.H) { 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; } AfxEndDeferRegisterClass #define AfxDeferRegisterClass(fClass) AfxEndDeferRegisterClass(fClass) BOOL AFXAPI AfxEndDeferRegisterClass(LONG fToRegister) { // mask off all classes that are already registered AFX_MODULE_STATE* pModuleState = AfxGetModuleState(); fToRegister &= ~pModuleState->m_fRegisteredClasses; if (fToRegister == 0) return TRUE; LONG fRegisteredClasses = 0; // common initialization WNDCLASS wndcls; memset(&wndcls, 0, sizeof(WNDCLASS)); // start with NULL defaults wndcls.lpfnWndProc = DefWindowProc; wndcls.hInstance = AfxGetInstanceHandle(); wndcls.hCursor = afxData.hcurArrow; INITCOMMONCONTROLSEX init; init.dwSize = sizeof(init); //各种各样的窗口类的注册 // work to register classes as specified by fToRegister, populate fRegisteredClasses as we go if (fToRegister & AFX_WND_REG) { // Child windows - no brush, no icon, safest default class styles wndcls.style = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW; wndcls.lpszClassName = _afxWnd; if (AfxRegisterClass(&wndcls)) fRegisteredClasses |= AFX_WND_REG; } if (fToRegister & AFX_WNDOLECONTROL_REG) { // OLE Control windows - use parent DC for speed wndcls.style |= CS_PARENTDC | CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW; wndcls.lpszClassName = _afxWndOleControl; if (AfxRegisterClass(&wndcls)) fRegisteredClasses |= AFX_WNDOLECONTROL_REG; } if (fToRegister & AFX_WNDCONTROLBAR_REG) { // Control bar windows wndcls.style = 0; // control bars don't handle double click wndcls.lpszClassName = _afxWndControlBar; wndcls.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1); if (AfxRegisterClass(&wndcls)) fRegisteredClasses |= AFX_WNDCONTROLBAR_REG; } if (fToRegister & AFX_WNDMDIFRAME_REG) { // MDI Frame window (also used for splitter window) wndcls.style = CS_DBLCLKS; wndcls.hbrBackground = NULL; if (_AfxRegisterWithIcon(&wndcls, _afxWndMDIFrame, AFX_IDI_STD_MDIFRAME)) fRegisteredClasses |= AFX_WNDMDIFRAME_REG; } if (fToRegister & AFX_WNDFRAMEORVIEW_REG) { // SDI Frame or MDI Child windows or views - normal colors wndcls.style = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW; wndcls.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1); if (_AfxRegisterWithIcon(&wndcls, _afxWndFrameOrView, AFX_IDI_STD_FRAME)) fRegisteredClasses |= AFX_WNDFRAMEORVIEW_REG; } if (fToRegister & AFX_WNDCOMMCTLS_REG) { // this flag is compatible with the old InitCommonControls() API init.dwICC = ICC_WIN95_CLASSES; fRegisteredClasses |= _AfxInitCommonControls(&init, AFX_WIN95CTLS_MASK); fToRegister &= ~AFX_WIN95CTLS_MASK; } if (fToRegister & AFX_WNDCOMMCTL_UPDOWN_REG) { init.dwICC = ICC_UPDOWN_CLASS; fRegisteredClasses |= _AfxInitCommonControls(&init, AFX_WNDCOMMCTL_UPDOWN_REG); } if (fToRegister & AFX_WNDCOMMCTL_TREEVIEW_REG) { init.dwICC = ICC_TREEVIEW_CLASSES; fRegisteredClasses |= _AfxInitCommonControls(&init, AFX_WNDCOMMCTL_TREEVIEW_REG); } if (fToRegister & AFX_WNDCOMMCTL_TAB_REG) { init.dwICC = ICC_TAB_CLASSES; fRegisteredClasses |= _AfxInitCommonControls(&init, AFX_WNDCOMMCTL_TAB_REG); } if (fToRegister & AFX_WNDCOMMCTL_PROGRESS_REG) { init.dwICC = ICC_PROGRESS_CLASS; fRegisteredClasses |= _AfxInitCommonControls(&init, AFX_WNDCOMMCTL_PROGRESS_REG); } if (fToRegister & AFX_WNDCOMMCTL_LISTVIEW_REG) { init.dwICC = ICC_LISTVIEW_CLASSES; fRegisteredClasses |= _AfxInitCommonControls(&init, AFX_WNDCOMMCTL_LISTVIEW_REG); } if (fToRegister & AFX_WNDCOMMCTL_HOTKEY_REG) { init.dwICC = ICC_HOTKEY_CLASS; fRegisteredClasses |= _AfxInitCommonControls(&init, AFX_WNDCOMMCTL_HOTKEY_REG); } if (fToRegister & AFX_WNDCOMMCTL_BAR_REG) { init.dwICC = ICC_BAR_CLASSES; fRegisteredClasses |= _AfxInitCommonControls(&init, AFX_WNDCOMMCTL_BAR_REG); } if (fToRegister & AFX_WNDCOMMCTL_ANIMATE_REG) { init.dwICC = ICC_ANIMATE_CLASS; fRegisteredClasses |= _AfxInitCommonControls(&init, AFX_WNDCOMMCTL_ANIMATE_REG); } if (fToRegister & AFX_WNDCOMMCTL_INTERNET_REG) { init.dwICC = ICC_INTERNET_CLASSES; fRegisteredClasses |= _AfxInitCommonControls(&init, AFX_WNDCOMMCTL_INTERNET_REG); } if (fToRegister & AFX_WNDCOMMCTL_COOL_REG) { init.dwICC = ICC_COOL_CLASSES; fRegisteredClasses |= _AfxInitCommonControls(&init, AFX_WNDCOMMCTL_COOL_REG); } if (fToRegister & AFX_WNDCOMMCTL_USEREX_REG) { init.dwICC = ICC_USEREX_CLASSES; fRegisteredClasses |= _AfxInitCommonControls(&init, AFX_WNDCOMMCTL_USEREX_REG); } if (fToRegister & AFX_WNDCOMMCTL_DATE_REG) { init.dwICC = ICC_DATE_CLASSES; fRegisteredClasses |= _AfxInitCommonControls(&init, AFX_WNDCOMMCTL_DATE_REG); } // save new state of registered controls pModuleState->m_fRegisteredClasses |= fRegisteredClasses; // special case for all common controls registered, turn on AFX_WNDCOMMCTLS_REG if ((pModuleState->m_fRegisteredClasses & AFX_WIN95CTLS_MASK) == AFX_WIN95CTLS_MASK) { pModuleState->m_fRegisteredClasses |= AFX_WNDCOMMCTLS_REG; fRegisteredClasses |= AFX_WNDCOMMCTLS_REG; } // must have registered at least as mamy classes as requested return (fToRegister & fRegisteredClasses) == fToRegister; } BOOL CFrameWnd::LoadFrame(UINT nIDResource, DWORD dwDefaultStyle, CWnd* pParentWnd, CCreateContext* pContext) { // only do this once ASSERT_VALID_IDR(nIDResource); ASSERT(m_nIDHelp == 0 || m_nIDHelp == nIDResource); m_nIDHelp = nIDResource; // ID for help context (+HID_BASE_RESOURCE) CString strFullString; if (strFullString.LoadString(nIDResource)) AfxExtractSubString(m_strTitle, strFullString, 0); // first sub-string VERIFY(AfxDeferRegisterClass(AFX_WNDFRAMEORVIEW_REG)); // attempt to create the window LPCTSTR lpszClass = GetIconWndClass(dwDefaultStyle, nIDResource); LPCTSTR lpszTitle = m_strTitle; if (!Create(lpszClass, lpszTitle, dwDefaultStyle, rectDefault, pParentWnd, MAKEINTRESOURCE(nIDResource), 0L, pContext)) { return FALSE; // will self destruct on failure normally } // save the default menu handle ASSERT(m_hWnd != NULL); m_hMenuDefault = ::GetMenu(m_hWnd); // load accelerator resource LoadAccelTable(MAKEINTRESOURCE(nIDResource)); if (pContext == NULL) // send initial update SendMessageToDescendants(WM_INITIALUPDATE, 0, 0, TRUE, TRUE); return TRUE; } CWnd::CreateEx() virtual BOOL CreateEx( DWORD dwExStyle, LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, int x, int y, int nWidth, int nHeight, HWND hWndParent, HMENU nIDorHMenu, LPVOID lpParam = NULL ); virtual BOOL CreateEx( DWORD dwExStyle, LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, LPVOID lpParam = NULL ); CMainFrame::PreCreateWindow() virtual BOOL PreCreateWindow( CREATESTRUCT& cs ); typedef struct tagCREATESTRUCT { LPVOID lpCreateParams; HANDLE hInstance; HMENU hMenu; HWND hwndParent; int cy; int cx; int y; int x; LONG style; LPCSTR lpszName; LPCSTR lpszClass; DWORD dwExStyle; } CREATESTRUCT; CwinThread::Run() int CWinApp::Run() { if (m_pMainWnd == NULL && AfxOleGetUserCtrl()) { // Not launched /Embedding or /Automation, but has no main window! TRACE0("Warning: m_pMainWnd is NULL in CWinApp::Run - quitting application.\n"); AfxPostQuitMessage(0); } return CWinThread::Run(); } 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 } |
欢迎访问最专业的网吧论坛,无盘论坛,网吧经营,网咖管理,网吧专业论坛
https://bbs.txwb.com
关注天下网吧微信/下载天下网吧APP/天下网吧小程序,一起来超精彩
|
本文来源:vczx 作者:佚名