Windows - событийно зависимая операционка. В ней всё происходит по событиям (сообщениям), поэтому эта темя основная для понимания программирования на Visual C++. В любоё последующей программе мы будем использовать вложенные в эту статью знания. Так что вперёд.
Напоминаю, что С++ предирчив к регистру. Это значит, что функции Create не create разные вещи, потому что первая буква написана в разных регистрах.
Функция (метод) обработки сообщения вызывается, когда происходит событие, предназначенное для этого метода. Существует три типа сообщений:
Сообщения Windows. Они посылаются операционкой и начинаются с префикса WM_ (кроме WM_COMMAND).
Уведомление элементов управления. Сообщения посылаемые дочерними окнами, родительскому окну.
Командные сообщения. Сообщения от кнопок, меню и других пользовательских элементов.
Что такое родительское и дочернее окно? Родительское окно - окно которое содержит другие элементы. Например, твоё главное окно - родительское. Все располагающиеся на нём элементы - дочерние окна по отношению к главному окну. Предположим на форме есть панель, а на панели кнопки. Тогда, панель - родитель по отношению к кнопкам, а кнопки дочерние по отношению к панели. В то же время панель дочерняя по отношению к форме.
В MFC для управления сообщениями была введена "карта сообщений". Карта устанавливает в соответствие каждому сообщению определённую тобой процедуру. Так, с помощью карты ты можешь назначить определённому сообщению отдельную функцию. Это намного удобней, чем использовать оператор case (как мы это делали в прошлом номере, когда знакомились с чистым С).
Карта сообщений отправляет сообщения на метода класса так, что они автоматически обрабатываются соответствующим окном или элементом.
Что? Это не то, что ты ожидал? А ты думал увидеть глобус? Нет, карта это не глобус.
В скобках написаны имена двух объектов CMainWnd и CFrameWnd , к которым относится эта карта.
Макросы карты сообщений предварительно определены в MFC и не требуют аргументов, но ты должен создать методы OnCreate() , OnLButtonDown() и OnRButtonDown() .
После того, как карта сокровищ создана, её нужно объявить. Для этого в соответствующем объекте нужно написать DECLARE_MESSAGE_MAP():
class CMainWnd: public CFrameWnd
{
DECLARE_MESSAGE_MAP()
}
С теорией на сегодня покончено. Теперь переходим к примерам. Создай новый проект с помощью File-New. Выбери "Win 32 Application" и щёлкай ОК. Теперь выбери "An empty project" (пустой проект) и жми Finish.
Теперь нужно добавить к нашему пустому проекту С++ файл. Щёлкни File-New и на закладке File выбери "C++ Source File". Введи любое имя и жми ОК.
Наш минимальный исходник будет выгладить так:
#include // Подключаем модуль afxwin.h
class CMinApp : public CWinApp //Объявляем класс CMinApp
{
public:
virtual BOOL InitInstance(); //Перекрываем функцию InitInstance
};
BOOL CMinApp::InitInstance()
{
CFrameWnd* pFrame = new CFrameWnd;//Инициализируем новое окно
pFrame->Create(0, _T("Минимальная прога"));//Создаём окно
pFrame->ShowWindow(SW_SHOW);//Показываем окно
pFrame->UpdateWindow();//Перерисовываем
AfxGetApp()->m_pMainWnd = pFrame;//Делаем окно главным в приложении
return TRUE;
}
CMinApp MyApp;
Прежде чем запускать проект выбери меню Project-Settings и установи там "Using MFC in a shared DLL" как на рис 1.
Рис 1. Настройки проекта
Теперь добавим в наш исходник обработку нажатия мыши. Смотри на полный исходник примера:
#include
//Объявляем приложение
class CMinApp : public CWinApp
{
public:
virtual BOOL InitInstance();
};
//В прошлом примере мы использовали стандартное окно CFrameWnd
//В этом мы создадим потомка от него, чтобы внести новые возможности
//т.е. карту сообщений
class CMainWnd : public CFrameWnd
{
protected:
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
afx_msg void OnRButtonDown(UINT nFlags, CPoint point);
DECLARE_MESSAGE_MAP();
};
// Карта сообщений
BEGIN_MESSAGE_MAP(CMainWnd, CFrameWnd)
ON_WM_LBUTTONDOWN()
ON_WM_RBUTTONDOWN()
END_MESSAGE_MAP()
void CMainWnd::OnLButtonDown(UINT nFlags, CPoint point)
{
CString szAboutLeft = "Ты нажал левую кнопку";
//Вывести звуковое сообщение
::MessageBeep(MB_ICONINFORMATION);
//Показать окно сообщение
::MessageBox(GetSafeHwnd(), szAboutLeft, "About",
MB_OK | MB_ICONINFORMATION);
//После собственной обработки вызываем обработчик поумолчанию
CFrameWnd::OnLButtonDown(nFlags, point);
}
void CMainWnd::OnRButtonDown(UINT nFlags, CPoint point)
{
CString szAboutRight = "Лучше нажми себе на пупок";
::MessageBeep(MB_ICONINFORMATION);
::MessageBox(GetSafeHwnd(), szAboutRight, "About",
MB_OK | MB_ICONINFORMATION);
CFrameWnd::OnRButtonDown(nFlags, point);
}
BOOL CMinApp::InitInstance()
{
CMainWnd* pFrame = new CMainWnd;//Создаём новое окно CMainWnd
pFrame->Create(0, _T("Обработчик сообщений"));
pFrame->ShowWindow(SW_SHOWNORMAL);
pFrame->UpdateWindow();
this->m_pMainWnd = pFrame;
return TRUE;
}
CMinApp MyApp;