Сообщения. Источники сообщений
Сообщение - это извещение о некотором имевшем место событии, посылаемое системой Windows.
Основными генераторами сообщений являются внешние устройства - большинство сообщений создают драйверы устройств ввода/вывода, таких, как клавиатура, мышь или таймер при получении аппаратных прерываний.
Например, когда вы нажимаете и затем отпускаете клавишу, драйвер обрабатывает прерывания от клавиатуры и создает несколько сообщений. Аналогично сообщения создаются при перемещении мыши или в том случае, когда вы нажимаете кнопки на корпусе мыши. Также сообщение может быть послано или получено от другого пользователя или Windows.
Очередь сообщения приложений может пополняться не только из системной очереди. Любое приложение может послать сообщение любому другому сообщению, в том числе и само себе.
Сообщения имеют приоритет: у программных сообщений он выше, чем у аппаратных.
Сообщение, в основном, состоит из полей wParam и lParam, также имеет заголовок. В сообщении, формируемом при нажатии любой кнопки мыши, младшее слово lParam содержит X – координату курсора, а старшее – Y – координату. Семь младших бит поля wParam содержит состояние кнопок мыши и клавиш Shift и Ctrl. Если кнопка или клавиша нажата, то соответствующий бит находится в состоянии 1.
typedef struct tagMSG
{
HWND hwnd;
UINT message;
WPARAM wParam;
LPARAM lParam;
DWORD time;
POINT pt;
} MSG;
4. Формирование сообщений, примеры. Очереди.
5.typedef struct tagMSG
6.{
7.HWND hwnd;
8.UINT message;
9.WPARAM wParam;
10.LPARAM lParam;
11.DWORD time;
12.POINT pt;
13.} MSG;
Сообщение - это извещение о некотором имевшем место событии, посылаемое системой Windows – они информируют Windows или приложение, что произошло какое-то событие (например, произошло нажатие клавиши). Также сообщение может быть послано или получено от другого пользователя или Windows
Сообщения имеют приоритет: у программных сообщений он выше, чем у аппаратных.
В Win принята 2-х ступенчатая очередь обработки сообщений.
Прежде всего, сообщения попадают в системную очередь сообщений Windows. Системная очередь сообщений одна. {Для обработки сообщений существует флаг, получается 2 очереди сообщений – обычная и с флагами.}
Далее из нее сообщения распределяются в очереди сообщений приложений. Для каждого приложения создается своя очередь сообщений.
Очередь сообщения приложений может пополняться не только из системной очереди. Любое приложение может послать сообщение любому другому приложение, в том числе и само себе. Данного рода отправка сообщения осуществляется двумя функциями –
PostMessage(HWND hwnd (дескриптор, которому посылается сообщение), UINT MESSAGE (номер сообщения), WPARAM wParam, LPARAM lParam); - ставит в очередь приложения
SendMessage(--//--); - вызывает обработчик
Основная работа, которую должно выполнять приложение, заключается в обслуживании собственной очереди сообщений. Обычно приложение в цикле опрашивает свою очередь сообщений (каждая программа должна иметь функцию обработки сообщений). Обнаружив сообщение, приложение с помощью специальной функции из программного интерфейса Windows распределяет его нужной функции окна, которая и выполняет обработку сообщения.
Примеры сообщений:
1. При сообщении WM_LBUTTONDOWN появляется диалоговая панель с кнопкой ОК.
case WM_LBUTTONDOWN: { MessageBox(NULL,"Нажата левая клавиша мыши", "Сообщение", MB_OK); return 0;}
2. Инициируем завершение работы приложения, помещая в очередь приложения сообщение WM_QUIT. Это приведет к завершению цикла обработки сообщений в функции WinMain
case WM_DESTROY: { PostQuitMessage(0); return 0; }14. Сообщения. Цикл сообщений, основные компоненты.
15.typedef struct tagMSG
16.{
17.HWND hwnd;
18.UINT message;
19.WPARAM wParam;
20.LPARAM lParam;
21.DWORD time;
22.POINT pt;
23.} MSG;
Сообщение - это извещение о некотором имевшем место событии, посылаемое системой Windows – они информируют Windows или приложение, что произошло какое-то событие (например, произошло нажатие клавиши). Также сообщение может быть послано или получено от другого пользователя или Windows
Для каждого приложения создается своя очередь сообщений. Очередь сообщения приложений может пополняться не только из системной очереди сообщений. Любое приложение может послать сообщение любому другому сообщению, в том числе и само себе.
Основная работа, которую должно выполнять приложение, заключается в обслуживании собственной очереди сообщений. Обычно приложение в цикле, называемом циклом сообщений, опрашивает свою очередь сообщений (каждая программа должна иметь функцию обработки сообщений).
Функция WinMain в цикле обработки сообщений с помощью функции GetMessage выбирает сообщения из очереди сообщений приложения и распределяет их функциям окон, вызывая функцию DispatchMessage.
Функция GetMessage предназначена для выборки сообщения из очереди приложения. Сообщение выбирается из очереди и записывается в область данных, принадлежащую приложению.
Функция TranslateMessage занимается обработкой клавишных команд.
Функция DispatchMessage предназначена для распределения выбранного из очереди сообщения нужной функции окна (определяет, какой функции окна отправить сообщение). Так как приложение обычно создает много окон и эти окна используют различные функции окна, необходимо распределить сообщение именно тому окну, для которого оно предназначено. Поэтому приложение должно распределить сообщение после его выборки из очереди приложения, в котором находятся сообщения для всех окон. Затем управление передается Windows, и он вызывает обработчик. Обработчик дополняется кодом и начинает работать в составе ОС.
Типичный цикл сообщений:
MSG msg; // Структура для временного хранения информации о сообщении.
while(GetMessage(&msg, 0, 0, 0)){ TranslateMessage(&msg); DispatchMessage(&msg); }return msg.wParam;24. Сообщения. Структура сообщений на примере WM_COMMAND
Сообщение - это извещение о некотором имевшем место событии, посылаемое системой Windows – они информируют Windows или приложение, что произошло какое-то событие (например, произошло нажатие клавиши). Также сообщение может быть послано или получено от другого пользователя или Windows.
Сообщение WM_COMMAND
idItem = wParam; /* control or menu item identifier */
hwndCtl = (HWND) LOWORD(lParam); /* handle of control */
wNotifyCode = HIWORD(lParam); /* notification message */
The WM_COMMAND message is sent to a window when the user selects an item from a menu, when a control sends a notification message
Сообщение с кодом WM_COMMAND передается функции родительского окна от органа управления, созданного этим окном. При создании органа управления (например, кнопки на базе класса "button") вызывается функция CreateWindow, которой указываете идентификатор родительского окна и идентификатор органа управления.
Если орган управления изменяет свое состояние (например, когда вы нажали на кнопку), функция родительского окна получает сообщение WM_COMMAND. Вместе с этим сообщением функция родительского окна получает в параметре wParam идентификатор органа управления. Младшее слово параметра lParam содержит идентификатор дочернего окна, т. е. идентификатор окна органа управления. Старшее слово lParam содержит код извещения от органа управления (notification code), по которому можно судить о том, какое действие было выполнено над органом управления.
Когда вы нажимаете на кнопку, родительское окно получает сообщение WM_COMMAND с кодом извещения, равным BN_CLICKED. Получив такое сообщение, приложение определяет, что была нажата кнопка, идентификатор которой находится в параметре wParam.
Или, если у нас создано меню с помощью шаблона, то мы можем получить это сообщение при выборе пункта системного меню. wParam содержит идентификатор строки, определенной в шаблоне меню.
Пример обработки сообщения WM_COMMAND:
LRESULT CALLBACK WndProc(HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam)
{
switch (iMessage)
{
// Осуществим обработку выбранного пункта меню
case WM_COMMAND:
{
switch (wParam)
{
// Сообщения от меню
case IDM_FIVE:
break;
case IDM_FOUR:
{
PostQuitMessage(0);
break;
}
}
}
default:
return DefWindowProc(hWnd, iMessage, wParam, lParam);
}
return 0;
}