如何停止显示 CListCtrl 的底部滚动条?
Posted
技术标签:
【中文标题】如何停止显示 CListCtrl 的底部滚动条?【英文标题】:How to stop the bottom scrollbar from a CListCtrl from displaying? 【发布时间】:2018-02-21 00:33:01 【问题描述】:我有一个CListCtrl
,它会随着对话动态调整大小。我在派生的CListCtrl
中使用了WM_SIZE
消息处理程序来调整列的大小,使总和为控件的宽度 - 4,其中 - 4 表示边框的宽度。
当我使对话变大时,控件会正确调整大小并且我没有得到底部滚动条。但是,当我缩小控件时,有时会出现水平滚动条。
void CMyListCtrl::OnSize(UINT nType, int cx, int cy)
CListCtrl::OnSize(nType, cx, cy);
ResizeLastColumn();
void CMyListCtrl::ResizeLastColumn()
LVCOLUMN column;
column.mask = LVCF_WIDTH;
LONG maxWidth = 0;
for (int i = 0; i < lastColumnIndex; ++i)
GetColumn(i, &column);
maxWidth += column.cx;
CRect wndRect;
GetWindowRect(&wndRect);
SetColumnWidth(lastColumnIndex, wndRect.Width() - maxWidth - 4);
就像WM_SIZE
消息在控件最终调整大小之前到达控件。
这与How to determine if a scrollbar for a CListCtrl is displaying? 有关。但是,这个问题不是在处理右滚动条,而是假设它没有被显示。
【问题讨论】:
【参考方案1】:调整窗口大小会生成一条消息以测试水平滚动。 SetColumnWidth
也将生成相同的消息。这取决于 ListView 如何在内部处理此问题,但垂直滚动也可能进出,这将改变客户区,因此代码可能必须进行递归调用以确定滚动是否可见。您可以看到这很容易遇到问题。
在调用默认过程之前尝试调整WM_WINDOWPOSCHANGED
中的列大小。使用SetRedraw
停止多余的绘制消息。
ON_WM_WINDOWPOSCHANGED()
...
void CMyListCtrl::OnWindowPosChanged(WINDOWPOS *wpos)
SetRedraw(FALSE);
ResizeLastColumn();
SetRedraw(TRUE);
CListCtrl::OnWindowPosChanged(wpos);
客户区可以使用GetClientRect
,这样就不需要减去边框粗细(不总是4)。
void ResizeLastColumn()
int maxwidth = 0;
int index = GetHeaderCtrl()->GetItemCount() - 1;
for(int i = 0; i < index; ++i)
maxwidth += GetColumnWidth(i);
CRect rc;
GetClientRect(&rc);
SetColumnWidth(index, rc.Width() - maxwidth);
同样GetHeaderCtrl()->GetItemCount()
返回列数。
【讨论】:
哦。这听起来很有希望。 工作得很好。也使我的其他链接问题没有实际意义。 我试过OnWindowPosChanged
并且它工作正常,它似乎也适用于您的系统。但现在有时它不起作用!我使用SetRedraw
添加了第二种方法,该方法在 Windows 10 上始终有效。稍后我将在 Win7 上尝试。
啊,我只是将CListCtrl::OnWindowPosChanged(wpos)
放在末尾而不是开头,这很好,就像在您更新的代码中一样。
我发现一个奇怪的行为,我不知道它是否相关,如果我插入足够多的行以至于它溢出客户区,并且我使控件更高,它会隐藏所有行,直到我使它足够小以显示垂直滚动条并移动它。之后,它工作正常。也许与不关闭和重绘有关?【参考方案2】:
我面临完全相同的问题,使用完全相同的用例。
要完全禁用水平滚动条,请为 WM_NCCALCSIZE 添加消息处理程序
使用类向导将以下内容添加到您的消息映射中:
ON_WM_NCCALCSIZE()
在此处理程序的实现中,您修改样式以禁用水平滚动条。
void CMyListCtrl::OnNcCalcSize(BOOL bCalcValidRects, NCCALCSIZE_PARAMS* lpncsp)
ModifyStyle(WS_HSCROLL, 0); // disable the horizontal scroll bar
__super::OnNcCalcSize(bCalcValidRects, lpncsp);
在我自己的 ResizeLastColumn() 实现中,与您的类似,我从宽度中减去 ::GetSystemMetrics(SM_CXVSCROLL) 以考虑垂直滚动条。
我知道这个回复有点晚了,但希望它会对某人有所帮助。
(已编辑以删除我遇到的一些问题的提及,因为 a)它们是题外话,b)因为我认为它们源于我没有使用 Doc-View 架构,因此事情没有正确连接。我会重新考虑我的方法。)
【讨论】:
以上是关于如何停止显示 CListCtrl 的底部滚动条?的主要内容,如果未能解决你的问题,请参考以下文章