C++ 如何在MFC功能包应用程序中禁用菜单栏项中文本的恢复?

C++ 如何在MFC功能包应用程序中禁用菜单栏项中文本的恢复?,c++,mfc,mfc-feature-pack,C++,Mfc,Mfc Feature Pack,我的应用程序是用MFC功能包(VS2012)编写的。它可以通过从资源dll加载数据来切换UI本地化。但是当应用程序重新加载时,CMFCMenuBar菜单将恢复菜单项的原始文本 如果我使用GetDockingManager()->DisableRestoreDockState(TRUE),它阻止恢复所有布局数据,而不仅仅是文本数据 我知道MFC功能包序列化了许多UI元素。如果可能,我如何禁用文本数据序列化来实现这一点?我找到了一个很好的解决方案。其主要思想是用菜单按钮数据存储LANGID。当菜单栏

我的应用程序是用MFC功能包(VS2012)编写的。它可以通过从资源dll加载数据来切换UI本地化。但是当应用程序重新加载时,
CMFCMenuBar
菜单将恢复菜单项的原始文本

如果我使用
GetDockingManager()->DisableRestoreDockState(TRUE),它阻止恢复所有布局数据,而不仅仅是文本数据


我知道MFC功能包序列化了许多UI元素。如果可能,我如何禁用文本数据序列化来实现这一点?

我找到了一个很好的解决方案。其主要思想是用菜单按钮数据存储LANGID。当菜单栏执行加载过程时,我们需要检查存储的LANGID和当前进程LANGID,如果它们不相等,则需要重置菜单栏

代码:

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;
    }
}
CLocalyMenuBar类 :公共CMFCMenuBar { 声明\u序列(CLocalyMenuBar) 公众: 类型定义CMFCMenuBar TBase; 公众: CLocalyMenuBar(); 虚拟~CLocalyMenuBar(); 虚空序列化(CArchive&ar); }; 实现_序列(CLocalyMenuBar,CLocalyMenuBar::TBase,可版本的_模式| 1) CLocalyMenuBar::CLocalyMenuBar() {} CLocalyMenuBar::~CLocalyMenuBar() {} void CLocalyMenuBar::序列化(CArchive&ar) { TBase::序列化(ar); if(ar.IsLoading()){ LANGID nID=MAKELANGID(LANGU NEUTRAL,SUBSLANGU NEUTRAL); ar>>nID; if((nID!=Locality::getCurrenSourceLangid())和&CanBeRestored(){ 恢复原始状态(); } } 否则{
ar仅删除文本,仍保存菜单位置/自定义

您必须超越CMFCToolbarButton类,并在不希望保存的位置使用该按钮。在CMFCMenuBar中,可能有一种方法可以传递用于按钮的类类型。然后,您的button类可以有一个打开或关闭保存文本的BOOL


如果菜单中没有向下传递按钮类类型的方法,则必须重写创建这些按钮的人。

与序列化代码一样,一个对象序列化另一个对象

CMFCMenuBar最终使用CBCGPToolbarButton::Serialize对项目进行序列化。如果查看此代码内部,您会发现文本存储并重新加载在其中

因此,您唯一的机会就是将工具栏中的所有控件更改为您的类。这几乎是不可能的。更改序列化中的行为是不可能的


因此,从我的角度来看,你的问题没有好的答案,只能选择不同的方法。

@spenibus,谢谢你。回头看,我遗漏了一些东西,所以我进一步修改了问题。显然,如果你觉得我的更改太过激烈,你应该毫不犹豫地回滚。@spenibus,不,你的更改很有用。正如所有w通过序列化代码,一个对象序列化了另一个对象。CMFCMenuBar最终使用CBCGPToolbarButton::Serialize序列化了这些项。因此,我必须子类化CMFCToolbarButton并覆盖Serialize()方法…然后我必须将工具栏和菜单中的所有按钮替换为我的类按钮。对于这样小的任务来说,这是一项巨大的工作!可能有一个技巧,但这是一个糟糕的黑客,它会修改UI,并且可能会因为断言而无法工作。在序列化之前保存所有文本,清除它,还原它。问题是,您只想阻止保存文本和文本列表在基类内部深层序列化。谢谢,我将尝试覆盖菜单栏的序列化机制。