MFC - Mensagens e Eventos
Um aplicativo é feito de vários objetos. Na maioria das vezes, mais de um aplicativo está sendo executado no computador e o sistema operacional é constantemente solicitado a realizar algumas atribuições. Como pode haver tantas solicitações apresentadas de maneira imprevisível, o sistema operacional deixa aos objetos a responsabilidade de especificar o que desejam, quando desejam e que comportamento ou resultado esperam.
Visão geral
O sistema operacional Microsoft Windows não pode prever quais tipos de solicitações um objeto precisaria ser atendido e que tipo de atribuição outro objeto precisaria.
Para gerenciar todas essas atribuições e solicitações, os objetos enviam mensagens.
Cada objeto tem a responsabilidade de decidir qual mensagem enviar e quando.
Para enviar uma mensagem, um controle deve criar um evento.
Para fazer uma distinção entre os dois, o nome de uma mensagem geralmente começa com WM_, que significa Window Message.
O nome de um evento geralmente começa com On, que indica uma ação.
O evento é a ação de enviar a mensagem.
Mapa de Mensagens
Como o Windows é um sistema operacional orientado a mensagens, uma grande parte da programação do ambiente Windows envolve o tratamento de mensagens. Cada vez que ocorre um evento, como um pressionamento de tecla ou clique do mouse, uma mensagem é enviada ao aplicativo, que deve então tratar o evento.
Para que o compilador gerencie as mensagens, elas devem ser incluídas na definição da classe.
o DECLARE_MESSAGE_MAP A macro deve ser fornecida no final da definição da classe, conforme mostrado no código a seguir.
class CMainFrame : public CFrameWnd {
public:
CMainFrame();
protected:
DECLARE_MESSAGE_MAP()
};
As mensagens reais devem ser listadas logo acima da linha DECLARE_MESSAGE_MAP.
Para implementar as mensagens, você precisa criar uma tabela de mensagens que seu programa está usando.
Esta tabela usa duas macros delimitadoras;
Isso começa com um BEGIN_MESSAGE_MAP e termina com um END_MESSAGE_MAP macros.
A macro BEGIN_MESSAGE_MAP leva dois argumentos, o nome da sua classe e a classe MFC da qual você derivou sua classe, conforme mostrado no código a seguir.
#include <afxwin.h>
class CMainFrame : public CFrameWnd {
public:
CMainFrame();
protected:
DECLARE_MESSAGE_MAP()
};
CMainFrame::CMainFrame() {
// Create the window's frame
Create(NULL, L"MFC Messages Demo", WS_OVERLAPPEDWINDOW,
CRect(120, 100, 700, 480), NULL);
}
class CMessagesApp : public CWinApp {
public:
BOOL InitInstance();
};
BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
END_MESSAGE_MAP()
BOOL CMessagesApp::InitInstance(){
m_pMainWnd = new CMainFrame;
m_pMainWnd->ShowWindow(SW_SHOW);
m_pMainWnd->UpdateWindow();
return TRUE;
}
CMessagesApp theApp;
Vejamos um exemplo simples criando um novo projeto Win32.
Step 1 - Para criar um projeto MFC, clique com o botão direito no projeto e selecione Propriedades.
Step 2 - Na seção esquerda, clique em Propriedades de configuração → Geral.
Step 3 - Selecione a opção 'Usar MFC na DLL compartilhada' na seção Padrões do projeto e clique em OK.
Step 4 - Precisamos adicionar um novo arquivo de origem.
Step 5 - Clique com o botão direito em seu Projeto e selecione Adicionar → Novo Item.
Step 6 - Na seção Modelos, clique em Arquivo C ++ (.cpp).
Step 7 - Clique em Adicionar para continuar.
Step 8 - Agora, adicione o seguinte código no arquivo * .cpp.
#include <afxwin.h>
class CMainFrame : public CFrameWnd {
public:
CMainFrame();
protected:
DECLARE_MESSAGE_MAP()
};
CMainFrame::CMainFrame() {
// Create the window's frame
Create(NULL, L"MFC Messages Demo", WS_OVERLAPPEDWINDOW,
CRect(120, 100, 700, 480), NULL);
}
class CMessagesApp : public CWinApp {
public:
BOOL InitInstance();
};
BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
END_MESSAGE_MAP()
BOOL CMessagesApp::InitInstance() {
m_pMainWnd = new CMainFrame;
m_pMainWnd->ShowWindow(SW_SHOW);
m_pMainWnd->UpdateWindow();
return TRUE;
}
CMessagesApp theApp;
Mensagens do Windows
Existem diferentes tipos de mensagens do Windows, como criar uma janela, mostrar uma janela, etc. Aqui estão algumas das mensagens do Windows comumente usadas.
mensagem | Entrada do mapa | Descrição |
---|---|---|
WM_ACTIVATE | ON_WM_ACTIVATE () | A estrutura chama essa função de membro quando um objeto CWnd está sendo ativado ou desativado. |
WM_ACTIVATEA PP | ON_WM_ACTIVATEAPP () | A estrutura chama essa função de membro para todas as janelas de nível superior da tarefa que está sendo ativada e para todas as janelas de nível superior da tarefa que está sendo desativada. |
WM_APPCOMM E | ON_WM_APPCOMMAND () | A estrutura chama essa função de membro quando o usuário gera um evento de comando do aplicativo. |
WM_CANCELMODE | WM_CANCELMODE () | A estrutura chama esta função de membro para informar CWnd para cancelar qualquer modo interno. |
WM_CHILDACTIVATE | ON_WM_CHILDACTIVATE () | Se o objeto CWnd for uma janela filho de interface de documentos múltiplos (MDI), OnChildActivate é chamado pela estrutura quando o usuário clica na barra de título da janela ou quando a janela é ativada, movida ou dimensionada. |
WM_CLIPBOAR DUPDATE | ON_WM_CLIPBOARDUPDATE () | A estrutura chama essa função de membro quando o conteúdo da área de transferência é alterado. |
WM_CLOSE | ON_WM_CLOSE () | A estrutura chama essa função de membro como um sinal de que o CWnd ou um aplicativo deve ser encerrado. |
WM_CONTEXTMENU | ON_WM_CONTEXTMENU () | Chamado pela estrutura quando o usuário clica com o botão direito do mouse (clica com o botão direito) na janela. |
WM_COPYDATA | ON_WM_COPYDATA () | Essa função de membro é chamada pela estrutura para copiar dados de um aplicativo para outro. |
WM_CREATE | ON_WM_CREATE () | A estrutura chama essa função de membro quando um aplicativo solicita que a janela do Windows seja criada chamando a função de membro Create ou CreateEx. |
WM_CTLCOLOR | ON_WM_CTLCOLOR () | A estrutura chama essa função de membro quando um controle filho está prestes a ser desenhado. |
WM_DELETEITEM | ON_WM_DELETEITEM () | A estrutura chama essa função de membro para informar ao proprietário de uma caixa de listagem ou caixa de combinação desenhada pelo proprietário que a caixa de listagem ou caixa de combinação foi destruída ou que os itens foram removidos. |
WM_DESTROY | ON_WM_DESTROY () | A estrutura chama essa função de membro para informar ao objeto CWnd que ele está sendo destruído. |
WM_DRAWITEM | ON_WM_DRAWITEM () | A estrutura chama essa função de membro para o proprietário de um controle de botão de desenho do proprietário, controle de caixa de combinação, controle de caixa de listagem ou menu quando um aspecto visual do controle ou menu é alterado. |
WM_DROPFILES | ON_WM_DROPFILES () | A estrutura chama esta função de membro quando o usuário libera o botão esquerdo do mouse sobre uma janela que se registrou como o destinatário dos arquivos descartados. |
WM_ENABLE | ON_WM_ENABLE () | A estrutura chama essa função de membro quando um aplicativo altera o estado ativado do objeto CWnd. Sintaxe. |
WM_HELPINFO | ON_WM_HELPINFO () | Lida com Ajuda F1 dentro do aplicativo (usando o contexto atual). |
WM_HOTKEY | ON_WM_HOTKEY () | A estrutura chama essa função de membro quando o usuário pressiona uma tecla de atalho de todo o sistema. |
WM_HSCROLL | ON_WM_HSCROLL () | A estrutura chama essa função de membro quando o usuário clica na barra de rolagem horizontal de uma janela. |
WM_KEYDOWN | ON_WM_KEYDOWN () | A estrutura chama essa função de membro quando uma tecla não pertencente ao sistema é pressionada. |
WM_KEYUP | ON_WM_KEYUP () | A estrutura chama essa função de membro quando uma chave não pertencente ao sistema é liberada. |
WM_KILLFOCUS | ON_WM_KILLFOCUS () | A estrutura chama essa função de membro imediatamente antes de perder o foco de entrada. |
WM_LBUTTONDBLCLK | ON_WM_LBUTTONDBLCLK () | A estrutura chama essa função de membro quando o usuário clica duas vezes com o botão esquerdo do mouse. |
WM_LBUTTONDOWN | ON_WM_LBUTTONDOWN () | A estrutura chama essa função de membro quando o usuário pressiona o botão esquerdo do mouse. |
WM_LBUTTONUP | ON_WM_LBUTTONUP () | A estrutura chama essa função de membro quando o usuário libera o botão esquerdo do mouse. |
WM_MBUTTONDBLCLK | ON_WM_MBUTTONDBLCLK () | A estrutura chama essa função de membro quando o usuário clica duas vezes no botão do meio do mouse. |
WM_MBUTTONDOWN | ON_WM_MBUTTONDOWN () | A estrutura chama essa função de membro quando o usuário pressiona o botão do meio do mouse. |
WM_MBUTTONUP | ON_WM_MBUTTONUP () | A estrutura chama essa função de membro quando o usuário libera o botão do meio do mouse. |
WM_MENUSELECT | ON_WM_MENUSELECT () | Se o objeto CWnd estiver associado a um menu, OnMenuSelect será chamado pela estrutura quando o usuário selecionar um item de menu. |
WM_MOUSEACTIVATE | ON_WM_MOUSEACTIVATE () | A estrutura chama esta função de membro quando o cursor está em uma janela inativa e o usuário pressiona um botão do mouse. |
WM_MOUSEHOVER | ON_WM_MOUSEHOVER () | A estrutura chama essa função de membro quando o cursor passa sobre a área do cliente da janela pelo período de tempo especificado em uma chamada anterior para TrackMouseEvent. |
WM_MOUSEHWHEEL | ON_WM_MOUSEHWHEEL () | O framework chama este membro quando a janela atual é composta pelo Desktop Window Manager (DWM), e essa janela é maximizada. |
WM_MOUSELEAVE | ON_WM_MOUSELEAVE () | A estrutura chama essa função de membro quando o cursor deixa a área do cliente da janela especificada em uma chamada anterior para TrackMouseEvent. |
WM_MOUSEMOVE | ON_WM_MOUSEMOVE () | A estrutura chama essa função de membro quando o cursor do mouse se move. |
WM_MOVE | ON_WM_MOVE () | A estrutura chama essa função de membro depois que o objeto CWnd foi movido. |
WM_PAINT | ON_WM_PAINT () | A estrutura chama essa função de membro quando o Windows ou um aplicativo faz uma solicitação para redesenhar uma parte da janela de um aplicativo. |
WM_SETFOCUS () | ON_WM_SETFOCUS () | A estrutura chama essa função de membro depois de obter o foco de entrada. |
WM_SIZE () | ON_WM_SIZE () | A estrutura chama essa função de membro após a alteração do tamanho da janela. |
WM_TIMER | ON_WM_TIMER () | A estrutura chama essa função de membro após cada intervalo especificado na função de membro SetTimer usada para instalar um cronômetro. |
WM_VSCROLL | ON_WM_VSCROLL () | A estrutura chama essa função de membro quando o usuário clica na barra de rolagem vertical da janela. |
WM_WINDOWPOSCHANGED | ON_WM_WINDOWPOSCHANGED () | A estrutura chama essa função de membro quando o tamanho, posição ou ordem Z mudou como resultado de uma chamada para a função de membro SetWindowPos ou outra função de gerenciamento de janela. |
Vejamos um exemplo simples de criação de janela.
WM_CREATE - Quando um objeto, chamado de janela, é criado, o quadro que cria os objetos envia uma mensagem identificada como ON_WM_CREATE.
Step 1- Para criar ON_WM_CREATE, adicione afx_msg int OnCreate (LPCREATESTRUCT lpCreateStruct); antes de DECLARE_MESSAGE_MAP () conforme mostrado abaixo.
class CMainFrame : public CFrameWnd {
public:
CMainFrame();
protected:
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
DECLARE_MESSAGE_MAP()
};
Step 2 - Adicione o ON_WM_CREATE () após o BEGIN_MESSAGE_MAP (CMainFrame, CFrameWnd) e antes de END_MESSAGE_MAP ()
BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
ON_WM_CREATE()
END_MESSAGE_MAP()
Step 3 - Aqui está a implementação do OnCreate ()
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) {
// Call the base class to create the window
if (CFrameWnd::OnCreate(lpCreateStruct) == 0) {
// If the window was successfully created, let the user know
MessageBox(L"The window has been created!!!");
// Since the window was successfully created, return 0
return 0;
}
// Otherwise, return -1
return -1;
}
Step 4 - Agora seu arquivo * .cpp será semelhante ao mostrado no código a seguir.
#include <afxwin.h>
class CMainFrame : public CFrameWnd {
public:
CMainFrame();
protected:
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
DECLARE_MESSAGE_MAP()
};
CMainFrame::CMainFrame() {
// Create the window's frame
Create(NULL, L"MFC Messages Demo", WS_OVERLAPPEDWINDOW,
CRect(120, 100, 700, 480), NULL);
}
class CMessagesApp : public CWinApp {
public:
BOOL InitInstance();
};
BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
ON_WM_CREATE()
END_MESSAGE_MAP()
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) {
// Call the base class to create the window
if (CFrameWnd::OnCreate(lpCreateStruct) == 0) {
// If the window was successfully created, let the user know
MessageBox(L"The window has been created!!!");
// Since the window was successfully created, return 0
return 0;
}
// Otherwise, return -1
return -1;
}
BOOL CMessagesApp::InitInstance() {
m_pMainWnd = new CMainFrame;
m_pMainWnd -> ShowWindow(SW_SHOW);
m_pMainWnd -> UpdateWindow();
return TRUE;
}
CMessagesApp theApp;
Step 5 - Quando o código acima for compilado e executado, você verá a seguinte saída.
Step 6 - Ao clicar em OK, a janela principal será exibida.
Mensagens de Comando
Uma das principais características de um aplicativo gráfico é apresentar os controles e recursos do Windows que permitem ao usuário interagir com a máquina. Exemplos de controles que aprenderemos são botões, caixas de listagem, caixas de combinação, etc.
Um tipo de recurso que apresentamos na lição anterior é o menu. Esses controles e recursos podem iniciar suas próprias mensagens quando o usuário clica neles. Uma mensagem que emana de um controle ou recurso do Windows é chamada de mensagem de comando.
Vejamos um exemplo simples de mensagens de comando.
Para fornecer ao seu aplicativo a capacidade de criar um novo documento, a classe CWinApp fornece o método OnFileNew ().
afx_msg void OnFileNew();
BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
ON_COMMAND(ID_FILE_NEW, CMainFrame::OnFileNew)
END_MESSAGE_MAP()
Aqui está a definição do método -
void CMainFrame::OnFileNew() {
// Create New file
}
Mensagens do teclado
UMA keyboardé um objeto de hardware conectado ao computador. Por padrão, é usado para inserir símbolos reconhecíveis, letras e outros caracteres em um controle. Cada tecla do teclado exibe um símbolo, uma letra ou uma combinação deles, para dar uma indicação de para que a tecla pode ser usada. O usuário normalmente pressiona uma tecla, que envia um sinal para um programa.
Cada chave possui um código que o sistema operacional pode reconhecer. Este código é conhecido comovirtual key code.
Sr. Não. | Constante / valor e descrição |
---|---|
1 | VK_LBUTTON Botão esquerdo do mouse |
2 | VK_RBUTTON Botão direito do mouse |
3 | VK_CANCEL Processamento de quebra de controle |
4 | VK_MBUTTON Botão do meio do mouse (mouse de três botões) |
5 | VK_BACK Tecla BACKSPACE |
6 | VK_RETURN Tecla Enter |
7 | VK_TAB Tecla de tabulação |
8 | VK_CLEAR CLEAR key |
9 | VK_SHIFT Tecla Shift |
10 | VK_CONTROL Tecla CTRL |
11 | VK_MENU Tecla ALT |
12 | VK_PAUSE Tecla PAUSA |
13 | VK_CAPITAL Tecla CAPS LOCK |
14 | VK_ESCAPE Tecla ESC |
15 | VK_SPACE BARRA DE ESPAÇO |
16 | VK_PRIOR Tecla PAGE UP |
17 | VK_NEXT Tecla PAGE DOWN |
18 | VK_END Tecla END |
19 | VK_HOME Tecla HOME |
20 | VK_LEFT Tecla SETA PARA A ESQUERDA |
21 | VK_UP Tecla de SETA PARA CIMA |
22 | VK_RIGHT Tecla de SETA PARA A DIREITA |
23 | VK_DOWN Tecla de SETA PARA BAIXO |
24 | VK_SELECT Tecla SELECT |
25 | VK_PRINT Tecla PRINT |
26 | VK_EXECUTE Tecla EXECUTE |
27 | VK_SNAPSHOT Tecla PRINT SCREEN |
28 | VK_INSERT Chave INS |
29 | VK_DELETE Tecla DEL |
30 | VK_NUMPAD0 Tecla 0 do teclado numérico |
31 | VK_NUMPAD1 Teclado numérico 1 tecla |
32 | VK_NUMPAD2 Tecla 2 do teclado numérico |
33 | VK_NUMPAD3 Tecla 3 do teclado numérico |
34 | VK_NUMPAD4 Tecla do teclado numérico 4 |
35 | VK_NUMPAD5 Tecla 5 do teclado numérico |
36 | VK_NUMPAD6 Tecla 6 do teclado numérico |
37 | VK_NUMPAD7 Tecla 7 do teclado numérico |
38 | VK_NUMPAD8 8 teclas do teclado numérico |
39 | VK_NUMPAD9 Tecla 9 do teclado numérico |
40 | VK_MULTIPLY Chave de multiplicação |
41 | VK_ADD Adicionar chave |
42 | VK_SEPARATOR Chave separadora |
43 | VK_SUBTRACT Subtrair chave |
44 | VK_DECIMAL Chave decimal |
45 | VK_DIVIDE Chave de divisão |
46 | VK_F1 Tecla F1 |
47 | VK_F2 Tecla F2 |
48 | VK_F3 Tecla F3 |
49 | VK_F4 Tecla F4 |
50 | VK_F5 Tecla F5 |
52 | VK_F6 Tecla F6 |
53 | VK_F7 Tecla F7 |
54 | VK_F8 Tecla F8 |
55 | VK_F9 Tecla F9 |
56 | VK_F10 Tecla F10 |
57 | VK_F11 Tecla F11 |
58 | VK_F12 Tecla F12 |
59 | VK_NUMLOCK Tecla NUM LOCK |
60 | VK_SCROLL Tecla SCROLL LOCK |
61 | VK_LSHIFT Tecla SHIFT esquerda |
62 | VK_RSHIFT Tecla SHIFT direita |
63 | VK_LCONTROL Tecla de controle esquerda |
64 | VK_RCONTROL Tecla CONTROL direita |
Pressionar uma tecla faz com que uma mensagem WM_KEYDOWN ou WM_SYSKEYDOWN seja colocada na mensagem do thread. Isso pode ser definido da seguinte forma -
afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags);
Vejamos um exemplo simples.
Step 1 - Aqui está a mensagem.
BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
ON_WM_CREATE()
ON_WM_KEYDOWN()
END_MESSAGE_MAP()
Step 2 - Aqui está a implementação de OnKeyDown ().
void CMainFrame::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) {
switch (nChar) {
case VK_RETURN:
MessageBox(L"You pressed Enter");
break;
case VK_F1:
MessageBox(L"Help is not available at the moment");
break;
case VK_DELETE:
MessageBox(L"Can't Delete This");
break;
default:
MessageBox(L"Whatever");
}
}
Step 3 - Quando o código acima for compilado e executado, você verá a seguinte saída.
Step 4 - Quando você pressiona Enter, a seguinte mensagem é exibida.
Mensagens do mouse
O mouse é outro objeto anexado ao computador, permitindo ao usuário interagir com a máquina.
Se o botão esquerdo do mouse foi pressionado, uma mensagem ON_WM_LBUTTONDOWN é enviada. A sintaxe desta mensagem é -
afx_msg void OnLButtonDown (UINT nFlags, ponto CPoint)
Se o botão direito do mouse foi pressionado, uma mensagem ON_WM_RBUTTONDOWN é enviada. Sua sintaxe é -
afx_msg void OnRButtonDown (UINT nFlags, ponto CPoint)
Da mesma forma, se o botão esquerdo do mouse for liberado, a mensagem ON_WM_LBUTTONUP será enviada. Sua sintaxe é -
afx_msg void OnLButtonUp (UINT nFlags, ponto CPoint)
Se o botão direito do mouse estiver sendo liberado, a mensagem ON_WM_TBUTTONUP será enviada. Sua sintaxe é -
afx_msg void OnRButtonUp (UINT nFlags, ponto CPoint)
Vejamos um exemplo simples.
Step 1 - Adicione as duas funções a seguir na definição da classe CMainFrame, conforme mostrado no código a seguir.
class CMainFrame : public CFrameWnd {
public:
CMainFrame();
protected:
afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags);
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
afx_msg void OnRButtonUp(UINT nFlags, CPoint point);
DECLARE_MESSAGE_MAP()
};
Step 2 - Adicione os dois mapas de mensagens a seguir.
BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
ON_WM_KEYDOWN()
ON_WM_LBUTTONDOWN()
ON_WM_RBUTTONUP()
END_MESSAGE_MAP()
Step 3 - Aqui está a definição das funções.
void CMainFrame::OnLButtonDown(UINT nFlags, CPoint point) {
CString MsgCoord;
MsgCoord.Format(L"Left Button at P(%d, %d)", point.x, point.y);
MessageBox(MsgCoord);
}
void CMainFrame::OnRButtonUp(UINT nFlags, CPoint point) {
MessageBox(L"Right Mouse Button Up");
}
Step 4 - Ao executar este aplicativo, você verá a seguinte saída.
Step 5 - Ao clicar em OK, você verá a seguinte mensagem.
Step 6- Clique com o botão direito nesta janela. Agora, quando você soltar o botão direito do mouse, a seguinte mensagem será exibida.