Цикл обработки сообщений

Обработка сообщений.

Отображение окна на экране

Для того, чтобы сделать созданное окно видимым, необходимо вызвать функцию.

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)


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: