Compartilhar via


TN061: mensagens ON_NOTIFY e WM_NOTIFY

Dica

A nota técnica a seguir não foi atualizada desde que ela foi incluída pela primeira vez na documentação online.Como resultado, alguns procedimentos e tópicos podem estar incorretos ou expirados.Para obter as informações mais recentes, é recomendável que você procure o tópico de interesse no índice de documentação online.

Observe que essa técnica fornece informações gerais na nova mensagem de WM_NOTIFY e descreve (e mais comum) a maneira recomendada de tratar mensagens de WM_NOTIFY em seu aplicativo MFC.

Notificações nas janelas 3.x

Nas janelas 3.x, os controles notificam seus pais de eventos como cliques do mouse, alterações no conteúdo e seleção, e pintura em segundo plano do controle enviando uma mensagem ao pai. As notificações são enviadas mensagens simples como especiais de WM_COMMAND , com o código de notificação (como BN_CLICKED) e a ID do controle empacotados em wParam e o identificador de controle em lParam. Observe que desde wParam e lParam não está completo, não há nenhuma forma de transmitir todos os dados adicionais — essas mensagens podem ser apenas notificação simples. Por exemplo, na notificação de BN_CLICKED , não há como enviar informações sobre o local do cursor do mouse quando o usuário clicou no botão.

Quando os controles nas janelas 3.x precisa enviar uma notificação que inclua dados adicionais, use uma variedade de mensagens do objetivo especial, incluindo WM_CTLCOLOR, WM_VSCROLL, WM_HSCROLL, WM_DRAWITEM, WM_MEASUREITEM, WM_COMPAREITEM, WM_DELETEITEM, WM_CHARTOITEM, WM_VKEYTOITEM, e assim por diante. Essas mensagens podem ser refletidas de volta para controlar as enviadas. Para obter mais informações, consulte TN062: Reflexão de mensagem para controles do windows.

Notificações no Win32

Para os controles que existiam no Windows 3.1, os usos da API do Win32 mais das notificações que foram usadas nas janelas 3.x. No entanto, o Win32 também adiciona um número de controles sofisticados, complexos para aqueles com suporte no windows 3.x. Frequentemente, necessidade desses controles de enviar dados adicionais com as notificações. Em vez de adicionando uma nova mensagem de WM_* para cada nova notificação de que precisa de dados adicionais, os designers da API do Win32 escolhidos para adicionar apenas uma mensagem, WM_NOTIFY, que podem passar qualquer quantidade de dados adicionais em uma forma padronizado.

As mensagens deWM_NOTIFY contém a ID de controle que envia a mensagem em wParam e um ponteiro para uma estrutura em lParam. Essa estrutura é uma estrutura de NMHDR ou alguma estrutura maior que tem uma estrutura de NMHDR como seu primeiro membro. Observe que desde que o membro de NMHDR é primeiro, um ponteiro a essa estrutura pode ser usado como um ponteiro para NMHDR ou como um ponteiro para a estrutura maior dependendo de como você converter a ele.

Na maioria dos casos, o ponteiro apontará para uma estrutura maior e você precisará ser convertida quando você a usará. Somente em algumas notificações, como as notificações comuns de notificações (cujos nomes começam com NM_) e de TTN_SHOW e de TTN_POP de controle da dica de ferramenta, é uma estrutura de NMHDR de fato usada.

A estrutura de NMHDR ou o membro inicial contém o identificador e o ID de controle que envia a mensagem e o código de notificação (como TTN_SHOW). O formato da estrutura de NMHDR é mostrado abaixo:

typedef struct tagNMHDR {
    HWND hwndFrom;
    UINT idFrom;
    UINT code;
} NMHDR;

Para uma mensagem de TTN_SHOW , o membro de code seria definido como TTN_SHOW.

A maioria das notificações transmite um ponteiro para uma estrutura maior que contém uma estrutura de NMHDR como seu primeiro membro. Por exemplo, considere a estrutura usada pela notificação de LVN_KEYDOWN do controle de exibição de lista, que é enviado quando uma chave é pressionada em um controle de exibição de lista. O ponteiro para uma estrutura de LV_KEYDOWN , que é definida como mostrado abaixo:

typedef struct tagLV_KEYDOWN {
    NMHDR hdr;   
    WORD wVKey;  
    UINT flags;  
} LV_KEYDOWN;

Observe que desde que o membro de NMHDR é primeiro nessa estrutura, o ponteiro que você for transmitido na notificação pode ser convertido em um ponteiro para NMHDR ou a um ponteiro para LV_KEYDOWN.

Notificações comuns a todos os controles do windows

Algumas notificações são comuns a todos os controles do windows. Essas notificações transmite um ponteiro para uma estrutura de NMHDR .

Código de notificação

Enviado como

NM_CLICK

O usuário clicou o botão esquerdo do mouse no controle

NM_DBLCLK

O usuário clicou duas vezes no botão esquerdo do mouse no controle

NM_RCLICK

O usuário clicou o botão direito do mouse no controle

NM_RDBLCLK

O usuário clicou duas vezes no botão direito do mouse no controle

NM_RETURN

O usuário pressionou a tecla ENTER quando o controle entre o foco

NM_SETFOCUS

Controle foi atribuído o foco de entrada

NM_KILLFOCUS

O controle perder o foco de entrada

NM_OUTOFMEMORY

O controle não foi possível concluir uma operação porque não há memória suficiente disponível

ON_NOTIFY: Mensagens de manipulação WM_NOTIFY em aplicativos de MFC

As notificações das alças de CWnd::OnNotify da função. Sua implementação padrão verifica o mapa de mensagem para que os manipuladores de notificação chame. Em geral, você não OnNotifysubstitui. Em vez disso, você fornece uma função de manipulador e adiciona uma entrada retornadas mapa para o manipulador no mapa da mensagem da classe da janela do proprietário.

ClassWizard, por meio da folha de propriedades de ClassWizard, pode criar a entrada retornadas mapa de ON_NOTIFY e fornecê-lo uma função de esqueleto do manipulador. Para obter mais informações sobre como usar ClassWizard mais fácil para fazer isso, consulte Mensagens de mapeamento a funções.

A macro retornadas mapa de ON_NOTIFY tem a seguinte sintaxe:

ON_NOTIFY( wNotifyCode, id, memberFxn )

onde parâmetros italicizados são substituídos por:

  • wNotifyCode
    O código para o qual a notificação é tratada, como LVN_KEYDOWN.

  • id
    O identificador filho do controle para o qual a notificação é enviada.

  • memberFxn
    A função de membro a ser chamada quando essa notificação é enviada.

A função de membro deve ser declarada com o seguinte protótipo:

afx_msg void memberFxn( NMHDR * pNotifyStruct, LRESULT * result );

Comentários

onde parâmetros italicizados são:

  • pNotifyStruct
    Um ponteiro para a estrutura de notificação, como descrito na seção anterior.

  • resultado
    Um ponteiro para o código de resultado você definirá antes de retornar.

Exemplo

Para especificar que a função de membro OnKeydownList1 para tratar mensagens de LVN_KEYDOWN de CListCtrl cujo ID é IDC_LIST1, você usaria o seguinte ClassWizard para adicionar a seu mapa de mensagem:

ON_NOTIFY( LVN_KEYDOWN, IDC_LIST1, OnKeydownList1 )

No exemplo anterior, a função é fornecida por 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 fornece um ponteiro de tipo apropriado automaticamente. Você pode acessar a estrutura de notificação com pNMHDR ou pLVKeyDow.

ON_NOTIFY_RANGE

Se você precisa processar a mesma mensagem de WM_NOTIFY 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 para que você deseja executar a mesma ação para uma determinada notificação.

Quando você usa ON_NOTIFY_RANGE, você especifica um intervalo contíguo de identificadores filho para o qual a notificação para lidar com especificando identificadores filhos de início e de término do intervalo.

ClassWizard não controla ON_NOTIFY_RANGE; para isso, você precisa editar seu mapa de mensagem você mesmo.

O protótipo de entrada e de são retornadas mapa para ON_NOTIFY_RANGE é a seguinte:

ON_NOTIFY_RANGE( wNotifyCode, id, idLast, memberFxn )

onde parâmetros italicizados são substituídos por:

  • wNotifyCode
    O código para o qual a notificação é tratada, como LVN_KEYDOWN.

  • id
    O primeiro identificador no intervalo contíguo de identificadores.

  • idLast
    O identificador do último no intervalo contíguo de identificadores.

  • memberFxn
    A função de membro a ser chamada quando essa notificação é enviada.

A 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 parâmetros italicizados são:

  • id
    O identificador filho do controle que enviou a mensagem de notificação.

  • pNotifyStruct
    Um ponteiro para a estrutura de notificação, como descrito acima.

  • resultado
    Um ponteiro para o código de resultado você definirá antes de retornar.

ON_NOTIFY_EX, ON_NOTIFY_EX_RANGE

Se você desejar mais de um objeto no roteamento de notificação para tratar de 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 a versão de EX e a versão comum é que a função de membro chamada para a versão de EX retorna BOOL que indica se o processamento da mensagem deve continuar. Retornar Falso dessa função permite processar a mesma mensagem em mais de um objeto.

ClassWizard não controla ON_NOTIFY_EX ou ON_NOTIFY_EX_RANGE; se você quiser usar qualquer um deless, você precisa editar seu mapa de mensagem você mesmo.

O protótipo de entrada e de são retornadas mapa para ON_NOTIFY_EX e ON_NOTIFY_EX_RANGE são como se segue. Os significados dos parâmetros são os mesmos que para as versões não deEX .

ON_NOTIFY_EX( nCode, id, memberFxn ) 
ON_NOTIFY_EX_RANGE( wNotifyCode, id, idLast, memberFxn )

O protótipo para o anterior é o mesmo:

afx_msg BOOL memberFxn( UINT id, NMHDR * pNotifyStruct, LRESULT * result );

Comentários

Em ambos os casos, id contém o identificador filho do controle que enviou a mensagem de notificação.

A função deve retornar Verdadeiro se a notificação esteve tratada por ou Falso se outros objetos no roteamento do comando tenha uma possibilidade tratar a mensagem.

Consulte também

Outros recursos

Observações técnicas por número

Observações técnicas por categoria