我有一个CListCtrl
,它会通过对话动态调整大小。我在派生的WM_SIZE
中使用了CListCtrl
消息处理程序来调整列的大小,使得总数是控件的宽度 - 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?有关。但是,这个问题不是处理正确的滚动条,而是假设它没有显示。
答案 0 :(得分: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()
也会返回列数。
答案 1 :(得分:0)
我正面临着完全相同的问题,具有完全相同的用例。
要完全禁用水平滚动条,请为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体系结构以及结果未正确连接。我将重新考虑我的方法。)