2015-12-04 34 views
0

CDockablePane::Serialize()方法是否從MFC Feature Pack核心調用?當MFC(Feature Pack)調用CDockablePane :: Serialize()時?

我有從CDockablePane類繼承的可停靠窗口類。我的課程覆蓋虛擬Serialize()方法並聲明爲系列DECLARE_SERIAL/IMPLEMENT_SERIAL。但MFC不會調用我的Serialize()方法!爲什麼? MSDN sayCDockablePane類有序列化方法:SaveState()LoadState()Serialize()。前兩個(SaveState(),LoadState())分別爲內部使用的Serialize()用於「序列化窗格」。但它不是呼喚!

+1

不,它不是由框架調用。你必須通常從'CDocument :: Serialize'手動調用它。 'LoadState' /'SaveState'用於保存/恢復窗格的位置和狀態。他們確實使用** Registry **作爲存儲。 –

+0

@AndrewKomiagin謝謝。 :(很遺憾,我不明白這個意思是聲明'CDockablePane'類是可序列化的。 – 23W

+0

'DECLARE_SERIAL'和'IMPLEMENT_SERIAL'用於支持'operator >>'和其他'CArchive'特定的東西以及運行時類信息。 –

回答

0

我的答案主張。當此停靠窗格由框架(框架調用方法LoadState()SaveState())創建或存儲時,我的類CSerializableDockablePane執行調用Serialize方法。

您可以使用CSerializableDockablePane作爲可停靠窗格的基類,並根據需要覆蓋虛擬Serialize()方法。

代碼:

class CSerializableDockablePane 
    : public CDockablePane 
{ 
    DECLARE_SERIAL(CSerializableDockablePane) 

public: 
    typedef CDockablePane TBase; 

public: 
    CSerializableDockablePane(); 
    virtual ~CSerializableDockablePane(); 

    virtual BOOL   LoadState(LPCTSTR lpszProfileName = NULL, int nIndex = -1, UINT uiID = (UINT)-1); 
    virtual BOOL   SaveState(LPCTSTR lpszProfileName = NULL, int nIndex = -1, UINT uiID = (UINT)-1); 
    virtual void   Serialize(CArchive& ar); 
}; 



///////////////////////////////////////////////////////////////////////////// 
// CSerializableDockablePane 

#define _MFC_DOCVIEW_PROFILE _T("DockableViews") 
#define _REG_UI_DOCVIEWSECTION_FMT _T("%TsSerializableDockablePane-%d") 
#define _REG_UI_DOCVIEWSECTION_FMT_EX _T("%TsSerializableDockablePane-%d%x") 
#define _REG_UI_SETTINGS _T("Settings") 

IMPLEMENT_SERIAL(CSerializableDockablePane, CSerializableDockablePane::TBase, VERSIONABLE_SCHEMA | 2) 

CSerializableDockablePane::CSerializableDockablePane() 
{ 
} 

CSerializableDockablePane::~CSerializableDockablePane() 
{ 
} 

BOOL CSerializableDockablePane::LoadState(LPCTSTR lpszProfileName /*= NULL*/, int nIndex /*= -1*/, UINT uiID /*= (UINT)-1*/) 
{ 
    BOOL bRes = TBase::LoadState(lpszProfileName, nIndex, uiID); 
    if (bRes) { 

     const CString strProfileName = ::AFXGetRegPath(_MFC_DOCVIEW_PROFILE, lpszProfileName); 
     if (nIndex == -1) { 
      nIndex = GetDlgCtrlID(); 
     } 

     CString strSection; 
     if (uiID == (UINT)-1) { 
      strSection.Format(_REG_UI_DOCVIEWSECTION_FMT, (LPCTSTR)strProfileName, nIndex); 
     } 
     else { 
      strSection.Format(_REG_UI_DOCVIEWSECTION_FMT_EX, (LPCTSTR)strProfileName, nIndex, uiID); 
     } 

     LPBYTE lpbData = nullptr; 
     UINT uiDataSize = 0; 

     CSettingsStoreSP regSP; 
     CSettingsStore& reg = regSP.Create(FALSE, TRUE); 

     if (!reg.Open(strSection)) { 
      return FALSE; 
     } 

     if (!reg.Read(_REG_UI_SETTINGS, &lpbData, &uiDataSize)) { 
      return FALSE; 
     } 

     try 
     { 
      CMemFile file(lpbData, uiDataSize); 
      CArchive ar(&file, CArchive::load); 

      Serialize(ar); 
      bRes = TRUE; 
     } 
     catch (CMemoryException* pEx) 
     { 
      pEx->Delete(); 
      TRACE(_T("Memory exception in CSerializableDockablePane::LoadState()!\n")); 
     } 
     catch (CArchiveException* pEx) 
     { 
      pEx->Delete(); 
      TRACE(_T("CArchiveException exception in CSerializableDockablePane::LoadState()!\n")); 
     } 

     if (lpbData != nullptr) { 
      delete[] lpbData; 
     } 
    } 

    return bRes; 
} 

BOOL CSerializableDockablePane::SaveState(LPCTSTR lpszProfileName /*= NULL*/, int nIndex /*= -1*/, UINT uiID /*= (UINT)-1*/) 
{ 
    BOOL bRes = TBase::SaveState(lpszProfileName, nIndex, uiID); 
    if (bRes) { 

     const CString strProfileName = ::AFXGetRegPath(_MFC_DOCVIEW_PROFILE, lpszProfileName); 
     if (nIndex == -1) { 
      nIndex = GetDlgCtrlID(); 
     } 

     CString strSection; 
     if (uiID == (UINT)-1) { 
      strSection.Format(_REG_UI_DOCVIEWSECTION_FMT, (LPCTSTR)strProfileName, nIndex); 
     } 
     else { 
      strSection.Format(_REG_UI_DOCVIEWSECTION_FMT_EX, (LPCTSTR)strProfileName, nIndex, uiID); 
     } 

     try 
     { 
      CMemFile file; 

      { 
       CArchive ar(&file, CArchive::store); 

       Serialize(ar); 
       ar.Flush(); 
      } 

      UINT uiDataSize = (UINT)file.GetLength(); 
      LPBYTE lpbData = file.Detach(); 

      if (lpbData != NULL) 
      { 
       CSettingsStoreSP regSP; 
       CSettingsStore& reg = regSP.Create(FALSE, FALSE); 

       if (reg.CreateKey(strSection)) { 
        bRes = reg.Write(_REG_UI_SETTINGS, lpbData, uiDataSize); 
       } 

       free(lpbData); 
      } 
     } 
     catch (CMemoryException* pEx) 
     { 
      pEx->Delete(); 
      TRACE(_T("Memory exception in CSerializableDockablePane::SaveState()!\n")); 
     } 
    } 

    return bRes; 
} 

void CSerializableDockablePane::Serialize(CArchive& ar) 
{ 
    TBase::Serialize(ar); 
} 
// CSerializableDockablePane 
///////////////////////////////////////////////////////////////////////////// 
3

不,Serialize()方法不被MFC框架自動調用。您必須通常從CDocument::Serialize()手動調用它。 LoadState()SaveState()方法用於保存/恢復窗格位置和狀態。他們確實使用註冊表作爲存儲。

至於DECLARE_SERIALIMPLEMENT_SERIAL它們被用來支持operator>>CArchive特異性的東西加上運行時類信息。所以你可以自動使用BOOL IsKindOf(RUNTIME_CLASS(...))

+0

不,'IsKinfOf'由MFC類信息工作(參見'DECLARE_DYNAMIC()'macro)。'DECLARE_SERIAL'實現'DECLARE_DYNAMIC',但主要支持序列化代碼! – 23W

+0

這是正確的。 –