Como evitar a cintilação durante o manuseio WM_ERASEBKGND no diálogo do Windows
Pergunta
Eu tenho um diálogo que redimensiona. Ele também tem um fundo personalizado que eu pinto, em resposta a uma chamada WM_ERASEBKGND (atualmente uma simples chamada para FillSolidRect).
Quando o diálogo é redimensionado, há uma tremenda cintilação acontecendo. Para tentar reduzir a cintilação eu enumerar todas as janelas filho e adicioná-los para a região de recorte. Isso parece ajudar um pouco -. Agora a cintilação é principalmente evidente em todos os controles filho como eles pintar
Como posso fazer a cintilação livre de diálogo durante o redimensionamento? Eu suspeito buffer duplo deve desempenhar um papel, mas eu não tenho certeza de como fazer isso com uma caixa de diálogo com controles filho (sem fazer todos os controles filho proprietário-desenhar ou algo parecido).
Devo observar que eu estou usando C ++ (não .net), e MFC, embora soluções puras baseados em Win32 são bem-vindas:)
NOTA: Uma coisa que eu tentei, mas que não fez trabalho (não sei porquê) foi:
CDC memDC;
memDC.CreateCompatibleDC(pDC);
memDC.FillSolidRect(rect, backgroundColor);
pDC->BitBlt(0, 0, rect.Width(), rect.Height(), &memDC, 0, 0, SRCCOPY);
Solução
Assumindo que "FillSolidRect" é o apagar do seu fundo, em seguida, retornar TRUE do WM_ERASEBKGND.
Para fazer o buffer duplo que você está quase fazendo no seu fragmento de código, você vai precisar usar CreateCompatibleBitmap e selecione que em seu memDC.
Outras dicas
Tente adicionar a seguinte linha para a sua função OnInitDialog:
ModifyStyle(0, WS_CLIPCHILDREN, 0);
Do nada no manuseamento WM_ERASEBKGND e fazer a apagar como parte de sua WM_PAINT principal. Você pode pintar mais inteligente para que você só redesenhar as áreas inválidos, ou mais facilmente, double-tamponar o desenho.
Ao não fazer nada no fundo apagar, você tem todo o código seu desenho em um local que deve tornar mais fácil para os outros a seguir e manter.
Se você está direcionando WinXP ou superior, você também pode usar o estilo WS_EX_COMPOSITED para permitir buffer duplo por padrão para janelas de nível superior com este modelo. Tenha em mente que isso tem seu próprio conjunto de limitações -. Especificamente, não mais desenho fora de ciclos OnPaint usando GetDC, etc
Você pode definir o parâmetro de sua chamada ao método InvalidateRect como falsa. Isso vai evitar que você envie WM_ERASEBKGND quando a janela irá redesenhar. Aqui é uma ligação agradável para evitar piscando na janela.
buffer duplo é realmente a única maneira de fazer este trabalho.
controles filho vai cuidar de si mesmos, desde que você tenha certeza CLIPCHILDREN
.