
- •Методические указания по теме «Программирование в среде Windows»
- •Часть 1
- •Содержание
- •Введение.
- •Литература. Введение
- •1. Каркас оконного приложения Windows
- •Приводит к перерисовке клиентской области окна. В случае каркасного приложения в этом нет необходимости, однако в реальных приложениях такую перерисовку практически всегда приходится производить.
- •2. Обработка сообщений в системе Windows
- •3. Перерисовка клиентской области окна
- •4. Простой текстовый редактор
- •5. Диагностика ошибок
- •6. Аппаратно-независимый растр
- •7. Файлы, отображаемые в память
- •Литература
Приводит к перерисовке клиентской области окна. В случае каркасного приложения в этом нет необходимости, однако в реальных приложениях такую перерисовку практически всегда приходится производить.
Далее следует цикл обработки сообщений:
while (GetMessage (&msg, NULL, 0, 0)) {
TranslateMessage (&msg);
DispatchMessage (&msg);
}
Сообщения это основной способ взаимодействия приложения с системой, пользователем и другими приложениями и поэтому после открытия окна и выделения необходимых ресурсов работа приложения обычно строится по схеме: проверка очереди сообщений и извлечение очередного сообщения из очереди, вызов оконной функции для выполнения действий обусловленных полученным сообщением, далее цикл повторяется. Функция GetMessage проверяет очередь сообщений и извлекает из очереди очередное сообщение, в соответствии с полученным сообщением заполняются поля структуры msg, указатель на которую является первым аргументом функции; значения остальных аргументов функции GetMessage ( ) означает, что из очереди необходимо извлекать все сообщения. В качестве своего значения функция GetMessage возвращает TRUE (что приводит к исполнению очередного шага цикла) для всех сообщений кроме сообщения WM_QUIT, для этого сообщения возвращается значение FALSE, в этом случае цикл прерывается и приложение завершает свою работу:
return msg.wParam;
}
В теле цикла обработки сообщений обычно вызываются две функции: TranslateMessage и DispatchMessage. Первая из них преобразует виртуальные коды клавиш в сообщения клавиатуры, ее используют в приложениях, где требуется ввод с клавиатуры. Функция DispatchMessage указывает системе на необходимость вызова оконной функции для отработки полученного сообщения.
Оконная функция вызывается системой после исполнения функции DispatchMessage для выполнения действий определяемых соответствующим сообщением. Прототип оконной функции (мы ее назвали WinFunc) был описан ранее; она имеет четыре аргумента, значения которых формируются системой в зависимости от значений полей структуры msg и определяются типом полученного сообщения. Первый аргумент оконной функции имеет значение дескриптора окна, для обработки сообщения которого эта функция была вызвана; второй аргумент – тип сообщения (сообщение таймера, мыши, клавиатуры и т.д.); третий и четвертый аргументы содержат дополнительную информацию структура и содержание которой определяется типом конкретного сообщения. Для рассматриваемого каркасного приложения оконная функция имеет вид:
LRESULT CALLBACK WinFunc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message) {
case WM_DESTROY:
PostQuitMessage (0);
break;
default:
return DefWindowProc (hwnd, message, wParam, lParam);
}
return 0;
}
Эта функция самостоятельно обрабатывает единственное сообщение WM_DESTROY. Это сообщение посылается, когда пользователь завершает работу приложения. Обрабатывая его, оконная функция вызывает функцию PostQuitMessage, значение аргумента PostQuitMessage используется как код завершения приложения. Исполнение функции PostQuitMessage приводит к посылке сообщения WM_QUIT текущему приложению. Получив сообщение WM_QUIT, функция GetMessage возвратит значение FALSE, цикл обработки сообщений прервется и приложение завершит свою работу. Все остальные сообщения, получаемые оконной функцией, направляются в систему для обработки по умолчанию посредством вызова функции DefWindowProc.
Полный текст рассматриваемой программы каркасного приложения:
#include <windows.h>
LRESULT CALLBACK WinFunc(HWND, UINT, WPARAM, LPARAM);
char szWinName[] = "MyWindow";
int WINAPI WinMain (HINSTANCE hThisInst, HINSTANCE hPrevInst, LPSTR lpszArgs, int nWinMode)
{
MSG msg;
WNDCLASSEX wcl;
HWND hWnd;
ZeroMemory (&wcl, sizeof (wcl));
wcl.cbSize = sizeof (wcl);
wcl.hInstance = hThisInst;
wcl.lpszClassName = szWinName;
wcl.lpfnWndProc = WinFunc;
wcl.hIcon=LoadIcon (NULL, IDI_APPLICATION);
wcl.hCursor=LoadCursor (NULL, IDC_ARROW);
wcl.hbrBackground = (HBRUSH)(GetStockObject (WHITE_BRUSH));
if (!RegisterClassEx (&wcl))
return 0;
hWnd = CreateWindow (szWinName, "Framework for Windows",
WS_OVERLAPPEDWINDOW,
10, 10, 320, 240,
HWND_DESKTOP, NULL, hThisInst, NULL);
ShowWindow (hWnd, nWinMode);
UpdateWindow (hWnd);
while (GetMessage (&msg, NULL, 0, 0)) {
TranslateMessage (&msg);
DispatchMessage (&msg);
}
return msg.wParam;
}
LRESULT CALLBACK WinFunc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message) {
case WM_DESTROY:
PostQuitMessage (0);
break;
default:
return DefWindowProc (hwnd, message, wParam, lParam);
}
return 0;
}