如何更改CDockablePane的标题

7
如何强制刷新MFC功能包中的CDockablePane标题?我正在使用选项卡式的Visual Studio样式示例,并希望更改选项卡的标题。但这些似乎被缓存了,因为当我从默认值更改时,它使用应用程序在上一次运行时使用的内容。我在注册表中找不到任何相关信息。我正在修改字符串表IDS_FILE_VIEW和IDS_CLASS_VIEW以设置新标题。我已经跟踪到CDockablePane ::CreateEx方法,lpszCaption参数确实包含新标题,但仍然使用旧标题。只有在隐藏和再次显示窗格后,才会加载新标题。这应该是一个提示,但我无法解决。为什么它不只是使用我传递给CreateEx的标题呢?
6个回答

6
简而言之,这是MFC功能包中的一个错误 - 实际上是在BCG软件库中。该错误是您无法动态更改这些标题。他们的答案是“为什么要这样做?”
可停靠窗格中选项卡的标题存储在注册表中。如果标题已经存在于注册表中,则不会使用创建时使用的标题。
因此,第一次运行应用程序时,它将使用来自字符串表的标题。之后,它将使用来自注册表的标题。
使用AppWizard创建的设置,注册表设置位于:
HKEY_CURRENT_USER\Software\Local AppWizard-Generated Applications\MyApp\Workspace\DockingManager-128\DockingPaneAndPaneDividers

这个键存储的值基本上是一个二进制文件,由停靠管理器在启动时序列化到窗格中。内容没有记录,但您可以在afxdockablepane.cpp中查看代码正在做什么。

我希望这能帮助其他遇到此问题的人。


非常感谢您的回复。对于“为什么要这样做?”我的回答是……嗯……国际化(抱歉BCG……并非所有地方都说英语)。太荒谬了。 - David Carr
哇,这太荒谬了。我花了一个小时寻找我们的窗格被错误翻译的原因,直到偶然发现了这个答案。非常感谢你。 - TorbenJ
谢谢你的建议。在更改字符串资源后,如果选项卡标题没有变化,我一直在想我是否有正确的字符串。奇怪的是,当鼠标悬停在选项卡上时出现的提示确实使用了新字符串! - user2108868

2

嗯,也许我误解了,但我刚刚在CDockablePane的实例上调用了'SetWindowText'方法。它的标题会根据我传递给'SetWindowText'的内容进行更改...


是的,SetWindowText可以工作,但并不像预期的那样。您必须在调用Create之后的某个时刻调用SetWindowText,并且它不能是Create之后的下一个调用。例如,VS示例有一个名为CreateDockingWindows的函数。在该函数中添加对SetWindowText的调用(在适当的Create之后)无效。我最初发布帖子的重点是Create函数接受一个完全被忽略的标题参数。 - cigarman

1
我曾遇到类似的问题,即应用程序第一次关闭后两个窗格具有相同的名称。我删除了注册表键,第一次启动时一切正常,第二次再次出现同样的错误。 在重载的OnSize中设置 SetWindowText("MyPane"); 解决了问题。这不是设置窗口标题的最佳位置,但正如 Colerman 上面所述,SetWindowsText并不总是按照预期工作。 无论如何,在应用程序启动时,窗格定位过程始终在窗格创建完成后调用OnSize 之后,因此对我来说,这种不太优雅的解决方法起了作用。

0

由于选项卡的文本存储在注册表中,而执行此操作的代码相当隐蔽且未记录,因此我找到了一种不好的方法来实现您想要的效果。

更改.rc文件中的字符串表为所需内容,例如,我将ClassView更改为LayerView:

STRINGTABLE
BEGIN
    IDS_CLASS_VIEW          "Layer View"
    ...
END

在你的主机类中添加这个调用:
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
    if (CMDIFrameWndEx::OnCreate(lpCreateStruct) == -1)
        return -1;

    BOOL bNameValid;

    // set the visual manager and style based on persisted value
    OnApplicationLook(theApp.m_nAppLook);

    GetDockingManager()->DisableRestoreDockState(TRUE); // <-- THIS CALL

这意味着当您关闭并重新打开应用程序时,存储在注册表中的名称将是您放置在 .rc 文件中的名称。

现在,您可以注释掉对 DisableRestoreDockState 的调用,因为正确的调用已存储在注册表中。用户计算机上的新安装也将正常工作。

我不会在最终版本中保留 DisableRestoreDockState,因为我希望其他设置能够恢复。

希望对您有所帮助。


0
窗口的名称在LoadState()时被序列化。删除应用程序中与窗口位置相关的所有注册表信息。在我的情况下,它位于HKCU\Software\My App Name。

0

我遇到了同样的问题,但是由于我不喜欢这里提供的任何解决方案,所以我做了更多的尝试,并发现您可以通过引用 CDockingManager 并调用其方法 DisableRestoreDockState 来轻松禁用从注册表加载状态。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接