TN014: controles personalizados
Essa observação descreve o suporte MFC para controles personalizadas e de desenho do. Também descreve subclassing dinâmico, e descreve a relação entre os objetos de CWnd e o HWNDS.
O aplicativo de exemplo CTRLTEST MFC ilustra como usar muitos controles personalizados. Consulte o código-fonte do exemplo CTRLTEST gerais de MFC e a ajuda online.
Controles/menus de Proprietário- descompasso
As janelas oferecem suporte para controles e menus de proprietário- descompasso usando mensagens do windows. A janela pai de todo o controle ou menu recebe essas mensagens e chama funções na resposta. Você pode substituir essas funções para personalizar a aparência e o comportamento visuais de seu controle ou o menu de proprietário- descompasso.
MFC O oferece suporte diretamente a proprietário- desenhe séries com as seguintes funções:
Você pode substituir essas funções em sua classe derivada de CWnd para implementar o comportamento personalizado de descompasso.
Essa abordagem não resulta no código reutilizável. Se você tiver dois controles semelhantes em duas classes diferentes de CWnd , você deve implementar o comportamento de controle personalizado em dois locais. A arquitetura MFC- suporte de controle de desenho do resolve o problema.
Controles e menus da descompasso
MFC O fornece uma implementação padrão (em classes de CWnd e de CMenu ) para as mensagens padrão de proprietário- descompasso. Essa implementação padrão descriptocrafará os parâmetros de proprietário- descompasso e delegará as mensagens de proprietário- desenhe séries nos controles ou ao menu. Isso é chamado de descompasso porque o código de desenho está na classe de controle ou no menu, a janela do proprietário.
Usando controles da descompasso você pode criar as classes reutilizáveis de controle que usam a semântica de proprietário- descompasso para exibir o controle. O código para desenhar o controle está na classe de controle, não o pai. Esta é uma abordagem orientado a objeto da programação de controle personalizado. Adicione a seguinte lista de funções às suas classes da descompasso:
Para os botões da descompasso:
CButton:DrawItem(LPDRAWITEMSTRUCT); // insert code to draw this button
Para menus da descompasso:
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 da descompasso:
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 da descompasso:
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 nas estruturas de proprietário- descompasso (DRAWITEMSTRUCT, MEASUREITEMSTRUCT, COMPAREITEMSTRUCT, e) DELETEITEMSTRUCTconsulte a documentação de MFC para CWnd::OnDrawItem, CWnd::OnMeasureItem, CWnd::OnCompareItem, e CWnd::OnDeleteItem respectivamente.
Usando controles e menus da descompasso
Para menus da descompasso, você deve substituir os métodos de OnMeasureItem e de OnDrawItem .
Para caixas de listagem e caixas de combinação da descompasso, você deve substituir OnMeasureItem e OnDrawItem. Você deve especificar o estilo de LBS_OWNERDRAWVARIABLE para caixas de listagem ou o estilo de CBS_OWNERDRAWVARIABLE para caixas de combinação no modelo da caixa de diálogo. O estilo de OWNERDRAWFIXED não funcionará com itens da desenhe séries como a altura do item fixa é determinada antes que os controles da descompasso estão anexados à caixa de listagem. (Você pode usar os métodos CListBox::SetItemHeight e CComboBox::SetItemHeight para superar esta restrição.)
A alternância como um estilo de OWNERDRAWVARIABLE forçará o sistema para aplicar estilo de NOINTEGRALHEIGHT ao controle. Como o controle não pode calcular uma altura integral com variável - os itens feito sob medida, o estilo padrão de INTEGRALHEIGHT são ignorados e o controle é sempre NOINTEGRALHEIGHT. Se os itens são a altitude fixa, você pode evitar que os itens parciais são desenhados especificando o tamanho do controle para ser um multiplicador do tamanho do item.
Para caixas de listagem e caixas de combinação de desenho com o estilo de LBS_SORT ou de CBS_SORT , você deve substituir o método de OnCompareItem .
Para caixas de listagem e caixas de combinação de desenho, OnDeleteItem não for substituído em geral. Você pode substituir OnDeleteItem se você desejar executar qualquer processamento especial. Um caso em que isso seria é aplicável quando a memória adicional ou outros recursos são armazenados com cada item da caixa de listagem ou na caixa de combinação.
Exemplos de controles e de menus do de desenho
O exemplo CTRLTEST gerais de MFC fornece exemplos de um menu da descompasso e uma caixa de listagem da descompasso.
O exemplo mais comum de um botão de desenho do é um botão de bitmap. Um botão de bitmap é um botão que mostra uma, duas, três ou imagens de bitmap para os estados diferentes. Um exemplo disso é fornecido na classe CBitmapButtonMFC.
Subclassing dinâmico
Ocasionalmente você pode querer alterar a funcionalidade de um objeto que já existe. Os exemplos anteriores exigiram-no personalizar os controles antes que foram criados. Subclassing dinâmico permite que você personalize um controle que já foi criado.
Subclassing é o termo do windows para substituir WndProc de uma janela com WndProc personalizado e chamar WndProc antiga para a funcionalidade padrão.
Isso não deve ser confundido com a derivação da classe C++. Para limpar o, os termos classe base do C++ e a classe derivada são análogos a superclass e a subclasse no modelo de objeto do windows. A derivação C++ com MFC e o windows que são semelhantes subclassing funcional, a não ser que C++ não oferece suporte subclassing dinâmico.
A classe de CWnd fornece a conexão entre o objeto c criando (derivado de CWnd) e um objeto da janela do windows (conhecido como HWND).
Há três maneiras comuns que são relacionados:
CWnd cria HWND. Você pode modificar o comportamento em uma classe derivada criando uma classe derivada de CWnd. HWND é criado quando o aplicativo chama CWnd::Create.
O aplicativo CWnd anexa a HWNDexistente. O comportamento da janela existente não é alterado. Este é um caso de delegação e é possível chamar CWnd::Attach ao alias HWND existente a um objeto de CWnd .
CWnd é anexado a HWND existente e você pode modificar o comportamento em uma classe derivada. Isso é chamado subclassing dinâmico porque nós estamos alterando o comportamento e, consequentemente, a classe do windows objetos em tempo de execução.
Você pode obter subclassing dinâmica usando os métodos CWnd::SubclassWindow eCWnd::SubclassDlgItem.
Ambas as rotinas anexar um objeto de CWnd a HWNDexistente. SubclassWindow usa HWND diretamente. SubclassDlgItem é uma função auxiliar que usa um ID de controle e a janela pai. SubclassDlgItem é criado anexando objetos C++ aos controles da caixa de diálogo criados de um modelo da caixa de diálogo.
Consulte o exemplo de CTRLTEST para vários exemplos de quando usar SubclassWindow e SubclassDlgItem.