MFC SDI OpenDocument() 正在重置我的主窗口大小。我怎样才能阻止它?
Posted
技术标签:
【中文标题】MFC SDI OpenDocument() 正在重置我的主窗口大小。我怎样才能阻止它?【英文标题】:MFC SDI OpenDocument() is resetting my main window size. How can I stop it? 【发布时间】:2021-10-24 02:10:01 【问题描述】:我已经实现了保存和加载主窗口大小和位置的代码,它工作正常,但是,当我打开一个文档时,它会将窗口大小更改回某个内部默认值。
这些是我看到的来自 Windows 的调用,导致更改发生:
CSingleDocTemplate::OpenDocumentFile()
CFrameWnd::InitialUpdateFrame()
CWnd::SendMessageToDescendants(WM_INITIALUPDATE, 0, 0, TRUE, TRUE)
这是我保存和加载窗口信息的代码:
BOOL CDisplayApp::InitInstance()
// existing code .....
LONG Ret;
HKEY RegistryKey;
DWORD type = REG_BINARY;
WINDOWPLACEMENT sWP;
DWORD sizewp = sizeof(WINDOWPLACEMENT);
Ret = RegOpenKeyEx(
HKEY_CURRENT_USER,
_T("SOFTWARE\\Local AppWizard-Generated Applications\\display\\PreservedWindowPos"),
0,
KEY_READ,
&RegistryKey);
if (Ret == ERROR_SUCCESS)
Ret = ::RegQueryValueEx(RegistryKey,
_T("PosAndSize"),
0,
&type,
(LPBYTE)&sWP,
&sizewp);
if (Ret != ERROR_SUCCESS)
m_pMainWnd->ShowWindow(SW_SHOW);
else
m_pMainWnd->SetWindowPlacement(&sWP);
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
// existing code .....
this->LoadBarState(_T("MainToolBar"));
void CMainFrame::OnClose()
// TODO: Add your message handler code here and/or call default
LONG Ret;
HKEY Registry_Key;
DWORD disposition;
WINDOWPLACEMENT sWindow_Position;
SaveBarState(_T("MainToolBar"));
Ret = RegOpenKeyEx(
HKEY_CURRENT_USER,
_T("SOFTWARE\\Local AppWizard-Generated Applications\\display\\PreservedWindowPos"),
NULL,
KEY_WRITE,
&Registry_Key);
if (Ret != ERROR_SUCCESS)
RegCreateKeyEx(
HKEY_CURRENT_USER,
_T("SOFTWARE\\Local AppWizard-Generated Applications\\display\\PreservedWindowPos"),
NULL,
NULL,
REG_OPTION_NON_VOLATILE,
KEY_ALL_ACCESS,
NULL,
&Registry_Key,
&disposition);
GetWindowPlacement(&sWindow_Position);
RegSetValueEx(
Registry_Key,
_T("PosAndSize"),
NULL,
REG_BINARY,
(BYTE*)&sWindow_Position,
sizeof(WINDOWPLACEMENT));
RegCloseKey(Registry_Key);
CFrameWnd::OnClose();
我希望在我打开文档时窗口大小和位置保持不变。我该怎么做?
【问题讨论】:
我用 AppWiz 生成的 SDI 项目试过这个,我看不出有什么问题,它保存了窗口大小/位置,OpenDocumentFile
没有改变它。你使用CWinApp
还是CWinAppEx
?
这是一个老程序,最初是用MS C++ v6编译的,所以我用的是CWinApp。我看到如果我一直在使用 CWinAppEx,我就不需要添加该代码来保存窗口大小。您认为我应该删除该代码并使用 CWinAppEx 吗?它可能会停止在文档打开时重置窗口吗?我该怎么做,只需将所有对 CWinApp 的引用更改为 CWinAppEx?还需要什么吗?
在源代码中搜索 RecalcLayout()
和 ResizeParentToFit()
等调用。或者跟踪/调试您的代码,这些可能由 MFC 框架本身调用。 CWinAppEx
实际上也是这样做的,它会尝试打开/移动主窗口到之前的位置(就在上次关闭之前),因此切换到 CWinAppEx
可能是一种替代方法。
使用“在文件中替换”,我将每个“CWinApp”更改为“CWinAppEx”,然后检查以确保没有“CWinAppExEx”。将“afxwinappex.h”添加到“stdafx.h”后,程序编译没有错误。我还删除了我为将窗口大小和位置保存到注册表而输入的代码。但是即使默认情况下 CWinAppEx 应该保存窗口大小等,它也只保存最近的文件列表,打开文档仍然会将窗口大小调整为某些默认值。还有其他想法吗?
如果您的项目是使用“MFC 静态库”构建的,您可以使用调试器进入OpenDocumentFile
或InitialUpdateFrame
,看看它们到底在做什么。还张贴程序的屏幕截图,我们可能会知道它是什么。还有关于CMyView
等的类继承的信息。老实说,我没有想法。
【参考方案1】:
我认为这里的正确答案是我的代码是旧的,我需要创建一个新的 SDI 项目并将我的程序移植到它上面,然后再进一步处理。那我看看我还有没有这些问题。
没关系!我很惭愧地报告问题来自我自己在 CView::OnInitialUpdate() 中编写的窗口大小调整代码,并且很久以前就忘记了。对不起!
【讨论】:
以上是关于MFC SDI OpenDocument() 正在重置我的主窗口大小。我怎样才能阻止它?的主要内容,如果未能解决你的问题,请参考以下文章
MFC项目组合:如何将没有文档类的SDI应用程序添加到MDI应用程序中?应该使用子窗口吗?[MFC]