Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

[MFC, C++] CListCtrl - mrugająca lista / podwójne buforowanie

Ostatnio zmodyfikowano 2013-07-22 02:29
Autor Wiadomość
DejaVu
Temat założony przez niniejszego użytkownika
[MFC, C++] CListCtrl - mrugająca lista / podwójne buforowanie
» 2013-07-22 02:29:51
Kolejny dzień, kolejne zmagania z MFC... generalnie rzecz biorąc po całym dniu Googlowania i testowania różnych rozwiązań, ostatecznie skleciłem kod, który eliminuje problem migającej/mrugającej listy. Przed zaimplementowaniem poniższego rozwiązania efekt mrugania można było zaobserwować gdy:
  • zmieniało się rozmiar okna lub kontrolki;
  • poruszało się po liście PGUP/PGDN;
  • poruszało się po liście ciągnąć suwakiem.
Inne przypadki również generowały mruganie, ale nie były one aż tak uciążliwe dla oka.

C/C++
//ListCtrlNoFlicker.hpp
#pragma once
#include <afxwin.h>
#include <afxcontrolbars.h>

class CListCtrlNoFlicker
    : public CListCtrl
{
    DECLARE_DYNCREATE( CListCtrlNoFlicker )
    DECLARE_MESSAGE_MAP()
    public
: afx_msg BOOL OnEraseBkgnd( CDC * _pDC );
    afx_msg void OnPaint();
}; //class CListCtrlNoFlicker

C/C++
//ListCtrlNoFlicker.cpp
#include "ListCtrlNoFlicker.hpp"

IMPLEMENT_DYNCREATE( CListCtrlNoFlicker, CListCtrl )

BEGIN_MESSAGE_MAP( CListCtrlNoFlicker, CListCtrl )
ON_WM_ERASEBKGND()
ON_WM_PAINT()
END_MESSAGE_MAP()

//afx_msg
BOOL CListCtrlNoFlicker::OnEraseBkgnd( CDC * _pDC )
{
    return TRUE; //TRUE = poinformuj WndProc, że czyszczenie zostało obsłużone
}

//afx_msg
void CListCtrlNoFlicker::OnPaint()
{
    //Pobranie rozmiaru kontrolki
    CRect rcClient;
    GetClientRect( rcClient );
   
    //Pobranie wysokości nagłówka i pomniejszenie rozmiaru kontrolki z góry o wysokość kontrolki
    CHeaderCtrl * pCtrl = GetHeaderCtrl();
    if( pCtrl &&::IsWindow( pCtrl->GetSafeHwnd() ) )
    {
        CRect rcHeaderRect;
        pCtrl->GetClientRect( & rcHeaderRect );
        rcClient.top += rcHeaderRect.Height();
    }
   
    if( rcClient.IsRectEmpty() )
         return; //Kontrolka ma zbyt mały rozmiar - nie ma czego rysować i tym samym nie ma czego buforować
   
    //Utworzenie bufora, wypełnienie go kolorem domyślnym i wywołanie domyślnej procedury do rysowania zawartości kontrolki
    CPaintDC dc( this );
    CMemDC dcMem( dc, rcClient );
    dcMem.GetDC().FillSolidRect( rcClient,::GetSysColor( COLOR_WINDOW ) );
    DefWindowProc( WM_PAINT,( WPARAM ) dcMem.GetDC().m_hDC,( LPARAM ) 0 );
    //Wywołanie destruktora CMemDC powoduje przekopiowanie danych do źródła (czyli na ekran)
}

Powyższy kod nie rozwiązuje jeszcze problemu mrugającego CHeaderCtrl, choć w istotny sposób go ogranicza, więc raczej tego tematu drążyć na razie nie będę :P
P-88516
« 1 »
  Strona 1 z 1