首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何获得MFC应用程序中列表控件的宽度(以像素为单位)?

如何获得MFC应用程序中列表控件的宽度(以像素为单位)?
EN

Stack Overflow用户
提问于 2020-09-08 06:30:54
回答 3查看 702关注 0票数 0

我正在用C++编写一个基于VisualStudio2017的MFC应用程序对话框。

我为用户添加了一个选项,以使窗口最大化\最小化。当用户调整对话框大小时,我希望调整控件的大小。在应用程序中有一个列表控件,如下图所示,它根据窗口的新大小进行调整。

在使窗口最大化之前,每个列的宽度调整为列表宽度:

在使窗口最大化之后:

我的问题是,我很难将它的列调整成新的大小。我看过一些关于这个问题的帖子,但不幸的是,我仍然无法解决这个问题。我希望这些柱子大小差不多,并填满整个窗口。

我尝试过的:

1.方法1 --问题是最后一列比其他列大得多

代码语言:javascript
复制
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中的flage LVSCW_AUTOSIZE_USEHEADER转换为LVSCW_AUTOSIZE,但这也没有帮助。

在使用方法1之后,列表在最大化对话框之后如下所示:

2.方法2 --问题是列的宽度不受影响。我认为这是因为width变量的值为2147483647,即使除以11 (列数),它仍然太大了

代码语言:javascript
复制
void CEditableListControlDlg::OnSize(UINT nType, int cx, 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

代码语言:javascript
复制
void CEditableListControlDlg::OnSize(UINT nType, int cx, 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;

}

相关文档:

  1. SetColumnWidth函数
  2. 正向结构
  3. CSize结构
  4. 函数ApproximateViewRect和GetViewRect

谢谢。

EN

回答 3

Stack Overflow用户

发布于 2020-09-09 04:42:20

简单的选择是让控件为您完成它:-)。在向控件发送LVM_SETCOLUMNWIDTH消息时,可以传递一个特殊值(LVM_SETCOLUMNWIDTH),如下所示:

https://learn.microsoft.com/en-us/windows/win32/controls/lvm-setcolumnwidth

在您的文章中提到的SetColumnWidth函数链接中也引用了。

票数 0
EN

Stack Overflow用户

发布于 2020-09-09 05:15:50

您可以参考以下代码。也许它能帮到你。

代码语言:javascript
复制
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;
    }
票数 0
EN

Stack Overflow用户

发布于 2020-09-09 16:14:51

因为LVSCW_AUTOSIZE_USEHEADER将最后一列的大小调整为剩余的宽度,因此它不会对您有帮助,因为您希望在所有列之间均匀地分配总宽度。

与您的方法2类似,您可以尝试以下方法:

  1. 对于每一列循环遍历所有行,包括标题,并使用CListCtrl::GetStringWidth获得以像素为单位的文本宽度。存储每列的最大宽度
  2. 把所有这些最大宽度加起来
  3. 使用GetClientRect获取控件客户端矩形的宽度。如果存在滚动条,则用::GetSystemMetrics (SM_CXVSCROLL)减去它
  4. 从3中减去2的结果,除以列数。将结果添加到1中获得的每个最大宽度。
  5. 使用SetColumnWidth为每个列分配新的宽度
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63788258

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档