1

I have implemented code to save and load the main window size and location, which works fine, however, when I open a document it changes the window size back to some internal default.

These are the calls from Windows I see leading up to when the change happens:

CSingleDocTemplate::OpenDocumentFile()
CFrameWnd::InitialUpdateFrame()
CWnd::SendMessageToDescendants(WM_INITIALUPDATE, 0, 0, TRUE, TRUE)

This is my code for saving and loading the window info:

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();
}

I would like it if the window size and location were to stay the same when I open documents. How can I do that?

IInspectable
  • 46,945
  • 8
  • 85
  • 181
WillDotson
  • 21
  • 5
  • I tried this with AppWiz generated SDI project, I couldn't see a problem, it saves the window size/position, `OpenDocumentFile` doesn't change it. Do you use `CWinApp` or `CWinAppEx`? – Barmak Shemirani Oct 24 '21 at 05:24
  • This is an old program, originally compiled with MS C++ v6, so I'm using CWinApp. I see that if I had been using CWinAppEx I would not have needed to add that code to save the window size. Do you think I should remove that code and use CWinAppEx? Might it stop the resetting of the window on document open? How do I do that, just change all refrences to CWinApp to CWinAppEx? Is anything else needed? – WillDotson Oct 24 '21 at 05:40
  • 1
    Search in the source code for calls like `RecalcLayout()` and `ResizeParentToFit()`. Or trace/debug your code, these may be called by the MFC Framework itself. `CWinAppEx` actually does this too, it tries to open/move the main window to its previous position (just before last closed), so switching to `CWinAppEx` could be an alternative. – Constantine Georgiou Oct 24 '21 at 11:17
  • Using "Replace in Files", I changed every "CWinApp" to "CWinAppEx", and then checked to make sure there were no "CWinAppExEx". After adding "afxwinappex.h" to "stdafx.h", the program compiled with no errors. I also removed the code I had put in to save the window size and position to the registry. But even though CWinAppEx by default is supposed to save the window size, etc. by default, it only saves the recent files list, and opening a document still resizes the window to some default. Any other ideas? – WillDotson Oct 24 '21 at 18:25
  • 1
    If your project is build with "MFC Static Libraries", you can use the debugger to step in to `OpenDocumentFile` or `InitialUpdateFrame`, see what they are doing exactly. Also post a screen shot of program, we might get a clue what it is. And info about class inheritance of `CMyView` etc. I am out of ideas to be honest. – Barmak Shemirani Oct 24 '21 at 18:36
  • Have you tried making a new test app and building it to see if *it* does what you expect? If it does, compare the code. – Andrew Truckle Oct 24 '21 at 19:51
  • Some tips: a. those `RecalcLayout()` and `ResizeParentToFit()` were called by old MFC versions, esp if your view class was a `CScrollView`-derived one like `CFormView`, so search your code for these, along with `SetWindowPos()` or `MoveWindow()`. b. Make sure your app uses the new MFC library, and not some old MFC dll. c. Try the `CFrameWndEx` frame window class instead of `CFrameWnd`. d. Delete the registry tree for your app. Settings like these are stored under HKCU\SOFTWARE\AppName\WorkSpace. They should all be there. Also (at least temporarily) try a lib- (not dll) based build and debug. – Constantine Georgiou Oct 24 '21 at 21:58
  • I used in the old days, an ovverriden virtual void CMainframe:ActiveFrame() to set SetWindwosPlacement() here. – Tom Tom Oct 24 '21 at 23:24

1 Answers1

0

I think the correct answer here is that my code is old, and I need to create a new SDI project and graft my program onto it before going any further with this. Then I will see if I still have these problems.

NEVER MIND! I am ashamed to report that the problem was coming from my own window sizing code that I wrote in CView::OnInitialUpdate() and forgot about long ago. SORRY!

WillDotson
  • 21
  • 5