TN061: Mensagens de WM_NOTIFY e ON_NOTIFY
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 fornece informações básicas sobre o novo WM_NOTIFY mensagem e descreve a maneira recomendada (e mais comum) de lidar WM_NOTIFY mensagens em seu aplicativo MFC.
Mensagens de notificação no Windows 3.x
No Windows 3.x, controles notificam seus pais de eventos, sistema autônomo cliques do mouse altera em conteúdo e seleção e pintura do plano de fundo de controle, enviando uma mensagem para o pai.Simples sistema autônomo notificações são enviadas sistema autônomo especial WM_COMMAND mensagens com o código de notificação (por exemplo, BN_CLICKED) e ID de controle incluídos em wParam e o identificador do controle em lParam. Observe que, desde wParam e lParam está cheio, não é possível passar dados adicionais — essas mensagens podem ser apenas notificação simples. Para instância, 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 controles no Windows 3.x necessário enviar uma mensagem de notificação que 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_VKEYTOITEM, e assim por diante. Essas mensagens podem ser refletidas de volta para o controle que os enviaram.Para obter mais informações, consulte TN062: Mensagem de reflexão para controles Windows.
Mensagens de notificação no Win32
Para controles que existiam no Windows 3.1, a API do Win32 utiliza a maioria das mensagens de notificação que foram usadas no Windows 3.x.No entanto, Win32 também acrescenta uma série de controles sofisticados e complexos à tem suporte 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 uma única mensagem, WM_NOTIFY, que pode passar qualquer quantidade de dados adicionais de maneira padronizada.
WM_NOTIFY mensagens contêm a ID do controle enviando a mensagem em wParam e um ponteiro para uma estrutura no lParam. Essa estrutura é um de um NMHDR estrutura ou alguns estrutura maior que possui um NMHDR estrutura sistema autônomo seu primeiro membro.Observe que, desde o NMHDR membro é o primeiro, um ponteiro para essa estrutura pode ser usado sistema autônomo qualquer um ponteiro para um NMHDR ou sistema autônomo um ponteiro para a estrutura maior dependendo de sistema autônomo lançá-lo.
Na maioria dos casos, o ponteiro irá apontar para uma estrutura maior e você precisará convertê-lo ao usá-lo.Em apenas algumas notificações, sistema autônomo sistema autônomo notificações comuns (cujos nomes começam com NM_) e TTN_SHOW and TTN_POP notificações, é um NMHDR estrutura realmente usada.
The NMHDR estrutura ou membro inicial contém o identificador e a ID do controle enviando a mensagem e o código de notificação (por exemplo, TTN_SHOW).O formato a NMHDR estrutura é mostrada abaixo:
typedef struct tagNMHDR {
HWND hwndFrom;
UINT idFrom;
UINT code;
} NMHDR;
Para um TTN_SHOW mensagem, a código membro seria definido como TTN_SHOW.
A maioria das notificações passarem um ponteiro para uma estrutura maior que contenha um NMHDR estrutura sistema autônomo seu primeiro membro.Considere, por exemplo, a estrutura usada pelo LVN_KEYDOWN notificação de mensagem, que é enviada quando uma tecla é pressionada em um controle de exibição de lista.O ponteiro aponta para um LV_KEYDOWN estrutura, que é definida sistema autônomo mostrado abaixo:
typedef struct tagLV_KEYDOWN {
NMHDR hdr;
WORD wVKey;
UINT flags;
} LV_KEYDOWN;
Observe que, desde o NMHDR membro é o primeiro nessa estrutura, o ponteiro que estiver passado a mensagem de notificação pode ser convertido em um ponteiro para um NMHDR ou um ponteiro para um LV_KEYDOWN.
Notificações comum para controles Windows All New
Algumas notificações são comuns a todos os novos controles do Windows.Essas notificações passarem um ponteiro para um NMHDR estrutura.
Código de notificação |
Enviado porque |
---|---|
NM_CLICK |
Usuário clicado botão do mouse esquerdo do mouse no controle |
NM_DBLCLK |
botão do mouse esquerdo do mouse clica duas vezes de usuário no controle |
NM_RCLICK |
Usuário clicado botão do mouse direito do mouse no controle |
NM_RDBLCLK |
botão do mouse direito do mouse clica duas vezes de usuário no controle |
NM_RETURN |
Usuário pressionou a tecla ENTER enquanto o controle tiver foco de entrada |
NM_SETFOCUS |
Controle tem foco de entrada |
NM_KILLFOCUS |
Controle perdeu o foco de entrada |
NM_OUTOFMEMORY |
Controle não foi possível concluir uma operação porque não havia memória suficiente disponível |
ON_NOTIFY: Tratamento de mensagens WM_NOTIFY em aplicativos MFC
A função CWnd::OnNotify manipula mensagens de notificação. A implementação padrão verifica o MAP da mensagem para manipuladores de notificação chamar.Em geral, não substituem OnNotify. Em vez disso, fornecem uma função de manipulador e adicionar uma entrada de MAP da mensagem para esse manipulador ao MAP da mensagem da classe da janela do proprietário.
ClassWizard, através da folha de propriedades ClassWizard, pode criar o ON_NOTIFY entrada de MAP 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 de mensagens para funções.
The ON_NOTIFY macro do MAP 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 deve ser tratado sistema autônomo LVN_KEYDOWN.id
O identificador do filho do controle para o qual a notificação é enviada.memberFxn
A função de membro a ser chamado quando esta notificação é enviada.
Função de membro deve ser declarada com o seguinte protótipo:
afx_msgvoidmemberFxn(NMHDR*pNotifyStruct,LRESULT*result);
Comentários
onde os parâmetros em itálico são:
pNotifyStruct
Um ponteiro para a estrutura de notificação, sistema autônomo descrito na seção acima.resultado
Um ponteiro para o código de resultado você definirá antes de retornar.
Exemplo
Para especificar que você deseja que a função de membro OnKeydownList1 para lidar com LVN_KEYDOWN o mensagensCListCtrl cuja ID é IDC_LIST1, você usaria ClassWizard para o MAP da mensagem, adicione o seguinte:
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 fornece automaticamente um ponteiro de tipo adequado.Você pode acessar a estrutura de notificação por meio de um dos pNMHDR ou pLVKeyDow.
ON_NOTIFY_RANGE
Se você precisar processo o mesmo 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 para o qual você deseja executar a mesma ação para uma mensagem de notificação de determinados.
Quando você usa ON_NOTIFY_RANGE, você especifica um intervalo contíguo de identificadores de filho para o qual você deseja manipular a mensagem de notificação, especificando o início e término filho identificadores do intervalo.
ClassWizard não manipula ON_NOTIFY_RANGE; para usá-lo, você precisa edição o MAP da mensagem por conta própria.
O protótipo de função e entrada de MAP da mensagem para ON_NOTIFY_RANGE são sistema autônomo 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 deve ser tratado sistema autônomo 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.
Função de membro deve ser declarada com o seguinte protótipo:
afx_msgvoidmemberFxn(UINT id, NMHDR*pNotifyStruct,LRESULT*result);
Comentários
onde os parâmetros em itálico são:
id
O identificador do 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ê definirá antes de retornar.
ON_NOTIFY_EX, ON_NOTIFY_EX_RANGE
Se você desejar mais de um objeto na notificação de roteamento para lidar com uma mensagem, você pode usar ON_NOTIFY_EX (or ON_NOTIFY_EX_RANGE) em vez de ON_NOTIFY (ou ON_NOTIFY_RANGE).A única diferença entre o POR EXEMPLO versão e a versão regular é que a função de membro chamada para o POR EXEMPLO versão retorna um BOOL que indica se ou não deve continuar o processamento de mensagem.Retornando FALSE dessa função permite que você processar a mesma mensagem de mais de um objeto.
ClassWizard não manipula ON_NOTIFY_EX or ON_NOTIFY_EX_RANGE; se você deseja usar qualquer um deles, você precisará edição o MAP da mensagem por conta própria.
O protótipo de função e entrada de MAP da mensagem para ON_NOTIFY_EX and ON_NOTIFY_EX_RANGE são sistema autônomo seguintes.sistema autônomo significados dos parâmetros são sistema autônomo mesmos sistema autônomo para o não-POR EXEMPLO versões.
ON_NOTIFY_EX(nCode,id,memberFxn)ON_NOTIFY_EX_RANGE( wNotifyCode, id, idLast,memberFxn )
O protótipo para ambos os itens acima é o mesmo:
afx_msgBOOLmemberFxn(UINT id, NMHDR*pNotifyStruct,LRESULT*result);
Comentários
Em ambos os casos, id contém o identificador do filho do controle que enviou a notificação.
A função deve retornar TRUE se a mensagem de notificação manipulada completamente ou FALSE se outros objetos no roteamento de comando deve terá a chance de manipular a mensagem.