MFC 框架、文档、视图操作常用函数用法简析

MFC 框架、文档、视图操作常用函数用法简析

1.     跟窗口刷新有关的几个MFC函数

//重绘窗口

1)               RecalcLayout();

       /*RecalcLayout()--

       The default implementation of this member function

       calls the CWnd member function RepositionBars to reposition all the

       control bars in the frame as well as in the main client window

       (usually a CView or MDICLIENT).

       */

2)               Invalidate();

       /*Invalidate()--

       Invalidates the entire client area of CWnd.

       */

3)               UpdateWindow();

       /*UpdateWindow()--

       The UpdateWindow member function sends a WM_PAINT message directly,

       bypassing the application queue. If the update region is empty, WM_PAINT

       is not sent.

       */

       对话框数据交换函数UpdateData(FALSE/TRUE)

4)           UpdateData()

/*

BOOL UpdateData(BOOL bSaveAndValidate = TRUE );

Parameters

bSaveAndValidate

Flag that indicates whether dialog box is being initialized (FALSE) or data is being retrieved (TRUE).

Return Value

Nonzero if the operation is successful; otherwise 0. If bSaveAndValidate is TRUE, then a return value of nonzero means that the data is successfully validated.

*/

2.     跟文档Document操作相关的几个MFC函数

1)        BOOL CNetGenixDoc::OnNewDocument()

{

       if (!CDocument::OnNewDocument())

              return FALSE;

       /*具体的MFC CDocument::OnNewDocument()实现

       BOOL CDocument::OnNewDocument()

       {

       if (IsModified())

       TRACE0("Warning: OnNewDocument replaces an unsaved document./n");

      

         DeleteContents();

         m_strPathName.Empty();      // no path name yet

         SetModifiedFlag(FALSE);     // make clean

        

              return TRUE;

              }

       */

       // TODO: add reinitialization code here

       // (SDI documents will reuse this document)

 

       return TRUE;

}

 

2)        BOOL CNetGenixDoc::OnOpenDocument(LPCTSTR lpszPathName)

{

if (!CDocument::OnOpenDocument(lpszPathName))

        return FALSE;

/* 具体的MFC CDocuemnt::OnOpenDocument()实现

BOOL CDocument::OnOpenDocument(LPCTSTR lpszPathName)

{

if (IsModified())

TRACE0("Warning: OnOpenDocument replaces an unsaved document./n");

  CFileException fe;

  CFile* pFile = GetFile(lpszPathName,

  CFile::modeRead|CFile::shareDenyWrite, &fe);

  if (pFile == NULL)

  {

  ReportSaveLoadException(lpszPathName, &fe,

  FALSE, AFX_IDP_FAILED_TO_OPEN_DOC);

  return FALSE;

  }

 

        DeleteContents();

        SetModifiedFlag();  // dirty during de-serialize

       

          CArchive loadArchive(pFile, CArchive::load | CArchive::bNoFlushOnDelete);

          loadArchive.m_pDocument = this;

          loadArchive.m_bForceFlat = FALSE;

          TRY

          {

          CWaitCursor wait;

          if (pFile->GetLength() != 0)

          Serialize(loadArchive);     // load me

          loadArchive.Close();

          ReleaseFile(pFile, FALSE);

          }

          CATCH_ALL(e)

          {

          ReleaseFile(pFile, TRUE);

          DeleteContents();   // remove failed contents

         

               TRY

               {

               ReportSaveLoadException(lpszPathName, e,

               FALSE, AFX_IDP_FAILED_TO_OPEN_DOC);

               }

               END_TRY

               DELETE_EXCEPTION(e);

               return FALSE;

               }

               END_CATCH_ALL

              

                 SetModifiedFlag(FALSE);     // start off with unmodified

                

                      return TRUE;

                      }

*/

// TODO: Add your specialized creation code here

return TRUE;

}

 

3)        BOOL CNetGenixDoc::OnSaveDocument(LPCTSTR lpszPathName)

{

       // TODO: Add your specialized code here and/or call the base class

       /*具体的MFC CDocument::OnSaveDocument()实现

       BOOL CDocument::OnSaveDocument(LPCTSTR lpszPathName)

       {

       CFileException fe;

       CFile* pFile = NULL;

       pFile = GetFile(lpszPathName, CFile::modeCreate |

       CFile::modeReadWrite | CFile::shareExclusive, &fe);

      

         if (pFile == NULL)

         {

         ReportSaveLoadException(lpszPathName, &fe,

         TRUE, AFX_IDP_INVALID_FILENAME);

         return FALSE;

         }

        

              CArchive saveArchive(pFile, CArchive::store | CArchive::bNoFlushOnDelete);

              saveArchive.m_pDocument = this;

              saveArchive.m_bForceFlat = FALSE;

              TRY

              {

              CWaitCursor wait;

              Serialize(saveArchive);     // save me

              saveArchive.Close();

              ReleaseFile(pFile, FALSE);

              }

              CATCH_ALL(e)

              {

              ReleaseFile(pFile, TRUE);

             

                TRY

                {

                ReportSaveLoadException(lpszPathName, e,

                TRUE, AFX_IDP_FAILED_TO_SAVE_DOC);

                }

                END_TRY

                DELETE_EXCEPTION(e);

                return FALSE;

                }

                END_CATCH_ALL

               

                     SetModifiedFlag(FALSE);     // back to unmodified

                    

                       return TRUE;        // success

                       }

       */   

       return CDocument::OnSaveDocument(lpszPathName);

}

 

4)        void CNetGenixDoc::OnCloseDocument()

{

       /*

       void CDocument::OnCloseDocument()

       // must close all views now (no prompting) - usually destroys this

       {

       // destroy all frames viewing this document

       // the last destroy may destroy us

       BOOL bAutoDelete = m_bAutoDelete;

       m_bAutoDelete = FALSE;  // don't destroy document while closing views

       while (!m_viewList.IsEmpty())

       {

       // get frame attached to the view

       CView* pView = (CView*)m_viewList.GetHead();

       ASSERT_VALID(pView);

       CFrameWnd* pFrame = pView->GetParentFrame();

       ASSERT_VALID(pFrame);

      

         // and close it

         PreCloseFrame(pFrame);

         pFrame->DestroyWindow();

         // will destroy the view as well

         }

         m_bAutoDelete = bAutoDelete;

        

              // clean up contents of document before destroying the document itself

              DeleteContents();

             

                // delete the document if necessary

                if (m_bAutoDelete)

                delete this;

       }

       */

       // TODO: Add your specialized code here and/or call the base class

      

       CDocument::OnCloseDocument();

}

 

3.     MDI每一文档多视图的实现方式之CCreateContext

1)        我查找很多MDI多视图的例子,总结写出下面这个函数以实现MDI架构下一个文档的多个视图创建:
版本1int CMainFrame::CreateNewView()//可以对CxChildFrame/CxView再进行抽象出来作为形式参数出现
{
    CMyHtmlChildFrame* pHtmlChild=new CMyHtmlChildFrame();//use CRuntimeClass* is also OK
    
    CMDIDemoDoc* pDoc=(CMDIDemoDoc*)(MDIGetActive()- >GetActiveDocument());
    ASSERT_VALID(pDoc);

    CMultiDocTemplate* pTemplate=(CMultiDocTemplate*)(pDoc- >GetDocTemplate());
    ASSERT_VALID(pTemplate);
    
    CCreateContext context;
    context.m_pCurrentDoc=pDoc;// use existing document
    context.m_pCurrentFrame=pHtmlChild;// new child frame to be upon
    context.m_pNewViewClass=RUNTIME_CLASS(CMyHtmlView);// new view to be created
    context.m_pNewDocTemplate=pTemplate;// use existing document
    context.m_pLastView=NULL;// no 

    if (!pHtmlChild- >LoadFrame(IDI_ICON1,WS_OVERLAPPEDWINDOW ¦FWS_ADDTOTITLE,this,&context)) 
    {
        TRACE0("Warning: Couldn 't load frame window!/n");
        return -1;
    }
    //pHtmlChild- >ShowWindow(SW_SHOWMAXIMIZED);
    pHtmlChild- >InitialUpdateFrame(pDoc,TRUE);
    //pTemplate- >InitialUpdateFrame(pHtmlChild,pDoc,TRUE);

    //it worked!
    return 0;
}

void CMainFrame::OnCreateView() 
{
    // TODO: Add your command handler code here
    CreateNewView();
}

 

2)        版本2int CMainFrame::CreateNewView(UINT nIDResource,CRuntimeClass* pFrameClass,CRuntimeClass* pViewClass,CDocument* pDoc)

{

       /***********************************************************

       * 函数名: CreateNewView

       * 参数: UINT nIDResource,CRuntimeClass* pFrameClass,CRuntimeClass* pViewClass,CDocument* pDoc

       * 功能描述:

       * 1. 根据框架/视图/文档动态创建视图

       * 2. 利用CCreateContext context关联文档/视图

       * 3. 可以再进一步的抽象参数为CCreateContext* pContext

       * 4. 具体可以参考CMDIChildWnd* CMDIFrameWnd::CreateNewChild()进行进一步的改写

       * 返回值:

       * 作者:

       * 日期:

       * 注释:

       * 日志:

       * 1.

       * 2.

       * 3.

       ***********************************************************/

      

       //1 CMyHtmlChildFrame* pHtmlChild=new CMyHtmlChildFrame();

       //use CRuntimeClass is also OK

       //1 CMyHtmlChildFrame* pHtmlChild=(CMyHtmlChildFrame*)pFrameClass->CreateObject();

       CMDIChildWnd* pFrame=(CMDIChildWnd*)pFrameClass->CreateObject();

       ASSERT_KINDOF(CMDIChildWnd, pFrame);

       //1 CMDIDemoDoc* pDoc=(CMDIDemoDoc*)(MDIGetActive()->GetActiveDocument());

       ASSERT_VALID(pDoc);

      

       //1 CMultiDocTemplate* pTemplate=(CMultiDocTemplate*)(pDoc->GetDocTemplate());

       CDocTemplate* pTemplate=pDoc->GetDocTemplate();

       //ASSERT_VALID(pTemplate);

      

       CCreateContext context;

       context.m_pCurrentDoc=pDoc;// use existing document

       context.m_pCurrentFrame=pFrame;// new child frame to be upon

       context.m_pNewViewClass=pViewClass;// RUNTIME_CLASS(CMyHtmlView);// new view to be created

       context.m_pNewDocTemplate=pTemplate;// use existing document template

       context.m_pLastView=NULL;// no

       TRACE0("Before LoadFrame()/n");

       if (!pFrame->LoadFrame(nIDResource,WS_OVERLAPPEDWINDOW|FWS_ADDTOTITLE,AfxGetMainWnd()/*this*/,&context))

       {

              TRACE0("Warning: Couldn't load frame window!/n");

              return -1;

       }

       TRACE0("After LoadFrame()/n");

       //pHtmlChild->ShowWindow(SW_SHOWNORMAL);

       pFrame->InitialUpdateFrame(pDoc,TRUE);

       //pHtmlChild->InitialUpdateFrame(pDoc,TRUE);

      

       //just delagate to implementation in CFrameWnd

       //pTemplate->InitialUpdateFrame(pHtmlChild,pDoc,TRUE);

      

       //it worked!

       return 0;

}

 

void CMainFrame::OnCreateNewView()

{

       // TODO: Add your command handler code here

       CDocument* pDoc=MDIGetActive()->GetActiveDocument();

       ASSERT_VALID(pDoc);

       //create html view

       CreateNewView(IDI_ICON1,RUNTIME_CLASS(CMyHtmlChildFrame),RUNTIME_CLASS(CMyHtmlView),pDoc);

       //create tree view

       //CreateNewView(IDI_ICON2,RUNTIME_CLASS(CMyTreeChildFrame),RUNTIME_CLASS(CMyTreeView),pDoc);

}

 

4.     MFC MDI框架视图的创建参考LoadFrame()

1)        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;

}

 

2)        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)

              TRACE0("Warning: CMDIFrameWnd without a default menu./n");

       return TRUE;

}

 

3)        BOOL CMDIChildWnd::LoadFrame(UINT nIDResource, DWORD dwDefaultStyle, CWnd* pParentWnd, CCreateContext* pContext)

{

       // only do this once

       ASSERT_VALID_IDR(nIDResource);

       ASSERT(m_nIDHelp == 0 || m_nIDHelp == nIDResource);

       ASSERT(m_hMenuShared == NULL);      // only do once

 

       m_nIDHelp = nIDResource;    // ID for help context (+HID_BASE_RESOURCE)

 

       // parent must be MDI Frame (or NULL for default)

       ASSERT(pParentWnd == NULL || pParentWnd->IsKindOf(RUNTIME_CLASS(CMDIFrameWnd)));

       // will be a child of MDIClient

       ASSERT(!(dwDefaultStyle & WS_POPUP));

       dwDefaultStyle |= WS_CHILD;

 

       // if available - get MDI child menus from doc template

       ASSERT(m_hMenuShared == NULL);      // only do once

       CMultiDocTemplate* pTemplate;

       if (pContext != NULL &&

              (pTemplate = (CMultiDocTemplate*)pContext->m_pNewDocTemplate) != NULL)

       {

              ASSERT_KINDOF(CMultiDocTemplate, pTemplate);

              // get shared menu from doc template

              m_hMenuShared = pTemplate->m_hMenuShared;

              m_hAccelTable = pTemplate->m_hAccelTable;

       }

       else

       {

              TRACE0("Warning: no shared menu/acceltable for MDI Child window./n");

                     // if this happens, programmer must load these manually

       }

 

       CString strFullString, strTitle;

       if (strFullString.LoadString(nIDResource))

              AfxExtractSubString(strTitle, strFullString, 0);    // first sub-string

 

       ASSERT(m_hWnd == NULL);

       if (!Create(GetIconWndClass(dwDefaultStyle, nIDResource),

         strTitle, dwDefaultStyle, rectDefault,

         (CMDIFrameWnd*)pParentWnd, pContext))

       {

              return FALSE;   // will self destruct on failure normally

       }

 

       // it worked !

       return TRUE;

}

 

4)        CMDIChildWnd* CMDIFrameWnd::CreateNewChild(CRuntimeClass* pClass, UINT nResources, HMENU hMenu /* = NULL */, HACCEL hAccel /* = NULL */)

{

       ASSERT(pClass != NULL);

       CMDIChildWnd* pFrame = (CMDIChildWnd*) pClass->CreateObject();

       ASSERT_KINDOF(CMDIChildWnd, pFrame);

 

       // load the frame

       CCreateContext context;

       context.m_pCurrentFrame = this;

 

       if (!pFrame->LoadFrame(nResources,

                     WS_OVERLAPPEDWINDOW | FWS_ADDTOTITLE, NULL, &context))

       {

              TRACE0("Couldn't load frame window./n");

              delete pFrame;

              return NULL;

       }

 

       CString strFullString, strTitle;

       if (strFullString.LoadString(nResources))

              AfxExtractSubString(strTitle, strFullString, CDocTemplate::docName);

 

       // set the handles and redraw the frame and parent

       pFrame->SetHandles(hMenu, hAccel);

       pFrame->SetTitle(strTitle);

       pFrame->InitialUpdateFrame(NULL, TRUE);

 

       return pFrame;

}

 

5)        void CMDIFrameWnd::OnWindowNew()

{

       CMDIChildWnd* pActiveChild = MDIGetActive();

       CDocument* pDocument;

       if (pActiveChild == NULL ||

         (pDocument = pActiveChild->GetActiveDocument()) == NULL)

       {

              TRACE0("Warning: No active document for WindowNew command./n");

              AfxMessageBox(AFX_IDP_COMMAND_FAILURE);

              return;     // command failed

       }

 

       // otherwise we have a new frame !

       CDocTemplate* pTemplate = pDocument->GetDocTemplate();

       ASSERT_VALID(pTemplate);

       CFrameWnd* pFrame = pTemplate->CreateNewFrame(pDocument, pActiveChild);

       if (pFrame == NULL)

       {

              TRACE0("Warning: failed to create new frame./n");

              return;     // command failed

       }

 

       pTemplate->InitialUpdateFrame(pFrame, pDocument);

}

 

 

 

 

5.     DECLARE_DYNCREATE动态创建宏

注:揭示了CraeteObject()New的联系

1)        DECLARE_DYNCREATE(CMDIDemoView)

/*

#define DECLARE_DYNCREATE(class_name) /

DECLARE_DYNAMIC(class_name) /

static CObject* PASCAL CreateObject();

*/

 

2)        IMPLEMENT_DYNCREATE(CMDIDemoView, CView)

/*

#define IMPLEMENT_DYNCREATE(class_name, base_class_name) /

CObject* PASCAL class_name::CreateObject() /

{ return new class_name; } /

IMPLEMENT_RUNTIMECLASS(class_name, base_class_name, 0xFFFF, /

class_name::CreateObject)

*/

 

6.     MFC Windows消息路由机制OnCmdMsg()

// CFrameWnd command/message routing

 

1)        BOOL CFrameWnd::OnCmdMsg(UINT nID, int nCode, void* pExtra,

       AFX_CMDHANDLERINFO* pHandlerInfo)

{

       CPushRoutingFrame push(this);

 

       // pump through current view FIRST

       CView* pView = GetActiveView();

       if (pView != NULL && pView->OnCmdMsg(nID, nCode, pExtra, pHandlerInfo))

              return TRUE;

 

       // then pump through frame

       if (CWnd::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo))

              return TRUE;

 

       // last but not least, pump through app

       CWinApp* pApp = AfxGetApp();

       if (pApp != NULL && pApp->OnCmdMsg(nID, nCode, pExtra, pHandlerInfo))

              return TRUE;

 

       return FALSE;

}

 

// Command routing

 

2)        BOOL CMDIFrameWnd::OnCmdMsg(UINT nID, int nCode, void* pExtra,

       AFX_CMDHANDLERINFO* pHandlerInfo)

{

       CMDIChildWnd* pActiveChild = MDIGetActive();

       // pump through active child FIRST

       if (pActiveChild != NULL)

       {

              CPushRoutingFrame push(this);

              if (pActiveChild->OnCmdMsg(nID, nCode, pExtra, pHandlerInfo))

                     return TRUE;

       }

 

       // then pump through normal frame

       return CFrameWnd::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo);

}

 

// Command routing

 

3)        BOOL CView::OnCmdMsg(UINT nID, int nCode, void* pExtra,

       AFX_CMDHANDLERINFO* pHandlerInfo)

{

       // first pump through pane

       if (CWnd::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo))

              return TRUE;

 

       // then pump through document

       if (m_pDocument != NULL)

       {

              // special state for saving view before routing to document

              CPushRoutingView push(this);

              return m_pDocument->OnCmdMsg(nID, nCode, pExtra, pHandlerInfo);

       }

 

       return FALSE;

}

 

// command routing

 

4)        BOOL CDocument::OnCmdMsg(UINT nID, int nCode, void* pExtra,

       AFX_CMDHANDLERINFO* pHandlerInfo)

{

       if (CCmdTarget::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo))

              return TRUE;

 

       // otherwise check template

       if (m_pDocTemplate != NULL &&

         m_pDocTemplate->OnCmdMsg(nID, nCode, pExtra, pHandlerInfo))

              return TRUE;

 

       return FALSE;

}

 

5)        BOOL CDocTemplate::OnCmdMsg(UINT nID, int nCode, void* pExtra,

       AFX_CMDHANDLERINFO* pHandlerInfo)

{

       BOOL bReturn;

       CCmdTarget* pFactory = DYNAMIC_DOWNCAST(CCmdTarget, m_pAttachedFactory);

 

       if (nCode == CN_OLE_UNREGISTER && pFactory != NULL)

              bReturn = pFactory->OnCmdMsg(nID, nCode, pExtra, pHandlerInfo);

       else

              bReturn = CCmdTarget::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo);

 

       return bReturn;

}

 
  • 0
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值