TN062: Mensagem de reflexão para controles do Windows
Observação: |
---|
A seguinte nota técnica não foi atualizada desde que foi incluída pela primeira vez na documentação online.sistema autônomo resultado, alguns procedimentos e tópicos podem estar desatualizado ou incorreto.Para obter informações mais recentes, é recomendável que você procurar o tópico de interesse no índice de documentação online. |
Esta nota técnica descreve reflexão de mensagem, um novo recurso do MFC 4.0.Ele também contém instruções para a criação de um controle reutilizável simples que usa a reflexão de mensagem.
Esta nota técnica não aborda a mensagem reflexão sistema autônomo ela se aplica a controles ActiveX (anteriormente chamado de controles OLE).Consulte o artigo Controles ActiveX: Subclassificação um controle Windows.
O que é o reflexão de mensagem?
Controles do Windows freqüentemente enviam mensagens de notificação para suas janelas de pai.Para instância, muitos controles enviar uma mensagem de notificação do controle de cor (WM_CTLCOLOR ou uma de suas variantes) para seus pais para permitir que o pai fornecer um pincel para pintar o plano de fundo do controle.
No Windows e no MFC antes da versão 4.0, a janela pai, geralmente uma caixa de diálogo, é responsável pela manipulação dessas mensagens.Isso significa que o código para manipular a mensagem precisa ser na classe da janela pai e que deve ser duplicada em cada classe que precisa para lidar com essa mensagem.Nesse caso, cada caixa de diálogo que queria controles com planos de fundo personalizados teria que lidar com a mensagem de notificação do controle cor.Seria muito mais fácil de reutilizar código se uma classe de controle poderia ser escrita que trataria sua própria cor do plano de fundo.
No MFC 4.0, o mecanismo antigo ainda funciona — janelas pai podem lidar com mensagens de notificação.Além disso, no entanto, MFC 4.0 facilita reutilização, fornecendo um recurso chamado "mensagem de reflexão" que permite que essas mensagens de notificação ser manipulado no janela do controle filho ou a janela pai ou em ambos.No exemplo de cor do plano de fundo de controle, você agora pode escrever uma classe de controle que define sua própria cor do plano de fundo, manipulando o refletido WM_CTLCOLOR mensagem — tudo isso sem depender do pai. (Observe que, já que a reflexão de mensagem é implementada pelo MFC, não pelo Windows, a classe de janela pai deve ser derivada de CWnd para reflexão mensagem funcione.)
Versões mais antigas do MFC foram algo similar à mensagem reflexão, fornecendo funções virtual para algumas mensagens, sistema autônomo mensagens para caixas de listagem de desenho proprietário (WM_DRAWITEMe assim por diante). O novo mecanismo de reflexão de mensagem é generalizada e consistente.
Mensagem de reflexão é retrocompatível com código escrito para versões do MFC antes de 4.0.
Se você tiver fornecido um manipulador para uma mensagem específica ou para um intervalo de mensagens, na classe da janela pai, ele irá substituir refletem manipuladores de mensagens para a mesma mensagem desde que você não chamar a função de manipulador de classe base no seu próprio manipulador.Por exemplo, se você tratar WM_CTLCOLOR na sua classe de caixa de diálogo, a sua manipulação substituirão quaisquer manipuladores de mensagens refletido.
Se, na sua classe de janela pai, você fornecer um manipulador para um específico WM_NOTIFY mensagem ou um intervalo de WM_NOTIFY mensagens, o manipulador será chamado somente se o controle filho enviando essas mensagens não tiver um manipulador de mensagens refletida através de ON_NOTIFY_REFLECT().Se você usar ON_NOTIFY_REFLECT_EX() no MAP da mensagem, seu manipulador de mensagens pode ou não permitir que a janela pai manipular a mensagem.Se o manipulador retornará FALSE, a mensagem será manipulada pelo pai também, enquanto uma telefonar que retorne TRUE não permite que o pai lidar com ele.Observe que a mensagem refletida é tratada antes da mensagem de notificação.
Quando um WM_NOTIFY mensagem é enviada, o controle é oferecido a chance de manipulá-lo primeira.Se qualquer Outros mensagem refletida for enviada, a janela pai tem a chance de manipulá-lo primeira e o controle receberá a mensagem refletida.Para fazer isso, ele precisará de uma função de manipulador e uma entrada apropriada no MAP da mensagem do controle de classe.
A macro de MAP da mensagem para mensagens refletidas é ligeiramente diferente para notificações regulares: Ele tem _REFLECT acrescentado ao nome normal.Por exemplo, para manipular um WM_NOTIFY mensagem no pai, você usar a macro ON_NOTIFY no MAP da mensagem do pai. Para manipular a mensagem refletida no controle filho, use o ON_NOTIFY_REFLECT macro no MAP da mensagem do controle filho.Em alguns casos, sistema autônomo parâmetros são diferentes, também.Observe que ClassWizard geralmente pode adicionar as entradas de MAP da mensagem para você e fornecer implementações de esqueleto função com parâmetros corretos.
See TN061: Mensagens de WM_NOTIFY e ON_NOTIFY para obter informações sobre o novo WM_NOTIFY mensagem.
Entradas de MAP da mensagem e protótipos de função Handler para mensagens refletidos
Para lidar com uma mensagem de notificação do controle refletido, use o MAP da mensagem macros e protótipos de função listados na tabela abaixo.
ClassWizard geralmente pode adicionar essas entradas de MAP da mensagem para você e fornecer implementações de esqueleto de função.See Definir um manipulador de mensagens para uma mensagem refletida para obter informações sobre como definir manipuladores de mensagens refletidas.
Para converter o nome da mensagem em nome da macro refletido, prepend ON_ e acrescentar**_REFLECT**.Por exemplo, WM_CTLCOLOR torna-se ON_WM_CTLCOLOR_REFLECT.(Para ver as mensagens que podem ser refletidas, fazer a conversão oposta nas entradas de macro na tabela a seguir.)
sistema autônomo três exceções à regra acima são:
A macro WM_COMMAND é de notificações de ON_CONTROL_REFLECT.
A macro WM_NOTIFY reflexos é ON_NOTIFY_REFLECT.
A macro ON_UPDATE_COMMAND_UI Reflexões é ON_UPDATE_COMMAND_UI_REFLECT.
Em cada um desses casos especiais acima, você deve especificar o nome da função de membro manipulador.Em outros casos, você deve usar o nome padrão para a função do manipulador.
Os significados dos parâmetros e valores de retorno das funções estão documentado sob o nome da função ou o nome da função com Em anexado.Por exemplo, CtlColor está documentadaOnCtlColor. Vários manipuladores de mensagens refletido necessário menos parâmetros que os manipuladores semelhantes em uma janela pai.Apenas correspondem aos nomes na tabela a seguir com os nomes dos parâmetros formais na documentação.
Mapeie a entrada |
Protótipo de função |
---|---|
() ON_CONTROL_REFLECT wNotifyCode, memberFxn ) |
afx_msg void memberFxn ( ); |
() ON_NOTIFY_REFLECT wNotifyCode, memberFxn ) |
afx_msg void memberFxn (NMHDR * pNotifyStruct, de resultado LRESULT * ); |
() ON_UPDATE_COMMAND_UI_REFLECT memberFxn ) |
afx_msg void memberFxn ( CCmdUI* pCmdUI ); |
(ON_WM_CTLCOLOR_REFLECT) |
afx_msg HBRUSH CtlColor (CDC * pDC, UINT nCtlColor ); |
(ON_WM_DRAWITEM_REFLECT) |
afx_msg void DrawItem (LPDRAWITEMSTRUCT lpDrawItemStruct ); |
(ON_WM_MEASUREITEM_REFLECT) |
afx_msg void MeasureItem (LPMEASUREITEMSTRUCT lpMeasureItemStruct ); |
(ON_WM_DELETEITEM_REFLECT) |
afx_msg void DeleteItem (LPDELETEITEMSTRUCT lpDeleteItemStruct ); |
(ON_WM_COMPAREITEM_REFLECT) |
int afx_msg CompareItem (LPCOMPAREITEMSTRUCT lpCompareItemStruct ); |
(ON_WM_CHARTOITEM_REFLECT) |
int afx_msg CharToItem (UINT nKey, UINT nIndex ); |
(ON_WM_VKEYTOITEM_REFLECT) |
int afx_msg VKeyToItem (UINT nKey, UINT nIndex ); |
(ON_WM_HSCROLL_REFLECT) |
afx_msg void HScroll (UINT nSBCode, UINT nPos ); |
(ON_WM_VSCROLL_REFLECT) |
afx_msg void VScroll (UINT nSBCode, UINT nPos ); |
(ON_WM_PARENTNOTIFY_REFLECT) |
afx_msg void ParentNotify (UINT message, LPARAM lParam ); |
The ON_NOTIFY_REFLECT and ON_CONTROL_REFLECT macros tem variações que permitem que mais de um objeto (sistema autônomo o controle e seu pai) para lidar com uma determinada mensagem.
Mapeie a entrada |
Protótipo de função |
---|---|
() ON_NOTIFY_REFLECT_EX wNotifyCode, memberFxn ) |
afx_msg BOOL memberFxn (NMHDR * pNotifyStruct, de resultado LRESULT * ); |
() ON_CONTROL_REFLECT_EX wNotifyCode, memberFxn ) |
afx_msg BOOL memberFxn ( ); |
Tratamento refletido mensagens: Um exemplo de um controle reutilizável
Esse exemplo simples cria um controle reutilizável, chamado CYellowEdit. O controle funciona do mesmo sistema autônomo um controle de edição regular, exceto pelo fato de que ele exibe texto em preto no plano de fundo amarelo.Seria fácil adicionar funções de membro que permita o CYellowEdit controle para exibir cores diferentes.
Para testar o exemplo cria um controle reutilizável
criar uma nova caixa de diálogo em um aplicativo existente.Para obter mais informações, consulte o editor da caixa de diálogo tópico.
Você deve ter um aplicativo no qual deseja desenvolver o controle reutilizável.Se você não tiver um aplicativo existente para usar, crie um aplicativo de baseado na caixa de diálogo de mensagens usando AppWizard.
Com o seu projeto carregado no Visual C++, use ClassWizard para criar uma nova classe chamada CYellowEdit com base em CEdit.
Adicione três variáveis de membros para seu CYellowEdit classe. As duas primeiras serão COLORREFvariáveis de Isenção a cor do texto e a cor do plano de fundo.A terceira será um CBrush objeto manterá o pincel para pintar o plano de fundo. The CBrush objeto permite o pincel de uma vez, apenas a referência depois que criar e destruir o pincel automaticamente quando o CYellowEdit controle é destruído.
Inicialize sistema autônomo variáveis de membro, escrevendo o construtor da seguinte maneira:
CYellowEdit::CYellowEdit() { m_clrText = RGB( 0, 0, 0 ); m_clrBkgnd = RGB( 255, 255, 0 ); m_brBkgnd.CreateSolidBrush( m_clrBkgnd ); }
Usando ClassWizard, adicione um manipulador para o refletido WM_CTLCOLOR mensagem para o CYellowEdit classe. Observe que o sinal de igual na frente do nome do mensagem na lista de mensagens, que você pode manipular indica que a mensagem aparecerá.Isso é descrito em Definir um manipulador de mensagens para uma mensagem refletida.
ClassWizard adiciona a seguinte função de macro e o esqueleto do MAP da mensagem para você:
ON_WM_CTLCOLOR_REFLECT() // Note: other code will be in between.... HBRUSH CYellowEdit::CtlColor(CDC* pDC, UINT nCtlColor) { // TODO: Change any attributes of the DC here // TODO: Return a non-NULL brush if the // parent's handler should not be called return NULL; }
Substitua o corpo da função com o seguinte código.O código especifica a cor do texto, a cor do plano de fundo do texto e a cor de plano de fundo para o restante do controle.
pDC->SetTextColor( m_clrText ); // text pDC->SetBkColor( m_clrBkgnd ); // text bkgnd return m_brBkgnd; // ctl bkgnd
Crie um controle de edição na caixa de diálogo e, em seguida, anexá-lo a uma variável de membro clicando duas vezes no controle de edição enquanto pressiona uma tecla de controle.Na caixa de diálogo Adicionar variável de membro, o nome da variável de Concluir e escolher "controle" para a categoria, em seguida, "CYellowEdit" para o tipo de variável.Não se esqueça de conjunto a ordem de tabulação na caixa de diálogo.Além disso, certifique-se de incluir o arquivo de cabeçalho para o CYellowEdit controlar no arquivo de cabeçalho da caixa de diálogo.
Criar e executar seu aplicativo.O controle de edição terá um plano de fundo amarelo.