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 静态库”构建的,您可以使用调试器进入OpenDocumentFileInitialUpdateFrame,看看它们到底在做什么。还张贴程序的屏幕截图,我们可能会知道它是什么。还有关于CMyView 等的类继承的信息。老实说,我没有想法。 【参考方案1】:

我认为这里的正确答案是我的代码是旧的,我需要创建一个新的 SDI 项目并将我的程序移植到它上面,然后再进一步处理。那我看看我还有没有这些问题。

没关系!我很惭愧地报告问题来自我自己在 CView::OnInitialUpdate() 中编写的窗口大小调整代码,并且很久以前就忘记了。对不起!

【讨论】:

以上是关于MFC SDI OpenDocument() 正在重置我的主窗口大小。我怎样才能阻止它?的主要内容,如果未能解决你的问题,请参考以下文章

在 SDI MFC 应用程序中绘制流程图

MFC项目组合:如何将没有文档类的SDI应用程序添加到MDI应用程序中?应该使用子窗口吗?[MFC]

在 MFC SDI 应用程序中调用 OnDraw

如何在 SDI 中使用 MFC CListCtrl

MFC, SDI app, 为啥视图的布局不能通过代码改变?

C++ MFC SDI 创建子窗口