Re: CListCtrl size at runtime
"Tom Serface" <tom.nospam@camaswood.com> ha scritto nel messaggio
news:AD3BBE0D-1E6C-4A20-BC12-7838B4A543D9@microsoft.com...
That is a great idea for Gary to try, but he may find out that the flicker
is because it is updating too fast rather than the opposite. I think the
control is just scrolling quickly and always pinning it to the bottom
makes a lot of calls to EnsureVisible() happen (I think he said as many as
10 a second).
Hi Tom,
I think that 10 updates per seconds are few :)
I tried 100 updates in less than a second, and using the technique of
painting to a CMemDC (as I posted above), I have zero flickering.
I belive the key here is to use CMemDC as described here:
http://69.10.233.10/KB/GDI-plus/what_is_a_basename_.aspx
The handlers for WM_ERASEBACKGROUND, WM_PAINT and WM_SIZE for a class I
derived from CListCtrl are like these:
<code>
BOOL CMyListCtrl::OnEraseBkgnd(CDC* pDC)
{
// TODO: Add your message handler code here and/or call default
UNUSED_ALWAYS(pDC);
// return CListCtrl::OnEraseBkgnd(pDC);
return TRUE;
}
void CMyListCtrl::OnSize(UINT nType, int cx, int cy)
{
CListCtrl::OnSize(nType, cx, cy);
GetClientRect(m_rectClient);
CHeaderCtrl* pHC;
pHC = GetHeaderCtrl();
if (pHC != NULL)
{
CRect rectHeader;
pHC->GetItemRect( 0, &rectHeader );
m_rectClient.top += rectHeader.bottom;
}
}
void CMyListCtrl::OnPaint()
{
CPaintDC dc(this); // device context for painting
// Paint to a memory device context to reduce screen flicker.
CodeProject::CMemDC memDC(&dc, &m_rectClient);
// Let the window do its default painting...
CWnd::DefWindowProc( WM_PAINT, (WPARAM)memDC.m_hDC, 0 );
}
</code>
Note that I used a custom CodeProject:: namespace above, because it seems
that VS2008 SP1 (ex Feature pack) defines a new CMemDC class (but I wanted
to use the CodeProject's one).
I use also a LVN_GETDISPINFO notification in is reflected form, such that it
can be handled in the CListCtrl-derived class, and the body of this handler
is something like this:
<code>
void CMyListCtrl::OnLvnGetdispinfo(NMHDR *pNMHDR, LRESULT *pResult)
{
NMLVDISPINFO *pDispInfo = reinterpret_cast<NMLVDISPINFO*>(pNMHDR);
*pResult = 0;
if (pDispInfo->item.iItem < 0 ||
pDispInfo->item.iItem >= GetDB()->Count())
{
return; // requesting invalid item
}
if (pDispInfo->item.mask & LVIF_TEXT) {
const Database::Record * pRec =
GetDB()->GetAt(pDispInfo->item.iItem);
LPCTSTR pszResult = TEXT("");
switch (pDispInfo->item.iSubItem)
{
case COL_NAME: pszResult = pRec->Name.GetString();
break;
case COL_SURNAME: pszResult = pRec->Surname.GetString();
break;
case COL_CITY: pszResult = pRec->City.GetString();
break;
}
pDispInfo->item.pszText = const_cast<LPTSTR>(pszResult);
}
if (pDispInfo->item.mask & LVIF_IMAGE) {
pDispInfo->item.iImage = -1;
}
if (pDispInfo->item.mask & LVIF_STATE) {
pDispInfo->item.state = 0;
}
}
</code>
G