C++ 如何在MFC功能包应用程序中禁用菜单栏项中文本的恢复?
我的应用程序是用MFC功能包(VS2012)编写的。它可以通过从资源dll加载数据来切换UI本地化。但是当应用程序重新加载时,C++ 如何在MFC功能包应用程序中禁用菜单栏项中文本的恢复?,c++,mfc,mfc-feature-pack,C++,Mfc,Mfc Feature Pack,我的应用程序是用MFC功能包(VS2012)编写的。它可以通过从资源dll加载数据来切换UI本地化。但是当应用程序重新加载时,CMFCMenuBar菜单将恢复菜单项的原始文本 如果我使用GetDockingManager()->DisableRestoreDockState(TRUE),它阻止恢复所有布局数据,而不仅仅是文本数据 我知道MFC功能包序列化了许多UI元素。如果可能,我如何禁用文本数据序列化来实现这一点?我找到了一个很好的解决方案。其主要思想是用菜单按钮数据存储LANGID。当菜单栏
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,并且可能会因为断言而无法工作。在序列化之前保存所有文本,清除它,还原它。问题是,您只想阻止保存文本和文本列表在基类内部深层序列化。谢谢,我将尝试覆盖菜单栏的序列化机制。