Mfc 基于控件可见性在运行时自定义动态布局

Mfc 基于控件可见性在运行时自定义动态布局,mfc,dialog,Mfc,Dialog,我有一个多功能的CDialog,它支持调整大小。它可以显示3种变体的内容 变更1: 变式2: 变式3: 对话控件使用资源编辑器中的动态布局设置 变化1是好的,不需要改变 变体2不显示组合和日期按钮。因此,我希望“文本将…”标签在底部向下,“编辑”框更高 变体3有一个类似的问题,日期按钮应该移到底部,编辑框应该更高 这可以通过更改代码中的动态布局来实现吗 更新 我在OnInitDialog中尝试了这一点: if (!m_bShowWeekCombo) { CRect rctCombo

我有一个多功能的
CDialog
,它支持调整大小。它可以显示3种变体的内容

变更1:

变式2:

变式3:

对话控件使用资源编辑器中的动态布局设置

变化1是好的,不需要改变

变体2不显示组合和日期按钮。因此,我希望“文本将…”标签在底部向下,“编辑”框更高

变体3有一个类似的问题,日期按钮应该移到底部,编辑框应该更高

这可以通过更改代码中的动态布局来实现吗

更新 我在OnInitDialog中尝试了这一点:

if (!m_bShowWeekCombo)
{
    CRect rctCombo;
    m_cbWeek.GetWindowRect(rctCombo);
    ScreenToClient(rctCombo);

    CRect rctNote;
    m_staticInfo.GetWindowRect(rctNote);
    ScreenToClient(rctNote);

    m_staticInfo.MoveWindow(rctCombo.left, rctCombo.top, rctNote.Width(), rctNote.Height());
}
起初,我认为这是可行的:

这张便条现在在底部。但只要我调整窗口大小:

钞票已恢复到原来的位置

我知道我有类似的问题,但我真的要重建整个布局吗

更新2
当我尝试上述方法时,控件宽度是原始宽度,即使对话框已恢复为更宽的对话框宽度。

cmfcdynamicclayout
读取对话框资源,它存储子控件的坐标及其动态调整大小/移动属性

这一切都是在
CDialog::OnInitDialog
中完成的。例如,如果移动子控件,
m_staticInfo
,则
cmfcdynamicclayout
不知道您移动了控件/调整了控件大小。因此,在下一个对话框调整大小请求时,
cmfcdynamiclayeout
使用旧值

您可以为所有控件EXPT
m_staticInfo
和其他要手动移动的控件添加动态调整大小/移动。然后分别添加
m_staticInfo

boolcmydialog::OnInitDialog()
{
CDialog::OnInitDialog();
正确的rctCombo;
m_cbWeek.GetWindowRect(rctCombo);
筛选客户(rctCombo);
m_staticInfo.SetWindowPos(NULL,rctCombo.left,rctCombo.top,0,0,
SWP|u NOSIZE | SWP|u NOZORDER);
如果(m_pdynamic布局)
{
如果(!m_pdynamicallayout->HasItem(m_staticInfo.m_hWnd))
{
m_pdynamicallayout->AddItem(m_staticInfo.m_hWnd,
CMFCDynamicLayout::MoveVertical(100),CMFCDynamicLayout::SizeNone();
}
其他的
{
跟踪(L“项已具有动态移动/大小\n”);
AfxDebugBreak(0);
}
}
返回1;
}
在内部,MFC调用
loadDynamicClayOutResource(m_lpszTemplateName)
初始化动态大小/移动。但文件上说不要直接使用这种方法

澄清 如果使用的对话框支持调整大小,则必须记住在将控件移动到新位置时计算新的宽度和高度。然后使用适当的
Size
调用之一。例如:

//编辑控件高度现在需要增加
iNewEditHeight=rctButton.top-iTextMarginY-rctEdit.top;
m_editText.SetWindowPos(nullptr,0,0,第二行,第八行,SWP_NOMOVE | SWP_NOZORDER);
这取决于你如何锻炼你想要你的控制最初重新大小

然后,在
OnInitDialog
中,我调用了一个新方法:

void-ceditextdlg::setupdynamicclayout()
{
if(m_pdynamicallayout!=nullptr)
{
动态布局->添加项(IDC按钮插入日期,
CMFCDynamicLayout::MoveHorizontalAndVertical(100100),CMFCDynamicLayout::SizeNone();
m_pdynamic layout->AddItem(IDC_STATIC_INFO,
CMFCDynamicClayout::MoveVertical(100),CMFCDynamicClayout::SizeHorizontal(100));
动态布局->添加项(IDC编辑文本,
CMFCDynamicLayout::MoveNone(),CMFCDynamicLayout::SizeHorizontalAndVertical(100100));
}
}

如果使用
SetWindowPos
时未正确设置宽度,而仅使用
SizeNone()
则无法正确调整大小。

谢谢。我要做的是在将控件添加到布局之前重新计算控件的默认大小(因为对话框已调整大小)。已排序。我不确定你想出了什么解决方案。我认为您决定手动移动/调整所有子控件的大小!没有。只有我需要调整大小的控件。我只需要首先正确地“调整”它们的大小。“移动”到正确的位置时,我必须正确地改变宽度。通过IDE资源属性,所有其他的都保留为默认值。那不好。我的控件在宽度或高度上都在拉伸。但我必须先更改控件的基本维度。所以我不得不重新计算正确的尺寸。我对你的答案做了调整。
if (!m_bShowWeekCombo)
{
    CRect rctEdit;
    m_editText.GetWindowRect(rctEdit);
    ScreenToClient(rctEdit);

    CRect rctCombo;
    m_cbWeek.GetWindowRect(rctCombo);
    ScreenToClient(rctCombo);

    CRect rctNote;
    m_staticInfo.GetWindowRect(rctNote);
    ScreenToClient(rctNote);

    //m_staticInfo.MoveWindow(rctCombo.left, rctCombo.top, rctNote.Width(), rctNote.Height());
    m_staticInfo.SetWindowPos(NULL, rctCombo.left, rctCombo.top, 0, 0,
        SWP_NOSIZE | SWP_NOZORDER);
    m_editText.SetWindowPos(NULL, 0, 0, rctEdit.Width(), rctEdit.Height() + (rctCombo.top - rctNote.top),
        SWP_NOMOVE | SWP_NOZORDER);

    if (m_pDynamicLayout)
    {
        if (!m_pDynamicLayout->HasItem(m_staticInfo.m_hWnd))
        {
            m_pDynamicLayout->AddItem(m_staticInfo.m_hWnd,
                CMFCDynamicLayout::MoveVertical(100), CMFCDynamicLayout::SizeHorizontal(100));
        }
        else
        {
            TRACE(L"item already has dynamic move/size\n");
        }
        if (!m_pDynamicLayout->HasItem(m_editText.m_hWnd))
        {
            m_pDynamicLayout->AddItem(m_editText.m_hWnd,
                CMFCDynamicLayout::MoveNone(), CMFCDynamicLayout::SizeHorizontalAndVertical(100, 100));
        }
        else
        {
            TRACE(L"item already has dynamic move/size\n");
        }

    }
}