Sobre controles de cabeçalho

Um controle de cabeçalho é uma janela que geralmente é posicionada acima de colunas de texto ou números. Ele contém um título para cada coluna e pode ser dividido em partes. O usuário pode arrastar os divisores que separam as partes para definir a largura de cada coluna. A ilustração a seguir mostra um controle de cabeçalho que rotulou colunas que fornecem informações detalhadas sobre arquivos em um diretório.

screen shot of a dialog box with a three-column header control

Você pode criar um controle de cabeçalho usando a função CreateWindowEx, especificando a classe de janela WC_HEADER e os estilos de controle de cabeçalho apropriados. Essa classe de janela é registrada quando a DLL de controle comum é carregada. Para garantir que essa DLL seja carregada, use a função InitCommonControlsEx. Depois de criar um controle de cabeçalho, você pode dividi-lo em partes, definir o texto em cada parte e controlar a aparência da janela usando mensagens de janela de cabeçalho.

Um controle de cabeçalho pode ser criado como uma janela filho de outro controle, como uma caixa de listagem. No entanto, o controle pai não está ciente do controle de cabeçalho e não permite o espaço ocupado pelo cabeçalho, com o resultado de que os itens de lista aparecerão atrás do cabeçalho. Se você deseja usar um controle de cabeçalho em uma caixa de listagem ou outro controle, o controle pai deve ser desenhado pelo proprietário para que todos os itens sejam exibidos na posição correta.

Os controles de exibição de lista já têm controles de cabeçalho. Em vez de criar um controle de cabeçalho para um controle de exibição de lista, use LVM_GETHEADER ou ListView_GetHeader para recuperar o controle existente.

Tamanho e posição do controle de cabeçalho

Normalmente, você deve definir o tamanho e a posição de um controle de cabeçalho para caber dentro dos limites de um retângulo específico, como a área do cliente de uma janela. Usando a mensagem HDM_LAYOUT, você pode recuperar os valores de tamanho e posição apropriados do controle de cabeçalho.

Ao enviar HDM_LAYOUT, você especifica o endereço de uma estrutura HDLAYOUT que contém as coordenadas do retângulo que o controle de cabeçalho deve ocupar e fornece um ponteiro para uma estrutura WINDOWPOS. O controle preenche a estrutura WINDOWPOS com valores de tamanho e posição apropriados para posicionar o controle ao longo da parte superior do retângulo especificado. O valor de altura é a soma das alturas das bordas horizontais do controle e a altura média dos caracteres na fonte atualmente selecionada no contexto do dispositivo do controle.

Se você quiser usar HDM_LAYOUT para definir o tamanho inicial e a posição de um controle de cabeçalho, defina o estado de visibilidade inicial do controle para que ele fique oculto. Depois de enviar HDM_LAYOUT para recuperar os valores de tamanho e posição, você pode usar a função SetWindowPos para definir o novo estado de tamanho, posição e visibilidade.

Itens

Um controle de cabeçalho normalmente tem vários itens de cabeçalho que definem as colunas do controle. Adicionar um item a um controle de cabeçalho enviando a mensagem de HDM_INSERTITEM para o controle. A mensagem inclui o endereço de uma estrutura HDITEM. Essa estrutura define as propriedades do item de cabeçalho, que pode incluir uma cadeia de caracteres, uma imagem bitmap, um tamanho inicial e um valor LPARAM definido pelo aplicativo.

O membro fmt da estrutura HDITEM de um item pode incluir o sinalizador HDF_STRING ou HDF_BITMAP para indicar se o controle exibe a cadeia de caracteres ou o bitmap do item. Se você quiser exibir uma cadeia de caracteres e um bitmap, crie um item desenhado pelo proprietário definindo o membro fmt para incluir o sinalizador HDF_OWNERDRAW. A estrutura HDITEM também especifica sinalizadores de formatação que informam ao controle se deve centralizar, alinhar à esquerda ou alinhar à direita a cadeia de caracteres ou bitmap no retângulo do item.

HDM_INSERTITEM retorna o índice do item recém-adicionado. Você pode usar o índice em outras mensagens para definir propriedades ou recuperar informações sobre o item. Você pode excluir um item usando a mensagem HDM_DELETEITEM, especificando o índice do item a ser excluído.

Você pode usar a mensagem HDM_SETITEM para definir as propriedades de um item de cabeçalho existente e a mensagem HDM_GETITEM para recuperar as propriedades atuais de um item. Para recuperar uma contagem dos itens em um controle de cabeçalho, use a mensagem HDM_GETITEMCOUNT.

Controles de cabeçalho desenhados pelo proprietário

Você pode definir itens individuais de um controle de cabeçalho para serem itens desenhados pelo proprietário. O uso dessa técnica oferece mais controle do que você teria sobre a aparência de um item de cabeçalho.

Você pode usar a mensagem HDM_INSERTITEM para inserir um novo item desenhado pelo proprietário em um controle de cabeçalho ou a mensagem HDM_SETITEM para alterar um item existente para um item desenhado pelo proprietário. Ambas as mensagens incluem o endereço de uma estrutura HDITEM, que deve ter o membro fmt definido como o valor HDF_OWNERDRAW.

Quando um controle de cabeçalho deve desenhar um item desenhado pelo proprietário, ele envia a mensagem WM_DRAWITEM para a janela pai. O parâmetro wParam da mensagem é o identificador de janela filho do controle de cabeçalho e o parâmetro lParam é um endereço de uma estrutura DRAWITEMSTRUCT. A janela pai usa as informações na estrutura para desenhar o item. Para um item desenhado pelo proprietário em um controle de cabeçalho, a estrutura DRAWITEMSTRUCT contém as seguintes informações.

Membro Descrição
CtlType ODT_HEADER tipo de controle desenhado pelo proprietário.
CtlID Identificador de janela filho do controle de cabeçalho.
ID do item Índice do item a ser sorteado.
itemAção ODA_DRAWENTIRE sinalizador de ação de desenho.
itemState ODS_SELECTED sinalizador de ação de desenho se o cursor estiver no item e o botão do mouse estiver para baixo. Caso contrário, esse membro será zero.
hwndItem Manipule o controle de cabeçalho.
hDC Manipular para o contexto do dispositivo do controle de cabeçalho.
rcItem Coordenadas do item de cabeçalho a ser desenhado. As coordenadas são relativas ao canto superior esquerdo do controle de cabeçalho.
itemData Valor de 32 bits definido pelo aplicativo associado ao item.

 

Filtros de controle de cabeçalho

Especificando o estilo de janela HDS_FILTERBAR para um controle de cabeçalho, você pode habilitar o posicionamento de caixas de edição de filtro abaixo dos títulos de coluna. Um botão de filtro aparece ao lado da caixa de edição. Você pode implementar a filtragem respondendo a códigos de notificação HDN_BEGINFILTEREDIT, HDN_ENDFILTEREDIT, HDN_FILTERBTNCLICK ou HDN_FILTERCHANGE.

Por padrão, a caixa de edição contém um prompt para o usuário inserir texto. Você pode restaurar a caixa de edição para esse estado padrão usando Header_ClearFilter ou Header_ClearAllFilters.

O exemplo de código a seguir mostra como recuperar o controle de cabeçalho de um controle de exibição de lista e adicionar uma barra de filtro.

// hList is the HWND of the list-view control.
HWND hHeader = ListView_GetHeader(hList);
LONG_PTR styles = GetWindowLongPtr(hHeader, GWL_STYLE);
SetWindowLongPtr(g_hHeader, GWL_STYLE, styles | HDS_FILTERBAR);

Processamento de mensagens de controle de cabeçalho padrão

Esta seção descreve as mensagens de janela manipuladas pelo procedimento de janela para a classe de janela WC_HEADER.

Mensagem Processamento realizado
WM_CREATE Inicializa o controle de cabeçalho.
WM_DESTROY Desinicializa o controle de cabeçalho.
WM_ERASEBKGND Preenche o plano de fundo do controle de cabeçalho usando a cor de plano de fundo atual do controle.
WM_GETDLGCODE Retorna uma combinação dos valores DLGC_WANTTAB e DLGC_WANTARROWS.
WM_GETFONT Retorna o identificador para a fonte atual, que é usada pelo controle de cabeçalho para desenhar seu texto.
WM_LBUTTONDBLCLK Captura a entrada do mouse. Se o cursor do mouse estiver em um divisor, o controle enviará o código de notificação HDN_BEGINTRACK e começará a arrastar o divisor. Se o cursor estiver em um item, o item será exibido no estado pressionado.
WM_LBUTTONDOWN O mesmo que a mensagem WM_LBUTTONDBLCLK.
WM_LBUTTONUP Libera a captura do mouse. Se o controle estava rastreando o movimento do mouse, ele envia o código de notificação HDN_ENDTRACK e redesenha o controle de cabeçalho. Caso contrário, o controle envia o código de notificação HDN_ITEMCLICK e redesenha o item de cabeçalho que foi clicado.
WM_MOUSEMOVE Se um divisor estiver sendo arrastado, o controle enviará o código de notificação HDN_TRACK e exibirá o item na nova posição. Se o botão esquerdo do mouse estiver para baixo e o cursor estiver em um item, o item será exibido no estado pressionado.
WM_NCCREATE Aloca e inicializa uma estrutura de dados interna.
WM_NCDESTROY Libera os recursos alocados pelo controle de cabeçalho depois que o controle de cabeçalho não é inicializado.
WM_PAINT Pinta a região inválida do controle de cabeçalho. Se o parâmetro wParam for não-NULL, o controle assume que o valor é um HDC e pinta usando esse contexto de dispositivo.
WM_SETCURSOR Define a forma do cursor, dependendo se o cursor está em um divisor ou em um item de cabeçalho.
WM_SETFONT Seleciona um novo identificador de fonte no contexto do dispositivo para o controle de cabeçalho.