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.
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:
I faced with exactly the same issue. But, I found another way to fix it. Instead of coding the layout by hand, I reload it from the resource in the "Advanced" button handler. So, the layout adjusts itself for the new controls' sizes.
// Find the layout resource and store it statically.
// There is no need to unload it every time for optimization.
static const HRSRC LAYOUT_RES = ::FindResource(NULL, MAKEINTRESOURCE(IDD_YOUR_DIALOG), RT_DIALOG_LAYOUT);
static const LPVOID LAYOUT_RES_DATA = ::LockResource(::LoadResource(NULL, LAYOUT_RES));
static const DWORD LAYOUT_RES_SIZE = ::SizeofResource(NULL, LAYOUT_RES);
if(auto lo = GetDynamicLayout())
lo->LoadResource(this, LAYOUT_RES_DATA, LAYOUT_RES_SIZE);
That's all. This code snippet picks up the dynamic dialog layout from the resource and applies it to the current state (sizes and positions) of the controls.
EDIT:
Though, there is no wrong resource ID or other erroneous situations handling here...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With