如何解决如何在MFC应用程序中以像素为单位获取列表控件的宽度?
我正在用C ++在Visual Studio 2017上编写基于对话框的MFC应用程序。
我为用户添加了一个最大化/最小化窗口的选项。当用户调整对话框的大小时,我要调整控件的大小。在该应用程序中,有一个列表控件,如下图所示,该控件可调整为新的窗口大小。
最大化窗口之前-将每列的宽度调整为列表宽度:
最大化窗口后:
我的问题是我无法将其列调整为新的大小。我已经看到了有关该主题的一些帖子,但不幸的是我仍然无法解决问题。我希望这些列的大小大致相同并填充整个窗口。
我尝试过的方法:
1。方法1 -问题是最后一列比其他列大
void CEditableListControlDlg::OnSize(UINT nType,int cx,int cy) {
if (m_bUseWMSize) {
// adjust column width to window
for (int i = 0; i < m_EditableList.GetHeaderCtrl()->GetItemCount(); ++i) {
m_EditableList.SetColumnWidth(i,LVSCW_AUTOSIZE_USEHEADER);
}
}
m_bUseWMSize = true;
}
变量m_bUseWMSize
可以忽略-它只是一个标志,因此在创建对话框时我不会执行代码。我也尝试过将SetColumnWidth中的标志LVSCW_AUTOSIZE_USEHEADER
切换为LVSCW_AUTOSIZE
,但这也无济于事。
使用方法1后,最大化对话框后,列表如下所示:
2。方法2 -问题是列宽没有受到影响。我认为这是因为width
变量的值为2147483647
,即使我将其除以11(列数),它仍然太大
void CEditableListControlDlg::OnSize(UINT nType,int cy) {
if (m_bUseWMSize) {
RECT rect;
m_EditableList.GetViewRect(&rect);
int width = abs(rect.left - rect.right);
int nCol = 11;
// adjust column width to window
for (int i = 0; i < m_EditableList.GetHeaderCtrl()->GetItemCount(); ++i) {
m_EditableList.SetColumnWidth(i,width/nCol);
}
}
m_bUseWMSize = true;
}
3。方法3 -我尝试以像素为单位检索列表的宽度,然后将其除以列数。问题是列宽太小,因为size.cx
的值为512
void CEditableListControlDlg::OnSize(UINT nType,int cy) {
if (m_bUseWMSize) {
CSize cz;
CSize size = m_EditableList.ApproximateViewRect(cz,-1);
int nCol = 11;
// adjust column width to window
for (int i = 0; i < m_EditableList.GetHeaderCtrl()->GetItemCount(); ++i) {
m_EditableList.SetColumnWidth(i,size.cx/11);
}
}
m_bUseWMSize = true;
}
相关文档:
谢谢。
解决方法
简单的选择是让控件为您完成:-)。根据以下文档主题,在向控件发送LVM_SETCOLUMNWIDTH消息时,可以传递一个特殊值(LVSCW_AUTOSIZE_USEHEADER):
https://docs.microsoft.com/en-us/windows/win32/controls/lvm-setcolumnwidth
您在帖子中提到的SetColumnWidth函数链接中也引用了该内容。
,您可以参考以下代码。也许可以帮到您。
bool CMFCApplication4Dlg::AdjustColumnWidth(CListCtrl* m_acclist)
{
CHeaderCtrl* pHeaderCtrl = m_acclist->GetHeaderCtrl();
int n = m_acclist->GetColumnWidth();
int nColumnCount = pHeaderCtrl->GetItemCount();
for (int i = 0; i < nColumnCount; i++)
{
m_acclist->SetColumnWidth(i,LVSCW_AUTOSIZE);
int nColumnWidth = m_acclist->GetColumnWidth(i);
m_acclist->SetColumnWidth(i,LVSCW_AUTOSIZE_USEHEADER);
int nHeaderWidth = m_acclist->GetColumnWidth(i);
m_acclist->SetColumnWidth(i,nColumnWidth > nHeaderWidth ? nColumnWidth : nHeaderWidth);
}
return true;
}
,
由于LVSCW_AUTOSIZE_USEHEADER
会将最后一列的大小调整为剩余宽度,因此对您没有帮助,因为您希望在所有列上平均分配总宽度。
类似于方法2,您可以尝试以下操作:
- 对于每一列,包括标题在内的所有行都进行循环,并使用
CListCtrl::GetStringWidth
获取以像素为单位的文本宽度。存储每列的最大宽度 - 总结所有这些最大宽度
- 使用
GetClientRect
获取控制客户端矩形的宽度。如果存在滚动条,请用::GetSystemMetrics (SM_CXVSCROLL)
减去它
- 从3中减去2的结果并除以列数。将结果加到在1 中获得的每个最大宽度
- 使用
SetColumnWidth
为每一列分配新宽度
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。