TN061: ON_NOTIFY e WM_NOTIFY mensagens
Observação |
---|
A seguinte nota técnica não foi atualizada desde que foi incluída pela primeira vez na documentação online.Como resultado, alguns procedimentos e tópicos podem estar desatualizado ou incorreto.As informações mais recentes, é recomendável que você procure o tópico de interesse no índice de documentação on-line. |
Esta nota técnica fornece informações básicas sobre o novo WM_NOTIFY mensagem e descreve a forma recomendada (e mais comum) de manipulação de WM_NOTIFY mensagens em seu aplicativo do MFC.
Mensagens de notificação no Windows 3. x
No Windows 3. x, controles notificam seus pais de eventos, como cliques de mouse, alterações no conteúdo e seleção e pintura de plano de fundo do controle, enviando uma mensagem para o pai.Notificações simples são enviadas como especiais WM_COMMAND mensagens, com o código de notificação (como BN_CLICKED) e controle ID embalada em wParam e o identificador do controle de lParam.Observe que, como wParam e lParam são completo, não há nenhuma maneira de passar dados adicionais — essas mensagens podem ser apenas notificação simple.Por exemplo, no BN_CLICKED notificação, não é possível enviar informações sobre o local do cursor do mouse quando o botão foi clicado.
Quando precisam de controles no Windows 3. x enviar uma mensagem de notificação inclui dados adicionais, eles usam uma variedade de mensagens de finalidade especial, incluindo WM_CTLCOLOR, WM_VSCROLL, WM_HSCROLL, WM_DRAWITEM, WM_MEASUREITEM, WM_COMPAREITEM, WM_DELETEITEM, WM_CHARTOITEM, WM_VKEYTOITEMe assim por diante.Essas mensagens podem ser refletidas de volta para o controle que os enviaram.Para obter mais informações, consulte TN062: reflexo de mensagem para controles de Windows.
Mensagens de notificação no Win32
Para controles que existiram no Windows 3.1, a API do Win32 usa a maioria das mensagens de notificação que foram usadas no Windows 3. x.No entanto, Win32 também adiciona um número de controles sofisticados e complexos suportados no Windows 3. x.Freqüentemente, esses controles precisam enviar dados adicionais com suas mensagens de notificação.Em vez de adicionar um novo WM _ * mensagem para cada nova notificação de que precisa de dados adicionais, os designers da API do Win32 optar por adicionar apenas uma mensagem WM_NOTIFY, que pode passar qualquer quantidade de dados adicionais de maneira padronizada.
WM_NOTIFY mensagens contêm a identificação do controle enviando a mensagem wParam e um ponteiro para uma estrutura de lParam.Essa estrutura é uma NMHDR estrutura ou alguns maiores que tem uma NMHDR estrutura como seu primeiro membro.Observe que, como o NMHDR é o primeiro membro, um ponteiro para essa estrutura pode ser usado como um ponteiro para um NMHDR ou como um ponteiro para a estrutura maior dependendo de como lançá-lo.
Na maioria dos casos, o ponteiro irá apontar para uma estrutura maior e você precisará lançá-lo quando você usá-lo.Em apenas algumas notificações, como notificações comuns (cujos nomes começam com NM_) e o controle de dica de ferramenta TTN_SHOW e TTN_POP notificações, é um NMHDR estrutura usada realmente.
O NMHDR estrutura ou membro inicial contém o identificador e a identificação do controle enviando a mensagem e o código de notificação (como TTN_SHOW).O formato de NMHDR estrutura é mostrada abaixo:
typedef struct tagNMHDR {
HWND hwndFrom;
UINT idFrom;
UINT code;
} NMHDR;
Para um TTN_SHOW mensagem, o código membro seria definido como TTN_SHOW.
A maioria das notificações passarem um ponteiro para uma estrutura maior que contém um NMHDR estrutura como seu primeiro membro.Por exemplo, considere a estrutura usada pelo controle de exibição lista LVN_KEYDOWN mensagem de notificação é enviada quando uma tecla é pressionada em um controle de exibição de lista.O ponteiro aponta para uma LV_KEYDOWN estrutura, que é definida como mostrado abaixo:
typedef struct tagLV_KEYDOWN {
NMHDR hdr;
WORD wVKey;
UINT flags;
} LV_KEYDOWN;
Observe que, como o NMHDR membro é primeiro nessa estrutura, o ponteiro é passado a mensagem de notificação pode ser convertido para um ponteiro para um NMHDR ou um ponteiro para um LV_KEYDOWN.
Notificações comum a todos os novos controles do Windows
Algumas notificações são comuns a todos os novos controles de Windows.Essas notificações passarem um ponteiro para um NMHDR estrutura.
Código de notificação |
Enviada porque |
---|---|
NM_CLICK |
Usuário clicado o botão esquerdo do mouse no controle |
NM_DBLCLK |
Botão esquerdo do mouse clicado duas vezes de usuário no controle |
NM_RCLICK |
Usuário clicou o botão direito do mouse no controle |
NM_RDBLCLK |
Botão direito do mouse clicado duas vezes de usuário no controle |
NM_RETURN |
Usuário pressionou a tecla ENTER enquanto o controle tem foco de entrada |
NM_SETFOCUS |
Controle tem foco de entrada |
NM_KILLFOCUS |
Controle perdeu o foco de entrada |
NM_OUTOFMEMORY |
Controle não pôde concluir uma operação porque não havia memória suficiente disponível |
ON_NOTIFY: Manipulação WM_NOTIFY mensagens em aplicativos MFC
A função CWnd::OnNotify manipula mensagens de notificação.Sua implementação padrão verifica o mapa da mensagem para manipuladores de notificação chamar.Em geral, você não substituir OnNotify.Em vez disso, você pode fornece uma função de manipulador e adicionar uma entrada de mapa da mensagem para esse manipulador ao mapa da mensagem da classe da janela do proprietário.
ClassWizard, por meio da folha de propriedades ClassWizard, pode criar o ON_NOTIFY entrada do mapa da mensagem e fornecer uma função de manipulador de esqueleto.Para obter mais informações sobre como usar ClassWizard para facilitar isso, consulte Mapeamento mensagens para funções.
O ON_NOTIFY macro de mapa da mensagem tem a seguinte sintaxe:
ON_NOTIFY( wNotifyCode, id, memberFxn )
onde os parâmetros em itálico são substituídos por:
wNotifyCode
O código para a mensagem de notificação ser manipulado, como LVN_KEYDOWN.id
O identificador de filho do controle para o qual a notificação é enviada.memberFxn
A função de membro a ser chamado quando esta notificação é enviada.
Sua função de membro deve ser declarada com o seguinte protótipo:
afx_msg void memberFxn( NMHDR * pNotifyStruct, LRESULT * result );
Comentários
onde os parâmetros em itálico são:
pNotifyStruct
Um ponteiro para a estrutura de notificação, conforme descrito na seção acima.resultado
Um ponteiro para o código de resultado você irá definir antes de retornar.
Exemplo
Para especificar que você deseja que a função de membro OnKeydownList1 para tratar LVN_KEYDOWN mensagens do CListCtrl cuja ID é IDC_LIST1, você usaria ClassWizard para adicionar o seguinte ao mapa de mensagem:
ON_NOTIFY( LVN_KEYDOWN, IDC_LIST1, OnKeydownList1 )
No exemplo acima, a função fornecida pelo ClassWizard é:
void CMessageReflectionDlg::OnKeydownList1(NMHDR* pNMHDR, LRESULT* pResult)
{
LV_KEYDOWN* pLVKeyDow = (LV_KEYDOWN*)pNMHDR;
// TODO: Add your control notification handler
// code here
*pResult = 0;
}
Observe que ClassWizard oferece um ponteiro de tipo apropriado automaticamente.Você pode acessar a estrutura de notificação por meio de um pNMHDR ou pLVKeyDow.
ON_NOTIFY_RANGE
Se você precisar processar a mesma WM_NOTIFY mensagem para um conjunto de controles, você pode usar ON_NOTIFY_RANGE em vez de ON_NOTIFY.Por exemplo, você pode ter um conjunto de botões que você deseja executar a mesma ação para uma determinada mensagem de notificação.
Quando você usa ON_NOTIFY_RANGE, especifique um intervalo contíguo de identificadores de filho para manipular a mensagem de notificação, especificando o início e final de identificadores de filho do intervalo.
ClassWizard não trata ON_NOTIFY_RANGE; para usá-lo, você precisa editar o mapa de mensagem você mesmo.
O protótipo de função e entrada de mapa de mensagens para ON_NOTIFY_RANGE são como segue:
ON_NOTIFY_RANGE( wNotifyCode, id, idLast, memberFxn )
onde os parâmetros em itálico são substituídos por:
wNotifyCode
O código para a mensagem de notificação ser manipulado, como LVN_KEYDOWN.id
O primeiro identificador no intervalo contíguo de identificadores.idLast
O último identificador no intervalo contíguo de identificadores.memberFxn
A função de membro a ser chamado quando esta notificação é enviada.
Sua função de membro deve ser declarada com o seguinte protótipo:
afx_msg void memberFxn( UINT id, NMHDR * pNotifyStruct, LRESULT * result );
Comentários
onde os parâmetros em itálico são:
id
O identificador de filho do controle que enviou a notificação.pNotifyStruct
Um ponteiro para a estrutura de notificação, conforme descrito acima.resultado
Um ponteiro para o código de resultado você irá definir antes de retornar.
ON_NOTIFY_EX, ON_NOTIFY_EX_RANGE
Se desejar mais de um objeto na notificação roteamento para manipular uma mensagem, você pode usar ON_NOTIFY_EX (ou ON_NOTIFY_EX_RANGE) em vez de ON_NOTIFY (ou ON_NOTIFY_RANGE).A única diferença entre o EX versão e a versão normal é chamada de função de membro para o EX versão retorna um BOOL que indica se ou não o processamento da mensagem deve continuar.Retornar FALSE essa função permite processar a mesma mensagem em mais de um objeto.
ClassWizard não trata ON_NOTIFY_EX ou ON_NOTIFY_EX_RANGE; Se você desejar usar qualquer um deles, você precisará editar o mapa de mensagem você mesmo.
O protótipo de função e entrada de mapa de mensagens para ON_NOTIFY_EX e ON_NOTIFY_EX_RANGE são como segue.O significado dos parâmetros é os mesmos para o não-EX versões.
ON_NOTIFY_EX( nCode, id, memberFxn )
ON_NOTIFY_EX_RANGE( wNotifyCode, id, idLast, memberFxn )
O protótipo para ambos acima é o mesmo:
afx_msg BOOL memberFxn( UINT id, NMHDR * pNotifyStruct, LRESULT * result );
Comentários
Em ambos os casos, id contém o identificador de filho do controle que enviou a notificação.
A função deve retornar TRUE se a mensagem de notificação foi tratada completamente ou FALSE se outros objetos no roteamento de comando devem ter a oportunidade de manipular a mensagem.