科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道基础软件关于MFC内部结构实用的一点看法

关于MFC内部结构实用的一点看法

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

我们在编写程序或是在看MFC类的书籍的时候,总会看到书上让我们在某个地方添加某某函数,响应什么消息。

作者:章志强 来源:VCKBASE 2007年10月16日

关键字:

  • 评论
  • 分享微博
  • 分享邮件
下面我们给出这些函数如何跟踪(我的是装在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
}

  MFC中的窗口销毁时,对象不一定销毁,窗口只是与对象的m-hWnd关联;但是如果一个对象销毁了,则拥有该对象的窗口也要销毁。

  好了,现在相信大家应该至少知道对于什么时候添加消息和在什么地方捕获消息有一个大致的了解了吧,写的仓促,难免有错,还请多多见量,谢谢。希望大家可以一起进步。

查看本文来源

    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章