Sobre o desenho personalizado

Esta seção contém informações gerais sobre a funcionalidade de desenho personalizado e fornece uma visão geral conceitual de como um aplicativo pode oferecer suporte a desenho personalizado. Atualmente, os seguintes controles oferecem suporte à funcionalidade de desenho personalizado:

  • Controles de cabeçalho
  • Controles de exibição de lista
  • Controles de vergalhão
  • Controles da barra de ferramentas
  • Controles de dica de ferramenta
  • Controles da barra de rastreamento
  • Controles de exibição em árvore

Sobre mensagens de notificação de desenho personalizado

Todos os controles comuns que oferecem suporte a desenhos personalizados enviam códigos de notificação NM_CUSTOMDRAW em pontos específicos durante as operações de desenho. Esses códigos de notificação descrevem operações de desenho que se aplicam a todo o controle, bem como operações de desenho específicas para itens dentro do controle. Como muitos códigos de notificação, NM_CUSTOMDRAW notificações são enviadas como mensagens WM_NOTIFY.

O parâmetro lParam de uma notificação de desenho personalizada será o endereço de uma estrutura NMCUSTOMDRAW ou uma estrutura específica de controle que contém uma estrutura NMCUSTOMDRAW como seu primeiro membro. A tabela a seguir ilustra a relação entre os controles e as estruturas que eles usam.

Estrutura Usado por
NMCUSTOMDRAW Controles de vergalhão, barra de trilha e cabeçalho
NMLVCUSTOMDRAW Controles de exibição de lista
NMTBCUSTOMDRAW Controles da barra de ferramentas
NMTTCUSTOMDRAW Controles de dica de ferramenta
NMTVCUSTOMDRAW Controles de exibição em árvore

 

Ciclos de pintura, estágios de desenho e mensagens de notificação

Como todos os aplicativos do Windows, controles comuns pintam e apagam periodicamente com base em mensagens recebidas do sistema ou de outros aplicativos. O processo de uma pintura de controle ou apagamento de si mesmo é chamado de ciclo de pintura. Os controles que oferecem suporte ao desenho personalizado enviam códigos de notificação NM_CUSTOMDRAW periodicamente durante cada ciclo de pintura. Esse código de notificação é acompanhado por uma estrutura NMCUSTOMDRAW ou outra estrutura que contém uma estrutura NMCUSTOMDRAW como seu primeiro membro.

Uma informação que a estrutura NMCUSTOMDRAW contém é o estágio atual do ciclo de pintura. Isso é conhecido como o estágio de sorteio e é representado pelo valor no membro dwDrawStage da estrutura. Um controle informa seu pai sobre quatro estágios básicos de sorteio. Esses estágios de desenho básicos, ou globais, são representados na estrutura pelos seguintes valores de sinalizador (definidos em Commctrl.h).

Valores globais do estágio de sorteio Descrição
CDDS_PREPAINT Antes do início do ciclo de pintura.
CDDS_POSTPAINT Após a conclusão do ciclo de pintura.
CDDS_PREERASE Antes que o ciclo de apagamento comece.
CDDS_POSTERASE Depois que o ciclo de apagamento estiver completo.

 

Cada um dos valores anteriores pode ser combinado com o sinalizador CDDS_ITEM para especificar estágios de desenho específicos para itens. Por conveniência, Commctrl.h contém os seguintes valores específicos de item.

Valores de estágio de desenho específicos do item Descrição
CDDS_ITEMPREPAINT Antes de um item ser desenhado.
CDDS_ITEMPOSTPAINT Depois que um item foi sorteado.
CDDS_ITEMPREERASE Antes de um item ser apagado.
CDDS_ITEMPOSTERASE Depois que um item foi apagado.
CDDS_SUBITEM Controle comum versões 4.71. Sinalizador combinado com CDDS_ITEMPREPAINT ou CDDS_ITEMPOSTPAINT se um subitem estiver sendo desenhado. Isso só será definido se CDRF_NOTIFYITEMDRAW for retornado do CDDS_PREPAINT.

 

Seu aplicativo deve processar o código de notificação NM_CUSTOMDRAW e, em seguida, retornar um valor específico que informa ao controle o que ele deve fazer. Consulte as seções a seguir para obter mais informações sobre esses valores de retorno.

Aproveitando os serviços de sorteio personalizados

A chave para aproveitar a funcionalidade de desenho personalizado está em responder aos códigos de notificação NM_CUSTOMDRAW que um controle envia. Os valores de retorno que seu aplicativo envia em resposta a essas notificações determinam o comportamento do controle para esse ciclo de pintura.

Esta seção contém informações sobre como seu aplicativo pode usar NM_CUSTOMDRAW valores de retorno de notificação para determinar o comportamento do controle.

Os detalhes são divididos nos seguintes tópicos:

Respondendo à notificação de pré-pintura

No início de cada ciclo de pintura, o controle envia o código de notificação NM_CUSTOMDRAW, especificando o valor CDDS_PREPAINT no membro dwDrawStage da estrutura NM_CUSTOMDRAW que o acompanha. O valor que seu aplicativo retorna para essa primeira notificação determina como e quando o controle envia notificações de desenho personalizadas subsequentes para o restante do ciclo de pintura. Seu aplicativo pode retornar uma combinação dos seguintes sinalizadores em resposta à primeira notificação.

Valor retornado Efeito
CDRF_DODEFAULT O controle vai se desenhar. Ele não enviará notificações de NM_CUSTOMDRAW adicionais para este ciclo de pintura. Esse sinalizador não pode ser usado com nenhum outro sinalizador.
CDRF_DOERASE O controle só desenhará o plano de fundo.
CDRF_NEWFONT Seu aplicativo especificou uma nova fonte para o item; O controle usará a nova fonte. Para obter mais informações sobre como alterar fontes, consulte Alterando fontes e cores. Isso ocorre quando dwDrawStage é igual a CDDS_ITEMPREPAINT.
CDRF_NOTIFYITEMDRAW O controle notificará o pai de quaisquer operações de desenho específicas do item. Ele enviará NM_CUSTOMDRAW códigos de notificação antes e depois de desenhar itens. Isso ocorre quando dwDrawStage é igual a CDDS_PREPAINT.
CDRF_NOTIFYPOSTERASE O controle notificará o pai depois de apagar um item. Isso ocorre quando dwDrawStage é igual a CDDS_PREPAINT.
CDRF_NOTIFYPOSTPAINT O controle enviará uma notificação NM_CUSTOMDRAW quando o ciclo de pintura de todo o controle for concluído. Isso ocorre quando dwDrawStage é igual a CDDS_PREPAINT.
CDRF_NOTIFYSUBITEMDRAW Versão 4.71. Sua inscrição receberá uma notificação de NM_CUSTOMDRAW com dwDrawStage definido como CDDS_ITEMPREPAINT | CDDS_SUBITEM antes de cada subitem de exibição de lista ser desenhado. Em seguida, você pode especificar a fonte e a cor para cada subitem separadamente ou retornar CDRF_DODEFAULT para processamento padrão. Isso ocorre quando dwDrawStage é igual a CDDS_ITEMPREPAINT.
CDRF_SKIPDEFAULT Seu aplicativo desenhou o item manualmente. O controle não desenhará o item. Isso ocorre quando dwDrawStage é igual a CDDS_ITEMPREPAINT.
CDRF_SKIPPOSTPAINT O controle não desenhará o retângulo de foco em torno de um item.

 

Solicitando notificações específicas do item

Se o aplicativo retornar CDRF_NOTIFYITEMDRAW à notificação de desenho personalizada inicial de pré-pintura, o controle enviará notificações para cada item desenhado durante esse ciclo de pintura. Essas notificações específicas de item terão o valor CDDS_ITEMPREPAINT no membro dwDrawStage da estrutura NMCUSTOMDRAW que acompanha. Você pode solicitar que o controle envie outra notificação quando terminar de desenhar o item, retornando CDRF_NOTIFYPOSTPAINT a essas notificações específicas do item. Caso contrário, retorne CDRF_DODEFAULT e o controle não notificará a janela pai até que ela comece a desenhar o próximo item.

Desenhando o item você mesmo

Se o aplicativo desenhar o item inteiro, retorne CDRF_SKIPDEFAULT. Isso permite que o controle ignore itens que não precisa desenhar, diminuindo assim a sobrecarga do sistema. Lembre-se de que retornar esse valor significa que o controle não desenhará nenhuma parte do item.

Alterando fontes e cores

Seu aplicativo pode usar o desenho personalizado para alterar a fonte de um item. Basta selecionar o HFONT desejado no contexto do dispositivo especificado pelo membro hdc da estrutura NMCUSTOMDRAW associada à notificação de desenho personalizada. Como a fonte selecionada pode ter métricas diferentes da fonte padrão, inclua o bit CDRF_NEWFONT no valor de retorno da mensagem de notificação. Para obter mais informações sobre como usar essa funcionalidade, consulte o código de exemplo em Usando o desenho personalizado. A fonte especificada pelo aplicativo é usada para exibir esse item quando ele não está selecionado. O desenho personalizado não permite que você altere os atributos de fonte dos itens selecionados.

Para alterar as cores de texto para todos os controles que oferecem suporte ao desenho personalizado, exceto para o modo de exibição de lista e modo de exibição de árvore, basta definir as cores de texto e plano de fundo desejadas no contexto do dispositivo fornecido na estrutura de notificação de desenho personalizada com as funções SetTextColor e SetBkColor. Para modificar as cores de texto no modo de exibição de lista ou no modo de exibição de árvore, você precisa colocar os valores de cor desejados nos membros clrText e clrTextBk da estrutura NMLVCUSTOMDRAW ou NMTVCUSTOMDRAW.

Observação

Antes da versão 6.0 dos controles comuns, as barras de ferramentas ignoram o sinalizador CDRF_NEWFONT. A versão 6.0 oferece suporte ao sinalizador CDRF_NEWFONT e você pode usá-lo para selecionar uma fonte diferente para a barra de ferramentas. No entanto, você não pode alterar a cor de uma barra de ferramentas quando um estilo visual está ativo. Para alterar a cor de uma barra de ferramentas na Versão 6.0, você deve primeiro desabilitar estilos visuais chamando SetWindowTheme e especificando nenhum estilo visual:

 

SetWindowTheme (hwnd, "", "");

Desenho personalizado com controles List-View e Tree-View

Os controles mais comuns podem ser manipulados essencialmente da mesma maneira. No entanto, os controles list-view e tree-view têm alguns recursos que exigem uma abordagem um pouco diferente para o desenho personalizado.

Para a versão 5.0, esses dois controles podem exibir texto cortado se você alterar a fonte retornando CDRF_NEWFONT. Esse comportamento é necessário para compatibilidade com versões anteriores dos controles comuns. Se você quiser alterar a fonte de um controle list-view ou tree-view, obterá melhores resultados se enviar uma mensagem CCM_SETVERSION com o valor wParam definido como 5 antes de adicionar qualquer item ao controle. Para obter um exemplo de um controle de exibição em árvore que usa desenho personalizado, consulte o artigo da Base de Dados de Conhecimento SAMPLE: CustDTv Illustrates Custom Draw in a TreeView (Q248496).

Desenho personalizado com controles de exibição de lista

Como os controles de exibição de lista têm subitens e vários modos de exibição, você precisará lidar com a notificação de NM_CUSTOMDRAW de forma um pouco diferente dos outros controles comuns.

Para o modo de relatório, use o procedimento a seguir.

  1. A primeira notificação NM_CUSTOMDRAW terá o membro dwDrawStage da estrutura NMCUSTOMDRAW associada definido como CDDS_PREPAINT. Volte CDRF_NOTIFYITEMDRAW.
  2. Em seguida, você receberá uma notificação de NM_CUSTOMDRAW com dwDrawStage definido como CDDS_ITEMPREPAINT. Se você especificar novas fontes ou cores e retornar CDRF_NEWFONT, todos os subitens do item serão alterados. Se, em vez disso, você quiser manipular cada subitem separadamente, retorne CDRF_NOTIFYSUBITEMDRAW.
  3. Se você retornou CDRF_NOTIFYSUBITEMDRAW na etapa anterior, receberá uma notificação de NM_CUSTOMDRAW para cada subitem com dwDrawStage definido como CDDS_SUBITEM | CDDS_ITEMPREPAINT. Para alterar a fonte ou a cor desse subitem, especifique uma nova fonte ou cor e retorne CDRF_NEWFONT.

Para os modos ícone grande, ícone pequeno e lista, use o procedimento a seguir.

  1. A primeira notificação NM_CUSTOMDRAW terá o membro dwDrawStage da estrutura NMCUSTOMDRAW associada definido como CDDS_PREPAINT. Volte CDRF_NOTIFYITEMDRAW.
  2. Em seguida, você receberá uma notificação de NM_CUSTOMDRAW com dwDrawStage definido como CDDS_ITEMPREPAINT. Você pode alterar as fontes ou cores de um item especificando novas fontes e cores e retornando CDRF_NEWFONT. Como esses modos não têm subitens, você não receberá nenhuma notificação de NM_CUSTOMDRAW adicional.

Para obter um exemplo de um manipulador de notificação de NM_CUSTOMDRAW exibição de lista, consulte Usando o desenho personalizado.

Conceitual

Usando o desenho personalizado

Referência de desenho personalizado

Outros recursos

EXEMPLO: CustDTv ilustra o desenho personalizado em um TreeView (Q248496)