DoubleBuffered и Resourse Leak
От: Mr.  
Дата: 11.09.09 06:43
Оценка:
Добрый день.
Использую ListView, и для того чтобы не мерцало использую самописную двойную буферизацию (пример нашел на rsdn):

LRESULT CListViewWTL::OnPaint(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/)
{
    if (!m_bRun)
        return DefWindowProc(WM_PAINT,wParam,lParam);

    if(!double_buffered) return DefWindowProc(WM_PAINT,wParam,lParam);

    WTL::CPaintDC pdc(this->m_hWnd);

    CRect crc;
    GetClientRect(&crc);

    //для тех кто не знает колонки — это отдельное окно
    //и рисуется оно само по себе, хотя и на том же HDC что и CListCtrl
    //Отодвигаем клиентскую область чтобы не зарисовывать постоянно колонки
    WTL::CHeaderCtrl hdr=GetHeader();
    if(hdr&&hdr.IsWindowVisible())
    {
        CRect hrc;
        hdr.GetWindowRect(&hrc);
        crc.top=hrc.Height();
    }

    //CListCtrl очень продвинутый в плане отрисовки
    //любит перересовываться по отлеьным строчкам
    //только о том что WM_ERASEBKGND ничего не делает он не знает 
    //Поэтому устанавливает полный регион для отрисовки медленнее зато надёжнее
    WTL::CRgn rgn;
    rgn.CreateRectRgn(crc.left,crc.top,crc.right,crc.bottom);
    pdc.SelectClipRgn(rgn);

    WTL::CMemoryDC dcMem(pdc, crc);
    dcMem.FillRect(crc,m_BrushBackground);

    //Проблема теперь только в том как заставить CListCtrl рисовать по нашему CMemDC
    //К счастию все стандартные контролы поддерживают WM_PRINTCLIENT
    //К сожалению мне не удалось отриовать колонки с помощью этого сообщения
    //Изврат выше с отодвиганием клиентской области введён именно поэтому
    //DefWindowProc(WM_ERASEBKGND,WPARAM(dcMem.m_hDC),0);
    //DefWindowProc(WM_ERASEBKGND,(WPARAM)dcMem.m_hDC,0);

    SendMessage(WM_PRINTCLIENT,(WPARAM)dcMem.m_hDC,PRF_CLIENT);
    
    return 0;
}

Но BoundsChecker выдает постоянно:

DeleteDC usage error. Device Context still contains objects.


Где грабли?
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.