Notícia

O método VCL LockDrawing no TWinControl

vcl110lockdrawingtext

Um dos recursos adicionados à biblioteca VCL no Delphi 11 é a capacidade de manipular a mensagem WM_SETREDRAW do Windows facilmente com dois métodos específicos adicionados à classe TWinControl: LockDrawing e UnlockDrawing


Eu estava revisando minha lista de tarefas no início desta semana e encontrei um not que indicava que eu deveria seguir a postagem do blog que fiz sobre os novos recursos da VCL no Delphi e C++Builder 11 sobre LockDrawing. Na verdade eu escrevi:  “A classe base TWinControl agora oferece os métodos LockDrawing e UnlockDrawing, para desabilitar e controlar a atualização. Isso aciona a execução da mensagem WM_SETREDRAW do Windows. Isso provavelmente vale a sua própria postagem no blog … ” mas eu esqueci totalmente disso. Então aqui está o post do blog, com alguns meses de atraso.

Vamos começar pela API do Windows. A mensagem  WM_SETREDRAW  é enviada para uma janela para “ permitir que as alterações nessa janela sejam redesenhadas, ou para evitar que as alterações nessa janela sejam redesenhadas. ” Sempre que você precisar realizar um conjunto de operações, cada uma exigindo repintar, você pode colocá-las em espera e repintar apenas no final, evitando oscilações e tornando o processo mais rápido. É claro que é importante remover o bloqueio e chamar uma função especial para forçar a repintura (RedrawWindow).

Tudo isso está devidamente encapsulado em dois métodos TWinControl adicionados à biblioteca VCL no RAD Studio 11, LockDrawing e UnlockDrawing, que enviam a mensagem WM_SETREDRAW com os parâmetros adequados. Eles também implementam uma “lógica de contagem de bloqueios” para que, se você bloquear o mesmo controle duas vezes, seja necessário desbloqueá-lo duas vezes para retomar a pintura. Além disso, o UnlockDrawing chama automaticamente a API RedrawWindow.

Dito isto, quais são os casos de uso? Eu escrevi uma demo mostrando dois cenários, e você também pode conferir esta bela postagem no blog de Radek Cervinka.

Um primeiro caso na minha demonstração é adicionar vários elementos a uma caixa de listagem. Embora o Delphi tradicionalmente ofereça e ainda tenha a capacidade de evitar a repintura “congelando” a atualização da lista de strings, faz sentido bloquear a repintura da interface do usuário. Estes são os dois estilos de codificação alternativos:

Em ambos os casos, o desempenho é muito maior (e perceptível) do que sem uma das duas soluções. Outro cenário é o de um conjunto de alterações em um componente causando uma repintura. Isso não é trivial para simular em um exemplo simples, mas uma maneira de causar cintilação “de propósito” com código como este:

Eu sei, isso é bastante estúpido, mas você pode ver que não há cintilação com as chamadas Lock/Unlock, enquanto o efeito parece bastante horrível sem bloquear a interface do usuário. Não que eu possa facilmente renderizar isso em uma captura de tela, mas aqui está o formulário em tempo de execução:

vcl110_lockdrawing-1878353


Reduce development time and get to market faster with RAD Studio, Delphi, or C++Builder.
Design. Code. Compile. Deploy.
Start Free Trial   Upgrade Today

   Free Delphi Community Edition   Free C++Builder Community Edition

Leave a Reply

Esse site utiliza o Akismet para reduzir spam. Aprenda como seus dados de comentários são processados.

IN THE ARTICLES