CDockablePane::Serialize()
方法是否正在从MFC Feature Pack核心调用?
我有从CDockablePane
类继承的可停靠窗口类。我的类覆盖虚拟Serialize()
方法并声明为serial DECLARE_SERIAL/IMPLEMENT_SERIAL
。但是MFC没有调用我的Serialize()
方法!为什么?
CDockablePane
类具有序列化方法的MSDN say:SaveState()
,LoadState()
和Serialize()
。前两个(SaveState()
,LoadState()
)在内部使用,Serialize()
用于" 序列化窗格&#34 ;。但它不是在呼唤!
答案 0 :(得分:3)
不,MFC框架不会自动调用Serialize()
方法。您必须通常从CDocument::Serialize()
手动调用它。 LoadState()
和SaveState()
方法用于保存/恢复窗格位置和状态。他们确实使用注册表作为存储。
对于DECLARE_SERIAL
和IMPLEMENT_SERIAL
,它们用于支持operator>>
和其他CArchive
- 特定事物以及运行时类信息。因此,您可以自动使用BOOL IsKindOf(RUNTIME_CLASS(...))
。
答案 1 :(得分:0)
我的回答主张。当这个停靠窗格由框架(框架调用方法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
/////////////////////////////////////////////////////////////////////////////