TN061: ON_NOTIFY e WM_NOTIFY mensagens

ObservaçãoObservaçã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.

Consulte também

Outros recursos

Notas técnicas por número

Notas técnicas por categoria