我有一个多功能的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());
}
起初我以为它可以正常工作:
注释现在在底部。但是,一旦我调整窗口大小:
笔记已恢复到原始位置。
我知道我有一个与此类似的问题answer,但是我真的必须重新构建整个布局吗?
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");
}
}
}
当我尝试上述操作时,即使对话框已恢复为更宽的对话框宽度,控件的宽度仍是原始宽度。
答案 0 :(得分:2)
CMFCDynamicLayout
读取对话框资源,它存储子控件的坐标及其动态调整大小/移动属性。
这一切都在CDialog::OnInitDialog
中完成。如果移动子控件,例如m_staticInfo
,则CMFCDynamicLayout
不会知道您已移动控件或调整控件的大小。因此,在下一个对话框调整大小请求时,CMFCDynamicLayout
使用旧值。
您可以为m_staticInfo
以外的所有控件以及您打算手动移动的其他控件添加动态调整大小/移动。然后分别添加m_staticInfo
:
BOOL CMyDialog::OnInitDialog()
{
CDialog::OnInitDialog();
CRect rctCombo;
m_cbWeek.GetWindowRect(rctCombo);
ScreenToClient(rctCombo);
m_staticInfo.SetWindowPos(NULL, rctCombo.left, rctCombo.top, 0, 0,
SWP_NOSIZE | SWP_NOZORDER);
if(m_pDynamicLayout)
{
if(!m_pDynamicLayout->HasItem(m_staticInfo.m_hWnd))
{
m_pDynamicLayout->AddItem(m_staticInfo.m_hWnd,
CMFCDynamicLayout::MoveVertical(100), CMFCDynamicLayout::SizeNone());
}
else
{
TRACE(L"item already has dynamic move/size\n");
AfxDebugBreak(0);
}
}
return 1;
}
在内部,MFC调用LoadDynamicLayoutResource(m_lpszTemplateName)
来初始化动态大小/移动。但是文档说不要直接使用此方法。
如果使用支持调整大小的对话框,则在将控件移到新位置时必须记住要计算新的宽度和高度。然后,您将使用适当的Size
调用之一。例如:
// The EDIT control height now needs increasing
iNewEditHeight = rctButton.top - iTextMarginY - rctEdit.top;
m_editText.SetWindowPos(nullptr, 0, 0, iNewWidth, iNewEditHeight, SWP_NOMOVE | SWP_NOZORDER);
由您决定如何调整控件的初始大小。
然后,在OnInitDialog
中,我调用了一个新方法:
void CEditTextDlg::SetupDynamicLayout()
{
if (m_pDynamicLayout != nullptr)
{
m_pDynamicLayout->AddItem(IDC_BUTTON_INSERT_DATE,
CMFCDynamicLayout::MoveHorizontalAndVertical(100, 100), CMFCDynamicLayout::SizeNone());
m_pDynamicLayout->AddItem(IDC_STATIC_INFO,
CMFCDynamicLayout::MoveVertical(100), CMFCDynamicLayout::SizeHorizontal(100));
m_pDynamicLayout->AddItem(IDC_EDIT_TEXT,
CMFCDynamicLayout::MoveNone(), CMFCDynamicLayout::SizeHorizontalAndVertical(100, 100));
}
}
如果使用SetWindowPos
时宽度设置不正确,而仅使用SizeNone()
,则宽度将无法正确调整。