6

使用Visual Studio 2010并使用MFC SDI 应用程序。我有一个主框架拥有的CMFCToolbar对象。

创建此应用程序中的文档时,MainFrame 调用一个函数以将 CMFCToolbar 对象中的一个按钮替换为CMFCToolbarMenuButton。菜单按钮的内容由文档中的信息填充。菜单创建始终有效。对 ReplaceButton 的调用总是成功的。但是我还没有弄清楚这个电话的视觉症状。

任何时候调用 ReplaceButton,按钮都会消失。它不仅不被绘制,而且不可点击。暂时没了。我认为这是因为有一个对旧按钮的悬空引用,我刚刚通过调用 ReplaceButton 将其销毁。

我试过调用 Invalidate()、RecalcLayout() 来触发重绘,但都没有奏效。我让按钮显示的唯一可靠方法是手动或通过取消停靠/重新停靠工具栏来重新调整应用程序窗口的大小。我假设在这些情况下会发生某种较低级别的刷新,但我不知道如何手动触发它。

有没有办法确保我的按钮立即被绘制?

编辑:代码示例

Count = m_Doc->...->GetCount();
for (Index = 0; Index < Count; ++Index)
{
    Caption.Format(L"%s", m_Doc->...->GetName());
        m_pLayerMenu->AppendMenu(MF_ENABLED | MF_STRING, LAYER_DROP_SEED+Index, Caption.GetData());
}
m_wndBrushBar.ReplaceButton(ID_BRUSH_TERRAIN,
    CMFCToolBarMenuButton(ID_BRUSH_TERRAIN, *m_pLayerMenu, GetCmdMgr()->GetCmdImage(ID_BRUSH_TERRAIN)));

更新:

调用m_wndBrushBar.AdjustLayout()似乎可以稳定这些 CMFCToolbar 按钮的视觉行为。所以这是一个部分解决方案。部分原因如下:

很难说出真正的视觉行为是什么。事实证明,所有视觉设置/状态都与这些 MFC 对象一起存储在注册表中,并且它可以保持动态创建的对象的状态,这些对象真正改变了应用程序的启动行为。

我已经进去删除了下面的注册表值

Current User -> "Local App-Wizard Generated Applications" -> [My App Name]. 这样做了很多次,只是为了找出我的应用程序的真实行为是什么。感觉好像我缺少当前版本的 MFC 的一些基础知识。注册表交易引起的许多错误。

有没有办法阻止某些对象的注册表设置,或者完全关闭这种行为?否则,我想我的关机过程必须更加彻底地重置所有视觉元素。注册表值似乎忽略、覆盖或绕过我的启动代码。我可以编写我希望对象如何看待启动的代码,但是如果注册表中有值,那就没有用了。

4

1 回答 1

0

您发现了 CMFC 代码有时令人讨厌的方面。也就是 Workspace 的概念。工作区管理应用程序状态的概念。我也遇到过你描述的问题。但是,您可以通过重写 LoadState () 和 SaveState () 方法灵活地管理如何重新创建这些对象。

于 2014-04-10T20:04:15.003 回答