1

My application is written with the MFC Feature Pack (VS2012). It can switch UI localization by loading data from a resource dll. But the CMFCMenuBar menu restores the original text of menu items when the application is reloaded.

If I use GetDockingManager()->DisableRestoreDockState(TRUE);, it blocks all layout data from being restored rather than only text data.

I know that the MFC Feature Pack serializes many of the UI elements. If possible, how can I disable text data serialization to achieve this?

23W
  • 1,413
  • 18
  • 37
  • @spenibus, thank you. – 23W Sep 15 '15 at 05:35
  • Looking back at it, I missed a few things so I revised the question further. Obviously if you feel my changes have been too drastic, you should not hesitate to rollback. – spenibus Sep 15 '15 at 13:18
  • @spenibus, no, your changes are useful. – 23W Sep 15 '15 at 13:38
  • As all with serializing code, one object serializes other. CMFCMenuBar finally serializes the items with CBCGPToolbarButton::Serialize. – xMRi Oct 21 '15 at 07:28

3 Answers3

0

I found good solution. Main idea is to store LANGID with menu buttons data also. When menu bar performs load process we need to check stored LANGID and current process LANGID and to reset bar if they are not equivalent.

Code:

class CLocalyMenuBar
    : public CMFCMenuBar
{
    DECLARE_SERIAL(CLocalyMenuBar)

public:
    typedef CMFCMenuBar TBase;

public:
    CLocalyMenuBar();
    virtual ~CLocalyMenuBar();

    virtual void        Serialize(CArchive& ar);
};



IMPLEMENT_SERIAL(CLocalyMenuBar, CLocalyMenuBar::TBase, VERSIONABLE_SCHEMA | 1)

CLocalyMenuBar::CLocalyMenuBar()
{}

CLocalyMenuBar::~CLocalyMenuBar()
{}

void CLocalyMenuBar::Serialize(CArchive& ar)
{
    TBase::Serialize(ar);

    if (ar.IsLoading()) {

        LANGID nID = MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL);
        ar >> nID;

        if ((nID != Locality::GetCurResourceLANGID()) && CanBeRestored()) {
            RestoreOriginalState();
        }
    }
    else {
        ar << Locality::GetCurResourceLANGID();
    }
}


namespace Locality {

    LANGID GetCurResourceLANGID()
    {
        // You should return current resource LANGID for your app process!
        return MY_PROCESS_CURRENT_LANGID;
    }
}

P.S.: For better result you should add such serialization code to all your toolbar and dockable bar classes.

23W
  • 1,413
  • 18
  • 37
0

As all with serializing code, one object serializes other.

CMFCMenuBar finally serializes the items with CBCGPToolbarButton::Serialize. And if you look inside this code you find that the text is stored and reloaded there...

So the only chance you have is to change all controls in the toolbar to be of your class. And this is nearly impossible. Changing the behavior in the serialization isn't a possible way.

So from my point of view, there is no good answer to your question, except choosing a different approach.

xMRi
  • 14,982
  • 3
  • 26
  • 59
-1

to get ONLY the text removed and still save positions/customization of the menu...

you would have to over ride the CMFCToolbarButton class and use that button in the places you don't want saved. In CMFCMenuBar there might be a way to pass down the class type used for buttons. then your button class could have a BOOL that toggles save text on or off.

If there is not a way to pass down button class type in the menu, then you would have to override the guy creating those buttons.

diox8tony
  • 348
  • 3
  • 13
  • So, I must subclass CMFCToolbarButton and overwrite Serialize() method... Then I must replace all buttons in toolbars and menu to my class button. A huge piece of work for such small task! – 23W Sep 16 '15 at 10:05
  • Maybe there is a trick, but this is IMHO a bad hack and it will modify the UI and may not work because of ASSERTs. Save all text before the Serialize, Clear it, Restore it. The problem is that you want to prevent only saving the text and the text ist serialized deep inside a base class. – xMRi Oct 21 '15 at 08:58