²©¿ÍÊ×Ò³ ×¢²á ½¨ÒéÓë½»Á÷ ÅÅÐаñ ¼ÓÈëÓÑÇéÁ´½Ó
ÍÆ¼ö ͶËß ËÑË÷£º °ïÖú

hardworkor

hardworkor.cublog.cn
mfc ÎĵµÊÓͼ½á¹¹ÄÚÄ»
mfcÎĵµÊÓͼ½á¹¹ÄÚÄ»(×ªÔØ)

     ////////////////////////////////////////////////////////////////////////////////////
                     /********* ÎÄÕÂϵÁУºMFC¼¼ÊõÄÚĻϵÁÐ***********/
                     /************MFC¼¼ÊõÄÚĻϵÁÐÖ®£¨¶þ£©***********/
                     /****    ÎÄÕÂÌâÄ¿£ºMFCÎĵµÊÓͼ½á¹¹ÄÚÄ»          *****/
                     /*                           Copyright(c)2002 bigwhite             */
                     /*                                 All rights Reserved                   */
                     /*********¹Ø¼ü×Ö£ºMFC£¬ÎĵµÊÓͼ½á¹¹************/
                     /*                                  Ê±¼ä£º2002.7.23                   */
                     /*     ×¢ÊÍ£º±¾ÎÄËùÉæ¼°µÄ³ÌÐòÔ´´úÂë¾ùÔÚMicrosoft   */
                     /             Visual Studio.Net Enterprise Architect Edition   /
                     /*                   ¿ª·¢¹¤¾ß°üÌṩµÄÔ´´úÂëÖР               */
                    
//////////////////////////////////////////////////////////////////////////////////////////////////////////
ÒýÑÔ£ººî½ÝÀÏʦµÄ"ÉîÈëdz³öMFC"Ò»ÊéµÄµÚ8ÕÂÖÐÓС°"Document/View"ÊÇMFCµÄ»ùʯ¡£¡±Ò»Ëµ£¬¿ÉÒÔ¿´³öÎĵµÊÓͼ½á¹¹ÔÚMFC FrameworkÖеĵØÎ»ÊǶàôµÄÖØÒª¡£±¾ÎĽ«ÒÔÒ»¸ö±ê×¼MFCÓ¦ÓóÌÐòÏòµ¼×÷³ÉµÄMDI³ÌÐòΪÀý£¬À´ºÍ´ó¼ÒÒ»ÆðÏêϸÍÚ¾òÎĵµÊÓͼ½á¹¹µÄÄÚÄ»¡£

ÕýÎÄ£º
                       /////////////////////////////////////////////
                       /*  1.»Ø¹Ë"InitInstanceº¯Êý"  */
                       /////////////////////////////////////////////
   ÔÚÎҵġ¶MFCÓ¦ÓóÌÐò¡°ÉúËÀÒò¹û¡±ÄÚÄ»¡·Ò»ÎÄÖУ¬µ±Ì¸µ½CMyWinApp::InitInstance()ʱ£¬ÎÒÖ»ÊÇ´ÖÂԵĽ²Á˽éÉÜÁËһϸ÷¸öº¯ÊýµÄ¹¦ÄÜ£¬¶øºöÂÔÁ˺ܶàϸ½Ú£¬ÕâÀïÈÃÎÒÃÇÔڻعËÒ»ÏÂCMyWinApp::InitInstance()º¯Êý£¬²¢½«ÀïÃæÓëÎĵµÊÓͼ½á¹¹ÓйصĴúÂëÉîÈë̽ÌÖһϣº
   BOOL CMyApp::InitInstance()//Ö»ÁгöÁËÓëÎĵµÊÓͼ½á¹¹Ïà¹ØµÄÔ´´úÂë
  {
 //...

 //ÎĵµÄ£°å½«ÓÃ×÷Îĵµ¡¢¿ò¼Ü´°¿ÚºÍÊÓͼ֮¼äµÄÁ¬½Ó
 CMultiDocTemplate* pDocTemplate;
 pDocTemplate = new CMultiDocTemplate(IDR_MyTYPE,
  RUNTIME_CLASS(CMyDoc),
  RUNTIME_CLASS(CChildFrame), // ×Ô¶¨Òå MDI ×Ó¿ò¼Ü
  RUNTIME_CLASS(CMyView));
 AddDocTemplate(pDocTemplate);
 // ´´½¨Ö÷ MDI ¿ò¼Ü´°¿Ú
 CMainFrame* pMainFrame = new CMainFrame;
 if (!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;
 }

                       ////////////////////////////////////////////
                       /*     2.³õʼ»¯ÎĵµÄ£°å       */
                       ////////////////////////////////////////////
·ÖÎöÒÔÏ´úÂ룺
        CMultiDocTemplate* pDocTemplate;
 pDocTemplate = new CMultiDocTemplate(IDR_MyTYPE,
  RUNTIME_CLASS(CMyDoc),
  RUNTIME_CLASS(CChildFrame), // ×Ô¶¨Òå MDI ×Ó¿ò¼Ü
  RUNTIME_CLASS(CMyView));
    Ó¦ÓóÌÐòÊ×ÏÈʵÀý»¯Ò»¸öCMultiDocTemplate¶ÔÏ󣬴˹ý³ÌÒ²ÊǶÔCMultiDocTemplateÀàÊý¾Ý³ÉÔ±µÄ³õʼ»¯¹ý³Ì¡£°´µ÷ÓôÎÐòÎÒÁгöÁËÒÔÏÂÔ´´úÂ룺
    ×¢ÊÍ1: CDocTemplate¹¹Ô캯Êý¶¨ÒåÔÚ£º..Visual Studio.NETvc7atlmfcsrcmfcdoctempl.cpp
 CDocTemplate::CDocTemplate(UINT nIDResource, CRuntimeClass* pDocClass,
           CRuntimeClass* pFrameClass, CRuntimeClass* pViewClass)//²¿·ÖÔ´´úÂë
 {
 ASSERT_VALID_IDR(nIDResource);
 ASSERT(pDocClass == NULL ||
  pDocClass->IsDerivedFrom(RUNTIME_CLASS(CDocument)));
 ASSERT(pFrameClass == NULL ||
  pFrameClass->IsDerivedFrom(RUNTIME_CLASS(CFrameWnd)));
 ASSERT(pViewClass == NULL ||
  pViewClass->IsDerivedFrom(RUNTIME_CLASS(CView)));

 m_nIDResource = nIDResource;
 ...//
        m_pDocClass = pDocClass;
 m_pFrameClass = pFrameClass;
 m_pViewClass = pViewClass;
 m_pOleFrameClass = NULL;
 m_pOleViewClass = NULL;
        ...//
 }
  ÒÔÉÏΪCMultiDocTemplateÀàµÄ»ùÀàCDocTemplate¹¹Ô캯ÊýµÄ²¿·ÖÔ´´úÂ룬¸Ãº¯Êý³õʼ»¯ÁËËĸöÖØÒªµÄ³ÉÔ±
m_nIDResource£¬m_pDocClass£¬m_pFrameClassºÍm_pViewClass¡£
   ×¢ÊÍ2: CMultiDocTemplate¹¹Ô캯Êý¶¨ÒåÔÚ£º..Visual Studio.NETvc7atlmfcsrcmfcdocmulti.cpp
   CMultiDocTemplate::CMultiDocTemplate(UINT nIDResource, CRuntimeClass* pDocClass,
 CRuntimeClass* pFrameClass, CRuntimeClass* pViewClass)
  : CDocTemplate(nIDResource, pDocClass, pFrameClass, pViewClass)
  {
 ASSERT(m_docList.IsEmpty());

 m_hMenuShared = NULL;
 m_hAccelTable = NULL;
 m_nUntitledCount = 0;   // start at 1

 // load resources in constructor if not statically allocated
 if (!CDocManager::bStaticInit)
  LoadTemplate();
  }
   ¿´ÍêÒÔÉÏ´úÂëºó£¬À´»Ø¹ýÍ·¿´Ò»¿´InitInstanceº¯Êý½«Ê²Ã´²ÎÊýÖµ´«¸øÁËCMultiDocTemplateµÄ¹¹Ô캯Êý¡£
Ô­À´ÊÇһЩRUNTIME_CLASSºê¡£ÒÔÏÂÊÇRUNTIME_CLASSºêµÄ¶¨Òå:
   ×¢ÊÍ3: ÒÔϵĺ궨ÒåÔÚ£º..Visual Studio.NETvc7atlmfcincludeafx.hÖÐ
   #define RUNTIME_CLASS(class_name) _RUNTIME_CLASS(class_name)
   #define _RUNTIME_CLASS(class_name) ((CRuntimeClass*)(&class_name::class##class_name))
   Õâ¸öµØ·½ÊǸöÄѵ㣬Õâ½«Éæ¼°µ½MFCµÄÁíÒ»¸öÖØÒª¼¼Êõ---"Ö´ÐÐÆÚÀàÐÍʶ±ð"¡£´ËÏî¼¼ÊõÎÒ½«ÔÚ
MFC¼¼ÊõÄÚĻϵÁÐÖ®£¨Èý£©---¡¶MFCÖ´ÐÐÆÚÀàÐÍʶ±ðÓ붯̬´´½¨¼¼ÊõÄÚÄ»¡·ÖÐÏêϸ½²½â¡£»Øµ½ÑÛǰÀ´£¬Ô´´úÂëÖÐÕâÑù×÷ÊÇΪÁ˽«CMyDoc£¬CChildFrame£¬CMyView¸÷ÀàÖеÄstatic CRuntimeClass class##class_nameµØÖ·¸³ÓèCMultiDocTemplateÀàµÄ¸÷CRuntimeClass*Ö¸Õë³ÉÔ±m_pDocClass£¬m_pFrameClassºÍm_pViewClass£¬ÕâλÒÔºóµÄ¶¯Ì¬´´½¨Document/Frame/View"Èý¿Ú×é"´òÏÂÁË»ù´¡¡£
                       ///////////////////////////////////////////
                       /*       3.ÎĵµÄ£°åÁжӠ      */
                       ///////////////////////////////////////////
   ÎĵµÄ£°å³õʼ»¯½áÊøºó£¬InitInstanceº¯Êýµ÷ÓÃÁËCWinApp::AddDocTemplate(pDocTemplate)º¯Êý£¬ÆäÖ÷ҪĿµÄÊǽ«ÒÔ³õʼ»¯ºóµÄÄǸöÎĵµÄ£°å¼ÓÈëµ½ÎĵµÄ£°åÁ´±íÖÐ,²¢ÓÉCDocManagerÀà¶ÔÏó½øÐйÜÀí¡£ÒÔϲÙ×÷¾ÍÊÇΪÁËÍê³É´Ë¹¤×÷¡£

×¢ÊÍ1: ÒÔϺ¯Êý¶¨ÒåÔÚ£º..Visual Studio.NETvc7atlmfcsrcmfcappui2.cpp
void CWinApp::AddDocTemplate(CDocTemplate* pTemplate)//½«CMultiDocTemplate* pDocTemplate
{                                                    //´«¸øpTemplate
 if (m_pDocManager == NULL)
  m_pDocManager = new CDocManager;
 m_pDocManager->AddDocTemplate(pTemplate);
}
×¢ÊÍ2: ÒÔϺ¯Êý¶¨ÒåÔÚ£º..Visual Studio.NETvc7atlmfcsrcmfcdocmgr.cpp
 CDocManager::CDocManager()
 {
  }//ĿǰÊÇÒ»¸ö¿Õº¯Êý£»

 void CDocManager::AddDocTemplate(CDocTemplate* pTemplate)//²¿·ÖÔ´´úÂë
 {
 if (pTemplate == NULL)
 {
  ...//
 }
 else
 {
  ASSERT_VALID(pTemplate);
  ASSERT(m_templateList.Find(pTemplate, NULL) == NULL);// must not be in list
  pTemplate->LoadTemplate();
  m_templateList.AddTail(pTemplate);//CPtrList m_templateList is a member                                                             //of CDocManager
 }
 }

                       ///////////////////////////////////////////////
                       /*    4.´´½¨³ÌÐòÖ÷¿ò¼Ü´°¿Ú    */
                       ///////////////////////////////////////////////
    Ó¦ÓóÌÐòʵÀý»¯ÁËÒ»¸öCMainFrameÀà¶ÔÏ󣬲¢µ÷ÓÃLoadFrameº¯Êý¼ÓÔØ´°¿Ú×ÊÔ´´´½¨Ö÷¿ò¼Ü´°¿Ú¡£ÒÔÏÂÊÇ´´½¨Ö÷¿ò¼Ü´°¿ÚµÄÁ÷³Ì¡£
    ´´½¨´°¿ÚµÄÖ÷Òª´úÂëÊÇ£ºpMainFrame->LoadFrame(IDR_MAINFRAME)£»LoadFrameº¯ÊýÊÇMFC°ü×°ÁË´°¿Ú´´½¨¹ý³ÌµÄº¯Êý£¬ÔÚºóÃæ¶¯Ì¬´´½¨Child´°¿Úʱ£¬Ëü»¹½«Åû¹ÒÉÏÕó(µ«ÉÔÓв»Í¬£©¡£ÏÂÃæÊÇËüµÄÔ´´úÂë,ÈÃÎÒÃÇ×Ðϸ·ÖÎöÒ»ÏÂ:
  ×¢ÊÍ1: ÒÔϺ¯Êý¶¨ÒåÔÚ£º..Visual Studio.NETvc7atlmfcsrcmfcwinmdi.cpp
   
  BOOL CMDIFrameWnd::LoadFrame(UINT nIDResource, DWORD dwDefaultStyle,
 CWnd* pParentWnd, CCreateContext* pContext)          
 {
 if (!CFrameWnd::LoadFrame(nIDResource, dwDefaultStyle,
   pParentWnd, pContext))
  return FALSE;

 // save menu to use when no active MDI child window is present
 ASSERT(m_hWnd != NULL);
 m_hMenuDefault = ::GetMenu(m_hWnd);
 if (m_hMenuDefault == NULL)
  TRACE(traceAppMsg, 0, "Warning: CMDIFrameWnd without a default menu. ");
 return TRUE;
 }
  CMDIFrameWnd::LoadFrameµ÷ÓÃÁËÆä»ùÀàCFrameWndµÄLoadFrame£¬²¢½«²ÎÊýÔ­·â²»¶¯µÄ´«¸øËü¡£

  ×¢ÊÍ2: ÒÔϺ¯Êý¶¨ÒåÔÚ£º..Visual Studio.NETvc7atlmfcsrcmfcwinfrm.cpp
 BOOL CFrameWnd::LoadFrame(UINT nIDResource, DWORD dwDefaultStyle,
 CWnd* pParentWnd, CCreateContext* pContext)          //²¿·ÖÔ´´úÂë
 {
 ...//
 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);
 CString strTitle = m_strTitle;
 if (!Create(lpszClass, strTitle, dwDefaultStyle, rectDefault,
   pParentWnd, MAKEINTRESOURCE(nIDResource), 0L, pContext))
 {
  return FALSE;   // will self destruct on failure normally
 }

 ...//
 if (pContext == NULL)   // send initial update
  SendMessageToDescendants(WM_INITIALUPDATE, 0, 0, TRUE, TRUE);

 return TRUE;
 }
                       //////////////////////////////////////////////////////
                       /* 4.1×¢²áÓ¦ÓóÌÐòÖ÷¿ò¼Ü´°¿ÚÀà */
                       //////////////////////////////////////////////////////
   ÔÚ´«Í³µÄWin32API±à³ÌÖУ¬´´½¨´°¿ÚÒ»°ã²½ÖèÊǶ¨Òå´°¿ÚÀ࣬ע²á´°¿ÚÀ࣬²¢µ÷ÓÃ::CreateWindowº¯ÊýÀ´´´½¨¡£Ç°ÃæËµ¹ýLoadFrameº¯Êý·â×°ÁËMFC´´½¨´°¿ÚµÄ¹ý³Ì£¬ÄÇôҲ¾ÍÊÇ˵LoadFrameº¯Êý½«¸ºÔð¶¨Òå´°¿ÚÀ࣬ע²á´°¿ÚÀàµÈËöË鹤×÷¡£ÏÂÃæÎÒÃǾÍͨ¹ýÍÚ¾òÔ´´úÂëÀ´¿´¿´LoadFrameº¯ÊýÊÇÈçºÎÍê³ÉÕâЩ¹¤×÷µÄ¡£
   LoadFrameÊ×Ïȵ÷ÓÃAfxDeferRegisterClass(AFX_WNDFRAMEORVIEW_REG)£¬
   ×¢ÊÍ1: ÒÔϺ궨ÒåÔÚ£º..Visual Studio.NETvc7atlmfcsrcmfcafximpl.h
       #define AfxDeferRegisterClass(fClass) AfxEndDeferRegisterClass(fClass)
  
   ×¢ÊÍ2: ÒÔϺ¯Êý¶¨ÒåÔÚ£º..Visual Studio.NETvc7atlmfcsrcmfcwincore.cpp
 
  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_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;
 }  
        
       ...//
 // must have registered at least as mamy classes as requested
 return (fToRegister & fRegisteredClasses) == fToRegister;
   }
   MFCÔ¤¶¨ÒåÁËÈô¸É¸ö¡°´°¿ÚÀàÄ£°å¡±£¬±ÈÈç"AFX_WNDMDIFRAME_REG","AFX_WNDFRAMEORVIEW_REG"µÈ£¬MFCÔÚ
LoadFrameº¯ÊýÖе÷ÓÃAfxEndDeferRegisterClassº¯ÊýΪÄãµÄÓ¦ÓóÌÐòԤע²áÁËÊʵ±µÄ´°¿ÚÀà¡£±¾ÀýÖÐԤע²áµÄ´°¿ÚÀàΪAFX_WNDFRAMEORVIEW_REG¡££¨×¢ÒâÊÇԤע²á£¬Èç¹ûÄãÔÚºóÃæ¸ü¸ÄÁËCREATESTRUCT½á¹¹µÄÓò³ÉÔ±£¬MFC»¹»á¸ù¾ÝÄãµÄ¸ü¸ÄÖØÐÂΪÄãµÄÓ¦ÓóÌÐòÕýʽע²áеĴ°¿ÚÀ࣬ÉÔºò»áÓÐÏêϸÐðÊö£©
  
   Ԥע²áÍê´°¿ÚÀ࣬MFC½«ÅжÏÄãÊÇ·ñÏë¸ü¸Ä´°¿ÚÀàµÄ¸÷²ÎÊý¡£ÈôÄã¸ü¸ÄÁË£¬ÔòMFC»áÖØÐÂ×¢²áÐÂÀࣻ·ñÔòԴԤע²áµÄ´°¿ÚÀà¾Í½«³ÉΪÕýʽµÄ´°¿ÚÀà¡£ÏÂÃæÎÒÃÇÀ´¿´¿´MFCµÄÅжϹý³Ì£º´ËÅжϹý³ÌÓÉGetIconWndClass¿ªÊ¼
  LPCTSTR lpszClass = GetIconWndClass(dwDefaultStyle, nIDResource);
  ×¢ÊÍ3: ÒÔϺ¯Êý¶¨ÒåÔÚ£º..Visual Studio.NETvc7atlmfcsrcmfcwinfrm.cpp
 
  LPCTSTR CFrameWnd::GetIconWndClass(DWORD dwDefaultStyle, UINT nIDResource)//²¿·ÖÔ´´úÂë
 {
 ...//
 HICON hIcon = ::LoadIcon(hInst, MAKEINTRESOURCE(nIDResource));
 if (hIcon != NULL)
 {
  CREATESTRUCT cs;
  memset(&cs, 0, sizeof(CREATESTRUCT));
  cs.style = dwDefaultStyle;
  PreCreateWindow(cs);
   // will fill lpszClassName with default WNDCLASS name
   // ignore instance handle from PreCreateWindow.

  WNDCLASS wndcls;
  if (cs.lpszClass != NULL &&
   GetClassInfo(AfxGetInstanceHandle(), cs.lpszClass, &wndcls) &&
   wndcls.hIcon != hIcon)
  {
   // register a very similar WNDCLASS
   return AfxRegisterWndClass(wndcls.style,
    wndcls.hCursor, wndcls.hbrBackground, hIcon);
  }
 }
 return NULL;        // just use the default
}
   GetIconWndClassº¯Êý½«µ÷ÓÃCMainFrame::PreCreateWindow(CREATESTRUCT& cs)À´¿´¿´Ó¦ÓóÌÐòÊÇ·ñÐÞ¸ÄÁËCREATESTRUCT½á¹¹µÄÓò³ÉÔ±¡£CMainFrame::PreCreateWindowµ÷Óà  CMDIFrameWnd::PreCreateWindow(CREATESTRUCT& cs)£¬ºóÕߵĴúÂëÈçÏÂ:
  BOOL CMDIFrameWnd::PreCreateWindow(CREATESTRUCT& cs)//in winmdi.cpp
  {
 if (cs.lpszClass == NULL)
 {
  VERIFY(AfxDeferRegisterClass(AFX_WNDMDIFRAME_REG));
  cs.lpszClass = _afxWndMDIFrame;
 }
 return TRUE;
  }
  MFC½«ÎªÓ¦ÓóÌÐò×¢²áAFX_WNDMDIFRAME_REGÔ¤¶¨Òå´°¿ÚÀ࣬²¢ÉèÖÃcs.lpszClass = _afxWndMDIFrame¡£
ÔÚÓ¦ÓóÌÐòµÄ´úÂëÖÐÎÒ¸ü¸ÄÁËcs½á¹¹£º
  BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
 {
 if( !CMDIFrameWnd::PreCreateWindow(cs) )
  return FALSE;
 // TODO: ÔÚ´Ë´¦Í¨¹ýÐÞ¸Ä CREATESTRUCT cs À´Ð޸Ĵ°¿ÚÀà»ò
 // Ñùʽ
 cs.dwExStyle=~WS_EX_CLIENTEDGE;
 return TRUE;
 }  
 
 CMainFrame::PreCreateWindow·µ»Øºó£¬GetIconWndClassº¯Êýµ÷ÓÃGetClassInfoº¯ÊýÖØÐÂÊÕ¼¯csÐÅÏ¢£¨´ËʱµÄÐÅÏ¢ÒÑÊǸü¸ÄºóµÄÁË)£¬²¢µ÷ÓÃAfxRegisterWndClassº¯ÊýÖØÐÂ×¢²á¸Ã´°¿ÚÀࣨ´Ë´°¿ÚÀàΪ¸ÃÓ¦ÓóÌÐòµÄÕýʽ´°¿ÚÀࣩ¡£µ½´ËΪֹ´°¿ÚÀà×¢²áÍê±Ï£¬ÒÔºó³ÌÐò»¹»áµ÷ÓÃÒ»´ÎCMainFrame::PreCreateWindow£¬²»¹ýÄÇ´ËÖ»ÊÇ"¹ýÃŲ»Èç"¶øÒÑ¡£
                       /////////////////////////////////////////////////
                       /*    4.2Ö÷¿ò¼Ü´°¿Ú´´½¨¿ªÊ¼    */
                       /////////////////////////////////////////////////

  ¿ªÊ¼½øÈë´´½¨¿ò¼Ü´°¿ÚµÄʵÖʽ׶Ρ£¿´LoadFrameº¯Êý×öÁËʲô?Ô­À´Ëüµ÷ÓÃÁËCreateº¯Êý¡£
  ×¢ÊÍ1: ÒÔϺ¯Êý¶¨ÒåÔÚ£º..Visual Studio.NETvc7atlmfcsrcmfcwinfrm.cpp
   BOOL CFrameWnd::Create(LPCTSTR lpszClassName,
 LPCTSTR lpszWindowName,
 DWORD dwStyle,
 const RECT& rect,
 CWnd* pParentWnd,
 LPCTSTR lpszMenuName,
 DWORD dwExStyle,
 CCreateContext* pContext)
  {
 HMENU hMenu = NULL;
 if (lpszMenuName != NULL)
 {
  // load in a menu that will get destroyed when window gets destroyed
  HINSTANCE hInst = AfxFindResourceHandle(lpszMenuName, RT_MENU);
  if ((hMenu = ::LoadMenu(hInst, lpszMenuName)) == NULL)
  {
   TRACE(traceAppMsg, 0, "Warning: failed to load menu for CFrameWnd. ");
   PostNcDestroy();            // perhaps delete the C++ object
   return FALSE;
  }
 }

 m_strTitle = lpszWindowName;    // save title for later

 if (!CreateEx(dwExStyle, lpszClassName, lpszWindowName, dwStyle,
  rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top,
  pParentWnd->GetSafeHwnd(), hMenu, (LPVOID)pContext))
 {
  TRACE(traceAppMsg, 0, "Warning: failed to create CFrameWnd. ");
  if (hMenu != NULL)
   DestroyMenu(hMenu);
  return FALSE;
 }

 return TRUE;
  }

  ¼òµ¥µØËµCFrameWnd::Createº¯Êýµ÷ÓÃÁË»ùÀàµÄCWnd::CreateEx£»
  ×¢ÊÍ2: ÒÔϺ¯Êý¶¨ÒåÔÚ£º..Visual Studio.NETvc7atlmfcsrcmfcwincore.cpp
  BOOL CWnd::CreateEx(DWORD dwExStyle, LPCTSTR lpszClassName,
 LPCTSTR lpszWindowName, DWORD dwStyle,
 int x, int y, int nWidth, int nHeight,
 HWND hWndParent, HMENU nIDorHMenu, LPVOID lpParam)//²¿·ÖÔ´´úÂë
 {
 // allow modification of several common create parameters
 CREATESTRUCT cs;
 cs.dwExStyle = dwExStyle;
 cs.lpszClass = lpszClassName;
 cs.lpszName = lpszWindowName;
 cs.style = dwStyle;
 cs.x = x;
 cs.y = y;
 cs.cx = nWidth;
 cs.cy = nHeight;
 cs.hwndParent = hWndParent;
 cs.hMenu = nIDorHMenu;
 cs.hInstance = AfxGetInstanceHandle();
 cs.lpCreateParams = lpParam;

 if (!PreCreateWindow(cs))
 {
  PostNcDestroy();
  return FALSE;
 }

 AfxHookWindowCreate(this);
 HWND hWnd = ::CreateWindowEx(cs.dwExStyle, cs.lpszClass,
   cs.lpszName, cs.style, cs.x, cs.y, cs.cx, cs.cy,
   cs.hwndParent, cs.hMenu, cs.hInstance, cs.lpCreateParams);
        ...//
       
        return TRUE;
 }

 BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
 {
 if( !CMDIFrameWnd::PreCreateWindow(cs) )
  return FALSE;
 // TODO: ÔÚ´Ë´¦Í¨¹ýÐÞ¸Ä CREATESTRUCT cs À´Ð޸Ĵ°¿ÚÀà»ò
 // Ñùʽ
        cs.dwExStyle=~WS_EX_CLIENTEDGE;
 return TRUE;
 }

 BOOL CMDIFrameWnd::PreCreateWindow(CREATESTRUCT& cs)
 {
 if (cs.lpszClass == NULL)
 {
  VERIFY(AfxDeferRegisterClass(AFX_WNDMDIFRAME_REG));
  cs.lpszClass = _afxWndMDIFrame;
 }
 return TRUE;
 }
   CWnd::CreateExµ÷ÓÃÁËCMainFrame::PreCreateWindow£¬µ«´Ë´ÎAfxDeferRegisterClass½«²»»á±»µ÷Óá£Ò²¾ÍÊÇÎÒÉÏÃæËù˵µÄ¡°¹ýÃŲ»È롱¡£

    CWnd::CreateExº¯Êý»¹µ÷ÓÃÁËAfxHookWindowCreate(this);ºóÕßÊǸÉʲôµÄÄØ£¿ÆäʵËüÓëÏûÏ¢Ó³ÉäºÍÃüÁî´«µÝÓйأ¬ÎÒ½«ÔÚMFC¼¼ÊõÄÚĻϵÁÐÖ®£¨ËÄ£©--¡¶MFCÏûÏ¢Ó³ÉäÓëÏûÏ¢´«µÝÄÚÄ»¡·Ò»ÎÄÖÐÏê½â¡£
  
   CWnd::CreateExµ÷ÓÃWin32API ::CreateWindowExº¯Êý£¨´«Í³µÄWin32API³ÌÐòÔ±Ò»¶¨²»Ä°ÉúÕâ¸öº¯Êý£©£¬
¾ÍÕâÑùÖ÷¿ò¼Ü´°¿Ú´´½¨½áÊø¡£

                       //////////////////////////////////////////////
                       /*     5.±ê×¼Íâ¿ÇÃüÁî½âÎö      */
                       ///////////////////////////////////////////////
    MFCÏòµ¼ÖÆ×÷µÄ±ê×¼MDIÓ¦ÓóÌÐòÆô¶¯Ê±£¬Ó¦ÓóÌÐò»á×Ô¶¯Æô¶¯Ò»¸ö×Ó´°¿Ú¿ò¼Ü£¨Êµ¼ÊÉÏÊÇÒ»Ì×ÎĵµÄ£°å£©£¬ÕâÊÇΪºÎÄØ£¿ÏÂÃæÎÒ½«Ïêϸ½²½âÒ»ÏÂÕâ¸ö´´½¨¹ý³Ì.
    ÆäʵÕâÒ»¹ý³ÌÒ²ÊÇÔÚCMyWinApp::InitInstance()º¯ÊýÖÐÍê³ÉµÄ£¬¿´¿´ÏÂÃæ´úÂ룺

        CCommandLineInfo cmdInfo;
 ParseCommandLine(cmdInfo);
        if (!ProcessShellCommand(cmdInfo))
  return FALSE;
   º¯ÊýÊ×ÏÈʵÀý»¯Ò»¸öCCommandLineInfoÀà¶ÔÏócmdInfo£¬ÈÃÎÒÃÇ¿´¿´CCommandLineInfoÊǸöʲô¶«¶«? 
 //in afxwin.h
 class CCommandLineInfo : public CObject//²¿·ÖÔ´´úÂë
{
 public:
 // Sets default values
 CCommandLineInfo();
        ...//
 BOOL m_bShowSplash;
 BOOL m_bRunEmbedded;
 BOOL m_bRunAutomated;
 enum { FileNew, FileOpen, FilePrint, FilePrintTo, FileDDE, AppRegister,
  AppUnregister, FileNothing = -1 } m_nShellCommand;

 // not valid for FileNew
 CString m_strFileName;

 // valid only for FilePrintTo
 CString m_strPrinterName;
 CString m_strDriverName;
 CString m_strPortName;

 ~CCommandLineInfo();
        // Implementation
        ...//
 };

 ÔÙÈÃÎÒÃÇÀ´¿´¿´ËüµÄ¹¹Ô캯ÊýµÄʵÏÖ£º

//in appcore.cpp
 CCommandLineInfo::CCommandLineInfo()
 {
 m_bShowSplash = TRUE;
 m_bRunEmbedded = FALSE;
 m_bRunAutomated = FALSE;
 m_nShellCommand = FileNew;
 }
 m_nShellCommand = FileNew;ÕâÒ»¾ä¶ÔÎÒÃÇ×îÖØÒª£»ÖÁÓÚCWinApp::ParseCommandLineÎÒÏëÓÃMFCÎĵµÖеÄÒ»¾ä»°À´½âÊÍ£º
   Call this member function to parse the command line and send the parameters, one at a time, to CCommandLineInfo::ParseParam.
   ÏÂÃæÎÒÃÇÀ´¿´¿´Íâ¿ÇÃüÁî½âÎöµÄÖ÷½Ç£ºCWinApp::ProcessShellCommand
//in appui2.cpp
//DDE and ShellExecute support

BOOL CWinApp::ProcessShellCommand(CCommandLineInfo& rCmdInfo)//²¿·ÖÔ´´úÂë
{
 BOOL bResult = TRUE;
 switch (rCmdInfo.m_nShellCommand)
 {
 case CCommandLineInfo::FileNew:
  if (!AfxGetApp()->OnCmdMsg(ID_FILE_NEW, 0, NULL, NULL))
   OnFileNew();
  if (m_pMainWnd == NULL)
   bResult = FALSE;
  break;

  // If we've been asked to open a file, call OpenDocumentFile()

 case CCommandLineInfo::FileOpen:
  if (!OpenDocumentFile(rCmdInfo.m_strFileName))
   bResult = FALSE;
  break;
        case CCommandLineInfo::FilePrintTo:
 case CCommandLineInfo::FilePrint:
  ...//
        case CCommandLineInfo::FileDDE:
  ...//
 case CCommandLineInfo::AppRegister:
  ...//
        case CCommandLineInfo::AppUnregister:
  ...//
         }
 return bResult;
}
   ÍÚ¾òÔ´´úÂëµÄÈ·ÊÇÁ˽âMFCÔËÐÐÄÚÄ»µÄ×îºÃÊֶΣ¬´ó¼ÒÒ»¿´Ô´´úÂë±ãÖªµÀÈçÖ®ºÎÁË¡£CCommandLineInfo¹¹Ô캯ÊýÖÐm_nShellCommand = FileNew;ËùÒÔÔÚProcessShellCommandÖжÔÓ¦µÄ´úÂë×ÔÈ»¾ÍһĿÁËÈ»ÁË£ºCWinApp::OnFileNew()±»µ÷ÓÃÁË¡£

                       //////////////////////////////////////////////////
                       /*   6.Ò»Ì×Îĵµ/ÊÓͼ¼´½«µ®Éú   */
                       //////////////////////////////////////////////////
    ÉÏÎÄ˵CWinApp::OnFileNew()±»µ÷ÓÃÁË£¬ÄÇô¾ÍÈÃÎÒÀ´¿´¿´Æä´úÂë°É£¡
 //in appdlg.cpp
 void CWinApp::OnFileNew()
 {
    if (m_pDocManager != NULL)
 m_pDocManager->OnFileNew();
 }
  //in docmgr.cpp
void CDocManager::OnFileNew()//²¿·ÖÔ´´úÂë
{
 ...//
       CDocTemplate* pTemplate = (CDocTemplate*)m_templateList.GetHead();
 if (m_templateList.GetCount() > 1)
 {
  // more than one document template to choose from
  // bring up dialog prompting user
  CNewTypeDlg dlg(&m_templateList);
  INT_PTR nID = dlg.DoModal();
  if (nID == IDOK)
   pTemplate = dlg.m_pSelectedTemplate;
  else
   return;     // none - cancel operation
 }

 ASSERT(pTemplate != NULL);
 ASSERT_KINDOF(CDocTemplate, pTemplate);
        pTemplate->OpenDocumentFile(NULL);
  // if returns NULL, the user has already been alerted
}
 //in docmulti.cpp
CDocument* CMultiDocTemplate::OpenDocumentFile(LPCTSTR lpszPathName,
 BOOL bMakeVisible)//²¿·ÖÔ´´úÂë
{
 CDocument* pDocument = CreateNewDocument();
 ...//
        BOOL bAutoDelete = pDocument->m_bAutoDelete;
 pDocument->m_bAutoDelete = FALSE;   // don't destroy if something goes wrong
 CFrameWnd* pFrame = CreateNewFrame(pDocument, NULL);
 pDocument->m_bAutoDelete = bAutoDelete;
 ...//

 if (lpszPathName == NULL)
 {
  // create a new document - with default document name
  SetDefaultTitle(pDocument);

  // avoid creating temporary compound file when starting up invisible
  if (!bMakeVisible)
   pDocument->m_bEmbedded = TRUE;

  if (!pDocument->OnNewDocument())
  {
   // user has be alerted to what failed in OnNewDocument
   TRACE(traceAppMsg, 0, "CDocument::OnNewDocument returned FALSE. ");
   pFrame->DestroyWindow();
   return NULL;
  }

  // it worked, now bump untitled count
  m_nUntitledCount++;
 }
 else
 {
  // open an existing document
  CWaitCursor wait;
  if (!pDocument->OnOpenDocument(lpszPathName))
  {
   // user has be alerted to what failed in OnOpenDocument
   TRACE(traceAppMsg, 0, "CDocument::OnOpenDocument returned FALSE. ");
   pFrame->DestroyWindow();
   return NULL;
  }
  pDocument->SetPathName(lpszPathName);
 }

 InitialUpdateFrame(pFrame, pDocument, bMakeVisible);
 return pDocument;
}
                       //////////////////////////////////////////////
                       /*     6.1.×ÓÎĵµ¶¯Ì¬Éú³É      */
                       //////////////////////////////////////////////
   CMultiDocTemplate::OpenDocumentFileµ÷ÓÃÁËCreateNewDocument()£¬Õâ¾ÍÊÇ×ÓÎĵµ¶¯Ì¬Éú³ÉµÄÖ÷º¯Êý¡£
  //in doctempl.cpp
 CDocument* CDocTemplate::CreateNewDocument()//²¿·ÖÔ´´úÂë
 {
 // default implementation constructs one from CRuntimeClass
 ...//
 CDocument* pDocument = (CDocument*)m_pDocClass->CreateObject();
 ...//
 AddDocument(pDocument);//½«¶¯Ì¬Éú³ÉµÄÎĵµ¶ÔÏóµÄÖ¸Õë¼ÓÈëµ½Ó¦ÓóÌÐòµÄÎĵµÁбíÖÐ
 return pDocument;
 }
  CDocument* pDocument = (CDocument*)m_pDocClass->CreateObject()£»ÕâÒ»¾ä¾ÍÊǶ¯Ì¬²úÉúµÄºËÐÄ£¬Ëü½èÖúÓÚCRuntimeClass¶¯Ì¬Éú³ÉÒ»¸öCDocument¶ÔÏó¡£Æä¶¯Ì¬Éú³ÉµÄ°ÂÃØÎÒ½«ÔÚMFC¼¼ÊõÄÚĻϵÁÐÖ®£¨Èý£©---
¡¶MFCÖ´ÐÐÆÚÀàÐÍʶ±ðÓ붯̬´´½¨¼¼ÊõÄÚÄ»¡·Ò»ÎÄÖÐÏê½â¡£

                       //////////////////////////////////////////////////
                       /*   6.2.×Ó´°¿Ú¿ò¼Ü¶¯Ì¬Éú³É    */
                       /////////////////////////////////////////////////
  CMultiDocTemplate::OpenDocumentFileµ÷ÓÃÁËCreateNewFrame£¬Õâ¾ÍÊÇ×Ó´°¿Ú¿ò¼Ü¶¯Ì¬Éú³ÉµÄÖ÷º¯Êý¡£

 // Default frame creation
 CFrameWnd* CDocTemplate::CreateNewFrame(CDocument* pDoc, CFrameWnd* pOther)//²¿·ÖÔ´´úÂë
 {
 if (pDoc != NULL)
  ASSERT_VALID(pDoc);
 // create a frame wired to the specified document

 ASSERT(m_nIDResource != 0); // must have a resource ID to load from
 CCreateContext context;
 context.m_pCurrentFrame = pOther;
 context.m_pCurrentDoc = pDoc;
 context.m_pNewViewClass = m_pViewClass;
 context.m_pNewDocTemplate = this;
        ...//
 CFrameWnd* pFrame = (CFrameWnd*)m_pFrameClass->CreateObject();
 if (pFrame == NULL)
 {
  TRACE(traceAppMsg, 0, "Warning: Dynamic create of frame %hs failed. ",
   m_pFrameClass->m_lpszClassName);
  return NULL;
 }
 ASSERT_KINDOF(CFrameWnd, pFrame);
        ...//
 
 // create new from resource
 if (!pFrame->LoadFrame(m_nIDResource,
   WS_OVERLAPPEDWINDOW | FWS_ADDTOTITLE,   // default frame styles
   NULL, &context))
 {
  TRACE(traceAppMsg, 0, "Warning: CDocTemplate couldn't create a frame. ");
  // frame will be deleted in PostNcDestroy cleanup
  return NULL;
 }

 // it worked !
 return pFrame;
}
   CFrameWnd* pFrame = (CFrameWnd*)m_pFrameClass->CreateObject();ÕâÒ»¾ä¾ÍÊǶ¯Ì¬²úÉúµÄºËÐÄ£¬Ëü½èÖúÓÚCRuntimeClass¶¯Ì¬Éú³ÉÒ»¸öCDocument¶ÔÏó¡£Æä¶¯Ì¬Éú³ÉµÄ°ÂÃØÎÒ½«ÔÚMFC¼¼ÊõÄÚĻϵÁÐÖ®£¨Èý£©---
¡¶MFCÖ´ÐÐÆÚÀàÐÍʶ±ðÓ붯̬´´½¨¼¼ÊõÄÚÄ»¡·Ò»ÎÄÖÐÏê½â¡£Ö®ºóº¯Êýµ÷ÓÃLoadFrameÀ´´´½¨×Ó´°¿Ú¡£Æä¹ý³ÌÓë´´½¨Ö÷¿ò¼Ü´°¿ÚµÄ¹ý³Ì´óÖÂÏàͬ£¬µ«Ò²ÓÐһЩ²»Í¬µÄµØ·½£¬ÏÂÃæÎҾͽ«ËµËµÕâµã²»Í¬¡£

                       //////////////////////////////////////////////
                       /*     6.3.×ÓÊÓͼ¶¯Ì¬Éú³É      */
                       //////////////////////////////////////////////
   µÉ´óÑÛ¾¦×Ðϸ²ì¿´OpenDocumentFileµÄÔ´´úÂ룬ÒÉ»óÁË,"ÔõôûÓÐÀàËÆCView* pView =CreateNewView();
µÄ´úÂë?","ÄÇô×ÓÊÓͼÊÇÈçºÎÉú³ÉµÄÄØ"ÏÂÃæÎÒ¾ÍΪÄãÏêϸ½âÊÍһϰɣ¡Æäʵ×ÓÊÓͼ¶¯Ì¬Éú³Éº¯Êý±»·Åµ½ÁíÒ»¸öµØ·½ÁË¡£ÈÃÎÒÃÇÏêϸÀ´¿´¿´°É¡£
   Æäʵ£¬¹Ø¼ü»¹ÊÇÔÚLoadFrame£¬µ«Óë´´½¨Ö÷´°¿Ú¿ò¼ÜµÄÄǸöLoadFrame²»Í¬µÄÊÇ´«½øÁËÒ»¸ö²»Í¬µÄ²ÎÊý
&context£¬Äã»Ø¹ýÍ·¿´¿´Ö÷´°¿Ú¿ò¼ÜµÄÄǸöLoadFrame£¬µ÷ÓÃËüʱʹÓÃÁËĬÈϲÎÊý£¬¶øÄǸöĬÈϲÎÊýֵΪNULL,
ÏÂÃæ¿´¿´CCreateContext ½á¹¹¡£
//in afxext.h
struct CCreateContext   // Creation information structure
 // All fields are optional and may be NULL
{
 // for creating new views
 CRuntimeClass* m_pNewViewClass; // runtime class of view to create or NULL
 CDocument* m_pCurrentDoc;

 // for creating MDI children (CMDIChildWnd::LoadFrame)
 CDocTemplate* m_pNewDocTemplate;

 // for sharing view/frame state from the original view/frame
 CView* m_pLastView;
 CFrameWnd* m_pCurrentFrame;
// Implementation
 CCreateContext();
};
  ¶øÔÚCDocTemplate::CreateNewFrameÖгõʼ»¯Á˸ýṹÈçÏ£º
      CCreateContext context;
 context.m_pCurrentFrame = pOther;
 context.m_pCurrentDoc = pDoc;
 context.m_pNewViewClass = m_pViewClass;
 context.m_pNewDocTemplate = this;
       context.m_pNewViewClass = m_pViewClass;//¹Ø¼üµÄ³ÉÔ±
  ÏÂÃæ¿´¿´Õâ¸ö´´½¨µÄ¾ßÌå¹ý³Ì£º
      LoadFrame(...,&context)-->CFrameWnd::Create(...,&context)--> CWnd::CreateEx(...,&context)
-->::CreateWindowEx
     ::CreateWindowEx APIº¯Êý½«²úÉúWM_CREATEÏûÏ¢£¬²¢½«&context´«µÝÖ®,CMainFrame::OnCreate½«ÏìÓ¦ÏûÏ¢,²¢ÒýÆðһϵÁеĺ¯Êýµ÷Ó㬿´ÏÂÃæ:
//in mainfrm.cpp
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
 if (CMDIFrameWnd::OnCreate(lpCreateStruct) == -1)
  return -1;
 ...//
 return 0;
}
// in winfrm.cpp
int CFrameWnd::OnCreate(LPCREATESTRUCT lpcs)
{
 CCreateContext* pContext = (CCreateContext*)lpcs->lpCreateParams;
 return OnCreateHelper(lpcs, pContext);
}
// in winfrm.cpp
int CFrameWnd::OnCreateHelper(LPCREATESTRUCT lpcs, CCreateContext* pContext)//²¿·ÖÔ´´úÂë
{
 if (CWnd::OnCreate(lpcs) == -1)
  return -1;

 // create special children first
 if (!OnCreateClient(lpcs, pContext))
 {
  TRACE(traceAppMsg, 0, "Failed to create client pane/view for frame. ");
  return -1;
 }

 ...//
        return 0;   // create ok
}
// in winfrm.cpp
BOOL CFrameWnd::OnCreateClient(LPCREATESTRUCT, CCreateContext* pContext)
{
 // default create client will create a view if asked for it
 if (pContext != NULL && pContext->m_pNewViewClass != NULL)
 {
  if (CreateView(pContext, AFX_IDW_PANE_FIRST) == NULL)
   return FALSE;
 }
 return TRUE;
}
// in winfrm.cpp
CWnd* CFrameWnd::CreateView(CCreateContext* pContext, UINT nID)//²¿·ÖÔ´´úÂë
{
 ...//

 // Note: can be a CWnd with PostNcDestroy self cleanup
 CWnd* pView = (CWnd*)pContext->m_pNewViewClass->CreateObject();
 if (pView == NULL)
 {
  TRACE(traceAppMsg, 0, "Warning: Dynamic create of view type %hs failed. ",
   pContext->m_pNewViewClass->m_lpszClassName);
  return NULL;
 }
 ASSERT_KINDOF(CWnd, pView);

 // views are always created with a border!
 if (!pView->Create(NULL, NULL, AFX_WS_DEFAULT_VIEW,
  CRect(0,0,0,0), this, nID, pContext))
 {
  TRACE(traceAppMsg, 0, "Warning: could not create view for frame. ");
  return NULL;        // can't continue without a view
 }

 ...//
 return pView;
}
  CWnd* pView = (CWnd*)pContext->m_pNewViewClass->CreateObject();ºËÐĺ¯ÊýÖÕÓÚ³öÏÖÁË¡£×ÓÊÓͼ¶¯Ì¬Éú³ÉÍê±Ï¡£

                       /////////////////////////////////////////
                       /*         7.ÊÕβ¹¤×÷          */
                       /////////////////////////////////////////
   ÖÁ´Ë£¬Ò»Ì×ÍêÕûµÄDocument/ChildFrame/View½á¹¹Éú³É,´Ë¡°Èý¿Ú×顱¹²ÊôͬһÌ×ÎĵµÄ£°å£¬Èç¹ûÄãÒª¶¨ÒåÁíÒ»Ìײ»Í¬µÄÎĵµÄ£µµÐèÔÙ¶¨ÒåÁíÒ»×鲻ͬ¡°Èý¿Ú×顱£¨ChildFrame¿ÉÒÔʹÓÃÏàͬµÄ£©¡£²¢µ÷ÓÃAddDocTemplate½«¸ÃÎĵµÄ£°å¼ÓÈëµ½Ó¦ÓóÌÐòµÄÎĵµÄ£°åÁÐ±í¡£±ÈÈ磺

       CMultiDocTemplate* pOtherDocTemplate;
 pOtherDocTemplate = new CMultiDocTemplate(IDR_MyOtherTYPE,
  RUNTIME_CLASS(CMyOtherDoc),
  RUNTIME_CLASS(CChildFrame), // ×Ô¶¨Òå MDI ×Ó¿ò¼Ü
  RUNTIME_CLASS(CMyOtherView));
 AddDocTemplate(pOtherDocTemplate);

¡°Èý¿Ú×顱Éú³Éºó³ÌÐòµ÷ÓÃShowWindow£¬UpdateWindow½«Ó¦ÓóÌÐòµÄÖ÷´°¿ÚÕ¹ÏÖÔÚÄãÑÛǰ¡£

  ×¢ÊÍ:µ±ÄãÔÚFile²Ëµ¥ÖÐÑ¡Ôñnew»òÔÚ¹¤¾ßÀ¸Öе¥»÷¡°Ð½¨¡±Ê±£¬Ó¦ÓóÌÐò½«Ñ¡Ôñµ±Ç°Ä¬ÈϵÄÎĵµÄ£°å²¢ÒÔËüΪ»ù´¡¶¯Ì¬Éú³É Document/ChildFrame/View¡°Èý¿Ú×顱£¬ÆäÉú³É¹ý³ÌÓëÎÒÉÏÊö½²µÄÒ»°ã²»¶þ¡£
                       ////////////////////////////////////////
                       /*       8. "ϼ¯Ô¤¸æ"        */
                       ////////////////////////////////////////

   MFC¼¼ÊõÄÚĻϵÁÐÖ®£¨Èý£©---¡¶MFCÖ´ÐÐÆÚÀàÐÍʶ±ðÓ붯̬´´½¨¼¼ÊõÄÚÄ»¡·

·¢±íÓÚ£º 2005-11-10£¬ÐÞ¸ÄÓÚ£º 2005-11-10 09:03£¬ÒÑä¯ÀÀ549´Î£¬ÓÐÆÀÂÛ0Ìõ ÍÆ¼ö ͶËß

¸øÎÒÁôÑÔ
°æÈ¨ËùÓÐ ChinaUnix.net Ò³ÃæÉú³Éʱ¼ä£º0.01938