Обработка сообщений.
Отображение окна на экране
Для того, чтобы сделать созданное окно видимым, необходимо вызвать функцию.
BOOL ShowWindow(HWND hwnd, int CmdShow)
SW_HIDE — окно свернуто в пиктограмму
SW_SHOWNORMAL — окно отображается в нормальном видео
Для перерисовки содержимого окна функция
UpdateWindows(HWND hwnd);
Вызывает функцию окна, и передает сообщение WM_PAINT
После создания окна следует вызывать обе функции. Только в сумме они отрисовывают все элементы отображения.
Основная работа, которое выполняет приложение заключается в обслуживании собственной очереди сообщений. Приложения, в цикле опрашивают в свою очередь сообщения, обнаружив сообщение, приложение распределяет его нужной функции окна, которая и осуществяет обработку сообщений. Сообщения Windows представляет собой следущую структуру данных:
typedef struct tagMSG {
HWND hwnd; //окно — адрес получателя.
UINT message; // код сообщения
WPARAM wParam; // содержимое сообщения
LPARAM lParam; // содержимое сообщения
DWORD time; // время отправления
POINT pt; // информация о координатах
|
|
} MSG;
Распределние сообщений между приложениями основано на понятии фокусов ввода. Фокус ввода — это аттрибут, который в любой момент времени может относиться только к одному окну. Если окно имеет фокус ввода, то все сообщения от клавиатуры распределяются в функции окна. Переключение фокуса ввода осуществляется с помощью комбинации клавиш, либо мышью. Сообщения от драйвера мыши всегда поступают в функци того окна, над которым находится курсор. Для приложения существует возможность захвата мыши. В этом случае все сообщения поступают в очередь приложения, захватившего мышь, вне зависимости от положения курсора.
После отображения окна, функция WinMain запускает цикл обработки сообщений.
While(GetMessage(&msg, 0, 0, 0))
DispatchMessage(&msg)
GetMessage предназначена для выборки сообщений из очереди приложения
BOOL GetMessage(
PMSG msg, // Дальний указатель на структуру типа MSG, в которую будет // записано выбранное из очереди сообщение.
HWND hwnd, // Идентификатор окна, для которого необходимо выбрать // сообщение. Нулевое значение параметра приведет к выборке
// сообщений для всех окон приложения.
WORD minimum // Задают диапазон кода сообщений, выбираемых из очереди.
WORD maximum // Нулевое значение привидет к выборке всех сообщений.
)
После работы функции GetMessage сообщение удаляется из очереди приложения. Если из очереди выбирается сообщение WM_QUIT, то функция GetMessage возвращает значение FALSE. В этом случае приложение завершает обработку цикла сообщений. Во всех других случаях функция возвращает значение TRUE.
Вторая функция DispatchMessage предназначена для распределения сообщений в соответствующие функции окна.
|
|
Простейщее приложение с обработкой сообщения.
В приложении определяется один класс окна,и на его основе создается главное окно. Для обработки сообщений выделяется функция окна, которая будет обрабатывать два сообщения:
WM_LBUTTONDOWN
WM_DESTROY
Сообщение WM_LBUTTONDOWN когда нажата левая кнопка мыши над окном.
Сообщение WM_DESTROY передается приложению при разрущении структуры окна. В ответ на это сообщение функция окна помещяет в очередь приложения специальное сообщение с кодом WM_QUIT. Оно приводит к завершению программы.
#include "stdafx.h"
#include <windows.h>
#include <memory.h>
BOOL InitApp(HINSTANCE); //Идентификатор приложения
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM);
TCHAR const szClassName[] = _T("WindowAppClass");
TCHAR const szWindowTitle[] = _T("WindowApplication");
TCHAR const lButtonMessageBoxContent[] = _T("Pressed left button");
TCHAR const lButtonMessageBoxTitle[] = _T("Message");
int WINAPI WinMain(
HINSTANCE hInstance, // Идентификатор текущей копии приложения
HINSTANCE hPrevInstance, //Раньше был идентификатор текущего прилжоения // теперь в WinApi32 всегда ноль
LPSTR lpszCmdLine, // Указатель на коммандуную строку
int nCmdShow // Способ отображения главного окна
)
{
MSG msg;
HWND hwnd;// Идентификатор главного окна приложения
// Код создания и инициализации
if (!InitApp(hInstance))// Завершаем приложение
return FALSE;
// Создание главного окна приложения
hwnd = CreateWindow(
szClassName,
szWindowTitle,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
0,
0,
hInstance,
NULL);
// Проверяем создано ли окно
if(!hwnd)
return FALSE;
// Окно создано, переходим к отображению
ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);
while(GetMessage(&msg, 0, 0, 0))
DispatchMessage(&msg);
return msg.wParam;
}
BOOL InitApp(HINSTANCE hInstance)
{
ATOM aWndClass; // Для хранения кода возврата
WNDCLASS WC;
memset(&WC, 0, sizeof(WC));
WC.style = 0;
WC.lpfnWndProc = (WNDPROC) WndProc;
WC.cbClsExtra = 0;
WC.cbWndExtra = 0;
WC.hInstance = hInstance;
WC.hIcon = LoadIcon(NULL, IDI_APPLICATION);
WC.hCursor = LoadCursor(NULL, IDC_ARROW);
WC.hbrBackground = (HBRUSH) (COLOR_WINDOW +1);
WC.lpszMenuName = (LPCWSTR) NULL;
WC.lpszClassName = (LPCWSTR) szClassName;
aWndClass = RegisterClass(&WC);
return (aWndClass!= 0);
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg)
{
case WM_LBUTTONDOWN:
{
MessageBox(NULL, lButtonMessageBoxContent, lButtonMessageBoxTitle, MB_OK||MB_ICONINFORMATION);
return 0;
}
case WM_DESTROY:
{
PostQuitMessage(0);
return 0;
}
}
return DefWindowProc(hwnd, msg, wParam, lParam);
}
Лекция №3 (29.10.10)