Recalculate dynamic layout properties

2020-04-21 06:14发布

问题:

Here is a window that is resizable:

The dynamic layout properties are set so that the top group box resizes in width and the lower group/box and tree resize in both dimensions along with the 3 buttons.

For the advanced check box I added code to hide the extra controls and adjust the heights of the associated boxes. So it looks like this:

The code that is used to toggle the control values are:

void CWishListDlg::ToggleAdvancedMode()
{
    CRect rtSortTalk, rtTalkSettings, rtTreeGroup, rtTree, rtTalkCombo;

    m_staticSortTalk.ShowWindow(m_bAdvancedMode ? SW_SHOW : SW_HIDE);
    m_cbTalkSortField.ShowWindow(m_bAdvancedMode ? SW_SHOW : SW_HIDE);
    m_cbTalkSortOrder.ShowWindow(m_bAdvancedMode ? SW_SHOW : SW_HIDE);
    m_staticSortSpeaker.ShowWindow(m_bAdvancedMode ? SW_SHOW : SW_HIDE);
    m_cbSpeakerSortField.ShowWindow(m_bAdvancedMode ? SW_SHOW : SW_HIDE);
    m_cbSpeakerSortOrder.ShowWindow(m_bAdvancedMode ? SW_SHOW : SW_HIDE);
    m_staticTalkHistory.ShowWindow(m_bAdvancedMode ? SW_SHOW : SW_HIDE);
    m_checkIncludeTalkHistory.ShowWindow(m_bAdvancedMode ? SW_SHOW : SW_HIDE);
    m_staticStyle.ShowWindow(m_bAdvancedMode ? SW_SHOW : SW_HIDE);
    m_cbStyle.ShowWindow(m_bAdvancedMode ? SW_SHOW : SW_HIDE);

    m_staticSortTalk.GetWindowRect(&rtSortTalk);
    m_staticSettings.GetWindowRect(&rtTalkSettings);
    m_staticTreeDetails.GetWindowRect(&rtTreeGroup);
    m_Tree.GetWindowRect(&rtTree);

    if (m_bAdvancedMode)
    {
        rtTalkSettings.bottom += m_iOffsetY;
        rtTreeGroup.top += m_iOffsetY;
        rtTree.top += m_iOffsetY;
    }
    else
    {
        rtTalkSettings.bottom -= m_iOffsetY;
        rtTreeGroup.top -= m_iOffsetY;
        rtTree.top -= m_iOffsetY;
    }

    ScreenToClient(&rtTalkSettings);
    ScreenToClient(&rtTreeGroup);
    ScreenToClient(&rtTree);

    m_staticSettings.MoveWindow(&rtTalkSettings);
    m_staticTreeDetails.MoveWindow(&rtTreeGroup);
    m_Tree.MoveWindow(&rtTree);
}

It works fine. I can toggle to my hearts content. Until I try to resize the window:

I can't see any way to recalculate the dynamic layout properties based on the active display.

If "Advanced" is ticked, so that the controls are visible (thus matching the resource editor) then it resizes fine. It is only when it is unticked and I have modified two of the controls that resizing won't work right.

回答1:

I found this excellent resource:

https://mariusbancila.ro/blog/2015/07/27/dynamic-dialog-layout-for-mfc-in-visual-c-2015/

What you have to do is delete the dynamic layout and recreate it:

void CWishListDlg::SetupDynamicLayout()
{
    // Disable dynamic layout (this will delete the pointer and set it to NULL)
    EnableDynamicLayout(FALSE);

    // Enable dynamic layout (this will create a new pointer with no elements)
    EnableDynamicLayout(TRUE);

    // Re-create the dynamic layout content
    auto pManager = GetDynamicLayout();
    if (pManager != nullptr)
    {
        pManager->Create(this); // Assign the window!
        auto moveNone = CMFCDynamicLayout::MoveNone();
        auto moveVertical100 = CMFCDynamicLayout::MoveVertical(100);
        auto moveBoth100 = CMFCDynamicLayout::MoveHorizontalAndVertical(100, 100);
        auto sizeBoth100 = CMFCDynamicLayout::SizeHorizontalAndVertical(100, 100);
        auto sizeHorizontal100 = CMFCDynamicLayout::SizeHorizontal(100);
        auto sizeNone = CMFCDynamicLayout::SizeNone();

        pManager->AddItem(m_staticSettings.GetSafeHwnd(), moveNone, sizeHorizontal100);
        pManager->AddItem(m_staticTreeDetails.GetSafeHwnd(), moveNone, sizeBoth100);
        pManager->AddItem(m_Tree.GetSafeHwnd(), moveNone, sizeBoth100);
        pManager->AddItem(IDC_BUTTON_HELP, moveVertical100, sizeNone);
        pManager->AddItem(IDC_BUTTON_REPORT, moveBoth100, sizeNone);
        pManager->AddItem(IDC_BUTTON_EXPAND_ALL, moveBoth100, sizeNone);
        pManager->AddItem(IDC_BUTTON_COLLAPSE_ALL, moveBoth100, sizeNone);
        pManager->AddItem(IDC_STATIC_RESIZE, moveBoth100, sizeNone);
    }
}

It is a pity that you can't just get an existing control in the layout or tell it to re-initialise based on the active content. But this way works fine. It now resizes correctly:



标签: mfc