I have a CListCtrl
which is dynamically resized with the dialogue. I used a WM_SIZE
message handler in the derived CListCtrl
to resize the columns such that the total is the width of the control - 4, where the - 4 is to indicate the width of the border.
When I make the dialogue bigger, the control resizes correctly and I don't get the bottom scrollbar. However when I shrink the control, I sometimes get the horizontal scrollbar showing up.
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);
}
It is like the WM_SIZE
message is getting to the control before the control is finally resized.
This is related to How to determine if a scrollbar for a CListCtrl is displaying?. However, this question is not dealing with the right scrollbar, and is assuming that it is not being displayed.
Resizing the window generates a message to test for horizontal scroll.
SetColumnWidth
will also generate the same message. It depends how ListView handles this internally, but a vertical scroll could also come in and go, this will change the client area, so the code may have to make recursive calls to figure out if the scroll should be visible or not. You can see this can easily run in to problems.Try resizing the columns in
WM_WINDOWPOSCHANGED
, before calling the default procedure. UseSetRedraw
to stop redundant paint messages.You can use
GetClientRect
for the client area, then you don't need to subtract the border thickness (which is not always 4).Also
GetHeaderCtrl()->GetItemCount()
returns the number of columns.