当 MFC(功能包)调用 CDockablePane::Serialize() 时?
When MFC (Feature Pack) calling for CDockablePane::Serialize()?
CDockablePane::Serialize()
方法是否从 MFC Feature Pack 核心调用?
我有继承自 CDockablePane
class 的可停靠 window class。我的 class 覆盖虚拟 Serialize()
方法并声明为串行 DECLARE_SERIAL/IMPLEMENT_SERIAL
。但是MFC并没有调用我的Serialize()
方法!为什么 ?
MSDN say CDockablePane
class 有序列化方法:SaveState()
、LoadState()
和Serialize()
。前两个(SaveState()
、LoadState()
)在内部使用,Serialize()
用于“序列化窗格 ”。但是它没有调用!
不,Serialize()
方法不会被 MFC 框架自动调用。您通常必须从 CDocument::Serialize()
手动调用它。 LoadState()
和 SaveState()
方法用于 save/restore 窗格位置和状态。他们确实使用 Registry 作为存储。
至于 DECLARE_SERIAL
和 IMPLEMENT_SERIAL
它们用于支持 operator>>
和其他 CArchive
-特定的东西加上运行时 class 信息。这样您就可以自动使用 BOOL IsKindOf(RUNTIME_CLASS(...))
。
我的回答命题。当此停靠窗格由框架创建或存储时,我的 class CSerializableDockablePane
执行调用 Serialize
方法(框架调用方法 LoadState()
和 SaveState()
)。
您可以使用 CSerializableDockablePane
作为可停靠窗格的基础 class,并根据需要覆盖虚拟 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
/////////////////////////////////////////////////////////////////////////////
CDockablePane::Serialize()
方法是否从 MFC Feature Pack 核心调用?
我有继承自 CDockablePane
class 的可停靠 window class。我的 class 覆盖虚拟 Serialize()
方法并声明为串行 DECLARE_SERIAL/IMPLEMENT_SERIAL
。但是MFC并没有调用我的Serialize()
方法!为什么 ?
MSDN say CDockablePane
class 有序列化方法:SaveState()
、LoadState()
和Serialize()
。前两个(SaveState()
、LoadState()
)在内部使用,Serialize()
用于“序列化窗格 ”。但是它没有调用!
不,Serialize()
方法不会被 MFC 框架自动调用。您通常必须从 CDocument::Serialize()
手动调用它。 LoadState()
和 SaveState()
方法用于 save/restore 窗格位置和状态。他们确实使用 Registry 作为存储。
至于 DECLARE_SERIAL
和 IMPLEMENT_SERIAL
它们用于支持 operator>>
和其他 CArchive
-特定的东西加上运行时 class 信息。这样您就可以自动使用 BOOL IsKindOf(RUNTIME_CLASS(...))
。
我的回答命题。当此停靠窗格由框架创建或存储时,我的 class CSerializableDockablePane
执行调用 Serialize
方法(框架调用方法 LoadState()
和 SaveState()
)。
您可以使用 CSerializableDockablePane
作为可停靠窗格的基础 class,并根据需要覆盖虚拟 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
/////////////////////////////////////////////////////////////////////////////