visual-c++mfcdialogstatusbardynamiclayout

Resizing dialog issues with MFC and status bars


The minimum size of my dialog does not factor in the size of the status bar.

In OnInitDialog I create the status bar and add it to the dynamic layout:

m_StatusBar.Create(this);
m_StatusBar.SetIndicators(&indicators_msa[0], 3);
m_StatusBar.SetPaneInfo(0, ID_INDICATOR_PROGRESS, SBPS_NORMAL, 100);
m_StatusBar.SetPaneInfo(1, ID_INDICATOR_TEXT, SBPS_STRETCH, 100);
m_StatusBar.SetPaneInfo(2, ID_INDICATOR_CONGREGATION_NAME, SBPS_NORMAL, 150);
m_StatusBar.SetPaneText(0, L"");
m_StatusBar.SetPaneText(1, L"");
m_StatusBar.SetPaneText(2, theApp.MSAToolsInterface().GetLocalCongregationName());

RepositionBars(AFX_IDW_CONTROLBAR_FIRST, AFX_IDW_CONTROLBAR_LAST, 0);

m_StatusProgressBar.Create(L"", 100, 100, true, 0, &m_StatusBar);

m_pDynamicLayout->AddItem(m_StatusBar.GetSafeHwnd(),
    CMFCDynamicLayout::MoveVertical(100),
    CMFCDynamicLayout::SizeHorizontal(100));

This bit does work. But when I try to reduce the size of the dialog it reduces to the original dialog size without taking into account the status bar:

enter image description here

I don't expect it to hide the status bar:

enter image description here

My CDialog inherits from a custom class which already implements:

void CResizingDialog::OnGetMinMaxInfo(MINMAXINFO* lpMMI)
{
    // Set the minimum window size to initial size.
    if (!m_rcInit.IsRectEmpty()) {
        lpMMI->ptMinTrackSize.x = m_rcInit.Width();
        lpMMI->ptMinTrackSize.y = m_rcInit.Height();

        if (m_bLimitToHorizontalResizing)
            lpMMI->ptMaxTrackSize.y = m_rcInit.Height();
    }

    __super::OnGetMinMaxInfo(lpMMI);
}

m_rcInit is defined in OnInitDialog. I realize that the base class has no knowledge of a status bar. So maybe I have to add the size of a status bar to the default height before setting ptMinTrackSize.y

?

It seems if I physically (in IDE) make the dialog taller to allow for the toolbar at top AND statusbar then things are better. Most odd.


Solution

  • The suggestion by @AdrianMole in the comments made me realise what the issue was. This is how resolved it:

    1. I added a new bool m_bRestoreWindowPositionImmediately variable to the CResizingDialog class.
    2. The constructor was updated to include this variable, defaulting to true for backward compatibility.
    3. OnInitDialog was updated:
    BOOL CResizingDialog::OnInitDialog()
    {
        __super::OnInitDialog();
    
        // Save Initial window size to m_rcInit
        RecalculateSize();
    
        if (m_bRestoreWindowPositionImmediately)
        {
            RestoreWindowPosition();
        }
    
        return TRUE;
    }
    
    1. Now I modified the parent CMeetingScheduleAssistantDlg::CMeetingScheduleAssistantDlg contructor to pass false for the new variable.

    2. Finally, I modified the CMeetingScheduleAssistantDlg::OnInitDialog to do this:

    BOOL CMeetingScheduleAssistantDlg::OnInitDialog()
    {
        // Create toolbar
        // Create status bar
    
        RecalculateSize(); // Resets the m_rcInit
        RestoreWindowPosition(); // Now restore
    }
    

    Now the m_rcInit has the correct size, with toolbar and statusbar inplace. And this is at the default window size. Calling RestoreWindowPosition at this time works correctly and the window no longer resizes too small and behaves exactly as it should do.