Partilhar via


TN014: Controles personalizados.

Esta nota descreve o suporte a MFC para controles personalizados e self-desenho.Ele também descreve a subclassificação dinâmica e descreve o Relação entre CWnd objetos de e HWNDs.

O aplicativo de exemplo MFC CTRLTEST ilustra como usar vários controles personalizados.Consulte o código-fonte para o MFC geral amostra CTRLTEST e ajuda online.

Controles/menus de desenho proprietário

Windows oferece suporte para menus e controles proprietário-draw usando mensagens do Windows.A janela pai de qualquer controle ou o menu recebe essas mensagens e chamadas de funções em resposta.Você pode substituir essas funções para personalizar a aparência e comportamento do seu menu ou controle de desenho proprietário.

MFC proprietário-draw suporta diretamente com as seguintes funções:

Você pode substituir essas funções em seu CWnd classe derivada para implementar personalizado desenhar comportamento.

Essa abordagem não levar a códigos reutilizáveis.Se você tiver dois controles semelhantes em dois diferentes CWnd classes, você deve implementar o comportamento do controle personalizado em dois locais. A arquitetura suportada MFC self-desenho controle resolve esse problema.

Self-Draw menus e controles

MFC fornece uma implementação padrão (no CWnd e CMenu classes) para as mensagens padrão de desenho proprietário.Esta implementação padrão será decodificar os parâmetros de desenho proprietário e delegue as mensagens de desenho proprietário para os controles ou menu.Isso é chamado self-draw porque o código do desenho está na classe do controle ou menu, não na janela do proprietário.

Usando controles self-draw você pode criar classes de controle reutilizável que usar semântica de desenho proprietário para exibir o controle.O código para desenhar o controle é da classe de controle, não seu pai.Isso é uma abordagem orientada a objeto para a programação de controle personalizado.Adicionar a lista seguinte das funções às classes self-draw:

  • Para botões self-draw:

    CButton:DrawItem(LPDRAWITEMSTRUCT);
            // insert code to draw this button
    
  • Para menus self-draw:

    CMenu:MeasureItem(LPMEASUREITEMSTRUCT);
            // insert code to measure the size of an item in this menu
    CMenu:DrawItem(LPDRAWITEMSTRUCT);
            // insert code to draw an item in this menu
    
  • Para caixas de listagem self-draw:

    CListBox:MeasureItem(LPMEASUREITEMSTRUCT);
            // insert code to measure the size of an item in this list box
    CListBox:DrawItem(LPDRAWITEMSTRUCT);
            // insert code to draw an item in this list box
    
    CListBox:CompareItem(LPCOMPAREITEMSTRUCT);
            // insert code to compare two items in this list box if LBS_SORT
    CListBox:DeleteItem(LPDELETEITEMSTRUCT);
            // insert code to delete an item from this list box
    
  • Para caixas de combinação self-draw:

    CComboBox:MeasureItem(LPMEASUREITEMSTRUCT);
            // insert code to measure the size of an item in this combo box
    CComboBox:DrawItem(LPDRAWITEMSTRUCT);
            // insert code to draw an item in this combo box
    
    CComboBox:CompareItem(LPCOMPAREITEMSTRUCT);
            // insert code to compare two items in this combo box if CBS_SORT
    CComboBox:DeleteItem(LPDELETEITEMSTRUCT);
            // insert code to delete an item from this combo box
    

Para obter detalhes sobre as estruturas proprietário-draw (DRAWITEMSTRUCT, MEASUREITEMSTRUCT, COMPAREITEMSTRUCT, and DELETEITEMSTRUCT) Consulte a documentação do MFC para CWnd::OnDrawItem, CWnd::OnMeasureItem, CWnd::OnCompareItem, e CWnd::OnDeleteItem respectivamente.

Usando controles self-draw e menus

Para menus self-draw, você deve substituir o OnMeasureItem e OnDrawItem métodos.

Para self-draw lista caixas e caixas de combinação, você deve substituir OnMeasureItem e OnDrawItem. Você deve especificar o LBS_OWNERDRAWVARIABLE estilo para lista caixas ou CBS_OWNERDRAWVARIABLE estilo de caixas de combinação no modelo de caixa de diálogo. The OWNERDRAWFIXED estilo não funcionará com itens self-draw porque altura fixa de item é determinada antes que controles self-draw ao lista caixa. (Você pode usar os métodos CListBox::SetItemHeight e CComboBox::SetItemHeight para superar essa limitação.)

Alternar para um OWNERDRAWVARIABLE estilo forçará o sistema para aplicar a NOINTEGRALHEIGHT estilo para o controle. Porque o controle não pode calcular uma altura integral com itens de tamanho variáveis, o estilo padrão de INTEGRALHEIGHT é ignorado e o controle é sempre NOINTEGRALHEIGHT. Se os itens forem corrigidos altura, você pode evitar que itens parcial que está sendo desenhado, especificando o dimensionar do controle como um multiplicador de inteiro do dimensionar do item.

Para self-desenho lista caixas e caixas de combinação com o LBS_SORT ou CBS_SORT estilo, você deve substituir o OnCompareItem método.

Para self-desenho lista caixas e caixas de combinação, OnDeleteItem não é geralmente substituído. Você pode substituir OnDeleteItem Se você quiser realizar qualquer processamento especial. Um caso onde isso seria aplicável é quando a memória adicional ou outros recursos são armazenados com cada lista item da caixa de combinação ou caixa.

Exemplos de Self-desenho Menus e controles

O exemplo de MFC geral CTRLTEST fornece exemplos de um menu self-draw e uma caixa de listagem self-draw.

O exemplo mais comum de um botão self-desenho é um botão de bitmap.Um botão de bitmap é um botão que mostra um, dois ou três imagens de bitmap para os diferentes estados.Um exemplo disso é fornecido no MFC classe CBitmapButton.

Subclassing dinâmico

Ocasionalmente, você deverá alterar a funcionalidade de um objeto que já existe.Os exemplos anteriores necessário personalizar os controles antes de terem sido criados.Subclassificação dinâmica permite personalizar um controle que já foi criado.

Subclassificação é o termo Windows para substituir o WndProc de uma janela com um personalizado WndProc e chamando o antigo WndProc para a funcionalidade padrão.

Não deve ser confundido com derivação de classe do C++.Para fins de esclarecimento, o C++ termos classe base and classe derivada são análogos aos superclasse and subclasse no modelo de objeto do Windows.Derivação de C++ com subclassificação MFC e do Windows são funcionalmente semelhantes, exceto C++ não dá suporte a subclassificação dinâmica.

The CWnd classe fornece a conexão entre um objeto C++ (derivado de CWnd) e um objeto de janela do Windows (conhecido sistema autônomo um HWND).

Há três maneiras comuns que eles estão relacionados:

  • CWnd cria o HWND. Você pode modificar o comportamento em uma classe derivada, criando uma classe derivada de CWnd. The HWND é criado quando o aplicativo chama CWnd::criar.

  • O aplicativo anexa um CWnd para um existente HWND. O comportamento de janela existente não é modificado.Este é um caso de delegação e é possibilitado pela chamada CWnd::anexar ao alias existente HWND para um CWnd objeto.

  • CWnd anexado a um existente HWND e você pode modificar o comportamento em uma classe derivada. Isso é chamado de subclassificação porque estamos alterando o comportamento e, portanto, a classe, de um objeto do Windows em time de execução dinâmico.

Você pode obter subclassificação dinâmica usando os métodos CWnd::SubclassWindow eCWnd::SubclassDlgItem.

Ambas as rotinas de anexar um CWnd objeto para um existente HWND. SubclassWindow leva a HWND diretamente. SubclassDlgItem é uma função auxiliar que leva a uma ID de controle e a janela pai. SubclassDlgItem destina-se anexar objetos C++ a controles de caixa de diálogo criados a partir de um modelo de caixa de diálogo.

Consulte o CTRLTEST exemplo vários exemplos de quando usar SubclassWindow e SubclassDlgItem.

Consulte também

Outros recursos

Notas técnicas por número

Notas técnicas por categoria