0
votes

Does CDockablePane::Serialize() method is calling from MFC Feature Pack core?

I have dockable window class that inherited from CDockablePane class. My class override virtual Serialize() method and declared as serial DECLARE_SERIAL/IMPLEMENT_SERIAL. But MFC does not call my Serialize() method! Why ? MSDN say that CDockablePane class have serialization methods: SaveState(), LoadState() and Serialize(). First two (SaveState(), LoadState()) are used internally and Serialize() used for "serializes the pane". But it is not calling!

2
No it is not called by framework. You have to call it manually usually from CDocument::Serialize. LoadState/SaveState are used to save/restore pane position and state. They do use Registry as storage.Andrew Komiagin
@AndrewKomiagin thank you. :( It's very sad, I do not understand the meaning declare CDockablePane class as serializable.23W
DECLARE_SERIAL and IMPLEMENT_SERIAL are used to support operator>> and other CArchive-specific stuff plus runtime class info.Andrew Komiagin

2 Answers

3
votes

No, the Serialize() method is not called by MFC framework automatically. You have to call it manually usually from CDocument::Serialize(). LoadState() and SaveState() methods are used to save/restore pane position and state. They do use Registry as storage.

As for DECLARE_SERIAL and IMPLEMENT_SERIAL they are used to support operator>> and other CArchive-specific things plus runtime class information. So you'll be able to use BOOL IsKindOf(RUNTIME_CLASS(...)) automagically.

0
votes

My answer proposition. My class CSerializableDockablePane performs call for Serialize method when this docked pane is created or stored by framework (framework calls methods LoadState() and SaveState()).

You can use CSerializableDockablePane as base class for your dockable pane and overwrite virtual Serialize() method for your need.

Code:

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