当 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_SERIALIMPLEMENT_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
/////////////////////////////////////////////////////////////////////////////