MFC、SDI 应用程序,为什么不能通过代码更改视图的布局?
MFC, SDI app, Why the layout of views cannot be changed via code?
我是 MFC 新手。我刚刚使用向导创建了一个 SDI 应用程序,然后尝试修改生成的代码以控制每个视图、工具栏或菜单的布局:
...
m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP | CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC)
...
DockPane(&m_wndToolBar); // m_wndToolBar is a tool bar
...
DockPane(&m_wndFileView);
m_wndClassView.AttachToTabWnd(&m_wndFileView, DM_SHOW, TRUE, &pTabbedBar);
DockPane(&m_wndOutput);
// w_wndFileView, m_wndClassView, m_wndOutput are some views.
...
但似乎不起作用:windows 总是表现得像记住用户上次操作的内容。例如,最后 3 行代码创建了 3 个视图,如下所示:
我运行代码并关闭,然后修改为:
DockPane(&m_wndFileView);
DockPane(&m_wndOutput);
m_wndClassView.AttachToTabWnd(&m_wndOutput, DM_SHOW, TRUE, &pTabbedBar);
我想它应该是这样的但失败了(这个截图不是 运行 结果,我手动更改了布局):
关闭时保持上次布局(如图1)。此外,可以记住任何用户手动更改布局。所以为什么?谁说的?
默认情况下,MFC SDI(和 MDI)应用程序 'remember' 同一应用程序运行之间的框架、菜单和侧窗格配置,这是通过 writing/reading 个条目实现的 to/from Windows 注册表。通常,对于由 Visual Studio 向导生成的名为“MySDIApp”的应用程序,此信息将位于名为 1:
的注册表项中
HKEY_CURRENT_USER\SOFTWARE\Local AppWizard-Generated Applications\MySDIApp
在此,将有一个名为“Workspace”的子项,该子项将包含许多子项,名称形式为“Pane-0123”、“MFCToolBar-456”等。要 'clear' 所有 这些记住的设置,您只需使用注册表编辑器删除该“Workspace”键即可。
或者,您可以通过在您的应用程序 class 覆盖 OnInitInstance
成员(代码应该插入到指示的向导生成的行之间:
BOOL CMySDIApp::InitInstance()
{
// Other wizard-generated and user code ...
SetRegistryKey(_T("Local AppWizard-Generated Applications")); // Wizard-generated
// Delete the remembered Workspace settings ...
HKEY sk;
CString kn;
kn.Format(L"SOFTWARE\%s\%s", m_pszRegistryKey, m_pszAppName);
if (RegOpenKeyEx(HKEY_CURRENT_USER, kn, 0, KEY_ALL_ACCESS, &sk) == ERROR_SUCCESS) {
SHDeleteKey(sk, L"WorkSpace");
RegCloseKey(sk);
}
LoadStdProfileSettings(4); // Wizard-generated
// More wizard-generated and user code ...
return TRUE;
}
1 您可以找到 actual 注册表项,方法是使用注册表编辑器并搜索名为“BasePane--1”的条目;这似乎是向导生成的(和其他)MFC 应用程序的“工作区”条目的第一个子项。
我是 MFC 新手。我刚刚使用向导创建了一个 SDI 应用程序,然后尝试修改生成的代码以控制每个视图、工具栏或菜单的布局:
...
m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP | CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC)
...
DockPane(&m_wndToolBar); // m_wndToolBar is a tool bar
...
DockPane(&m_wndFileView);
m_wndClassView.AttachToTabWnd(&m_wndFileView, DM_SHOW, TRUE, &pTabbedBar);
DockPane(&m_wndOutput);
// w_wndFileView, m_wndClassView, m_wndOutput are some views.
...
但似乎不起作用:windows 总是表现得像记住用户上次操作的内容。例如,最后 3 行代码创建了 3 个视图,如下所示:
我运行代码并关闭,然后修改为:
DockPane(&m_wndFileView);
DockPane(&m_wndOutput);
m_wndClassView.AttachToTabWnd(&m_wndOutput, DM_SHOW, TRUE, &pTabbedBar);
我想它应该是这样的但失败了(这个截图不是 运行 结果,我手动更改了布局):
关闭时保持上次布局(如图1)。此外,可以记住任何用户手动更改布局。所以为什么?谁说的?
默认情况下,MFC SDI(和 MDI)应用程序 'remember' 同一应用程序运行之间的框架、菜单和侧窗格配置,这是通过 writing/reading 个条目实现的 to/from Windows 注册表。通常,对于由 Visual Studio 向导生成的名为“MySDIApp”的应用程序,此信息将位于名为 1:
的注册表项中HKEY_CURRENT_USER\SOFTWARE\Local AppWizard-Generated Applications\MySDIApp
在此,将有一个名为“Workspace”的子项,该子项将包含许多子项,名称形式为“Pane-0123”、“MFCToolBar-456”等。要 'clear' 所有 这些记住的设置,您只需使用注册表编辑器删除该“Workspace”键即可。
或者,您可以通过在您的应用程序 class 覆盖 OnInitInstance
成员(代码应该插入到指示的向导生成的行之间:
BOOL CMySDIApp::InitInstance()
{
// Other wizard-generated and user code ...
SetRegistryKey(_T("Local AppWizard-Generated Applications")); // Wizard-generated
// Delete the remembered Workspace settings ...
HKEY sk;
CString kn;
kn.Format(L"SOFTWARE\%s\%s", m_pszRegistryKey, m_pszAppName);
if (RegOpenKeyEx(HKEY_CURRENT_USER, kn, 0, KEY_ALL_ACCESS, &sk) == ERROR_SUCCESS) {
SHDeleteKey(sk, L"WorkSpace");
RegCloseKey(sk);
}
LoadStdProfileSettings(4); // Wizard-generated
// More wizard-generated and user code ...
return TRUE;
}
1 您可以找到 actual 注册表项,方法是使用注册表编辑器并搜索名为“BasePane--1”的条目;这似乎是向导生成的(和其他)MFC 应用程序的“工作区”条目的第一个子项。