当 MFC(功能包)调用 CDockablePane::Serialize() 时?
Posted
技术标签:
【中文标题】当 MFC(功能包)调用 CDockablePane::Serialize() 时?【英文标题】:When MFC (Feature Pack) calling for CDockablePane::Serialize()? 【发布时间】:2015-12-04 10:11:58 【问题描述】:CDockablePane::Serialize()
方法是否从 MFC 功能包核心调用?
我有继承自 CDockablePane
类的可停靠窗口类。我的类覆盖虚拟Serialize()
方法并声明为串行DECLARE_SERIAL/IMPLEMENT_SERIAL
。但是 MFC 不会调用我的Serialize()
方法!为什么 ?
MSDN say 认为CDockablePane
类有序列化方法:SaveState()
、LoadState()
和Serialize()
。前两个(SaveState()
、LoadState()
)在内部使用,Serialize()
用于“序列化窗格”。但它没有调用!
【问题讨论】:
不,它不是由框架调用的。您通常必须从CDocument::Serialize
手动调用它。 LoadState
/SaveState
用于保存/恢复窗格位置和状态。他们确实使用 Registry 作为存储。
@AndrewKomiagin 谢谢。 :( 很伤心,我不明白声明CDockablePane
类为可序列化的含义。
DECLARE_SERIAL
和 IMPLEMENT_SERIAL
用于支持 operator>>
和其他 CArchive
特定的东西以及运行时类信息。
【参考方案1】:
不,MFC 框架不会自动调用Serialize()
方法。您通常必须从CDocument::Serialize()
手动调用它。 LoadState()
和 SaveState()
方法用于保存/恢复窗格位置和状态。他们确实使用 Registry 作为存储。
至于DECLARE_SERIAL
和IMPLEMENT_SERIAL
,它们用于支持operator>>
和其他CArchive
特定的东西以及运行时类信息。这样你就可以自动使用BOOL IsKindOf(RUNTIME_CLASS(...))
了。
【讨论】:
不,IsKinfOf
按 MFC 类信息工作(请参阅 DECLARE_DYNAMIC()
宏)。 DECLARE_SERIAL
实现了DECLARE_DYNAMIC
,但主要支持序列化代码!【参考方案2】:
我的回答命题。我的班级CSerializableDockablePane
在框架创建或存储此停靠窗格时调用Serialize
方法(框架调用方法LoadState()
和SaveState()
)。
您可以使用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
/////////////////////////////////////////////////////////////////////////////
【讨论】:
以上是关于当 MFC(功能包)调用 CDockablePane::Serialize() 时?的主要内容,如果未能解决你的问题,请参考以下文章