Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
МП 1,2.doc
Скачиваний:
11
Добавлен:
05.11.2018
Размер:
2.77 Mб
Скачать

Int ReleaseDc(hwnd hwnd, hdc hdc);

Тип HDC означает дескриптор контекста устройства. Функция ReleaseDC() возвращает ненулевое значение, если она завершилась успешно.

Текст на экран выводит функция, имеющая следующий прототип:

BOOL TextOut(HDC hdc, int x, int y, LPSTR lpstr, int nlength);

На экран выводится nlength символов строки, указатель на которую равен lpstr. Координаты задаются относительно начала рабочей области, а не экрана.

Обработка запроса на перерисовку окна. Если нажать кнопку минимизации окна, а затем вновь распахнуть окно, то символы, записанные в окне с помощью TextOut(), будут потеряны. Система Windows, как правило, не запоминает содержимое окна, но каждый раз, когда надо перерисовать окно, она посылает оконной функции сообщение WM_PAINT.

В некоторых случаях при перемещении и при изменении размеров окна система сохраняет и перерисовывает содержимое окна, но это не касается случая, когда окно минимизируется или перекрывается другим окном, а потом делается попытка восстановить его в исходное состояние. Для того чтобы обрабатывать сообщение WM_PAINT, добавим соответствующий этому сообщению случай в оператор switch функции окна:

case WM_PAINT:

hdc = BeginPaint(hwnd, &paintstruct); // получить DC

TextOut(hdc, 1, 1, str, strlen(str));

EndPaint(hwnd, &paintstruct); // освободить DC

break;

В данном случае применяются другие функции получения и освобождения контекста устройства. Они имеют дополнительный параметр, равный адресу структуры.

struct PAINTSTRUCT

{

HDC hdc; // дескриптор DC

BOOL fErase; // true, если перерисовывается заполнение окна

RECT rcPaint; // координаты области перерисовки

BOOL fRestore, fIncUpdate; // резерв

BYTE rgbReserved[32]; // резерв

}

Здесь тип RECT описывает структуру

struct RECT

{

LONG left, top, right, bottom;

}

Для обработки сообщения WM_PAINT добавим определение

PAINTSTRUCT paintstruct;

В результате получаем приведённую ниже оконную функцию:

LRESULT CALLBACK WindowFunc(HWND hwnd,

UINT message,

WPARAM wParam,

LPARAM lParam)

{

HDC hdc; // контекст устройства

PAINTSTRUCT paintstruct;

switch(message)

{

case WM_CHAR:

hdc = GetDC(hwnd); // получить контекст устройства

TextOut(hdc, 1, 1, “ “, 2); // стереть старый символ

sprintf(str, “%c”, (char)wParam); // записать в буфер новый символ

TextOut(hdc, 1, 1, str, strlen(str)); // вывести на экран

ReleaseDC(hwnd, hdc); // освободить контекст устройства

break;

case WM_PAINT:

hdc = BeginPaint(hwnd, &paintstruct); //получить DC

TextOut(hdc, 1, 1, str, strlen(str));

EndPaint(hwnd, &paintstruct); //освободить DC

break;

case WM_DESTROY:

PostQuitMessage(0); //сообщение о завершении

break;

default: //обработка остальных сообщений

return DefWindowProc(hwnd, message, wParam, lParam);

}

return 0;

}

В реальных программах обработка сообщения WM_PAINT может быть намного сложнее. Она выполняется одним из трех способов:

  • программа выводит при перерисовке информацию, полученную в результате некоторых вычислений;

  • последовательность событий запоминается и при необходимости воспроизводится вновь для перерисовки окна;

  • программа поддерживает виртуальный экран, который при перерисовке копируется в окно.

Обработка сообщений мыши. Рассмотрим наиболее часто употребляемые сообщения мыши WM_LBUTTONDOWN и WM_RBUTTONDOWN, которые поступают при нажатии соответственно левой и правой кнопок мыши. Для обработки этих сообщений в оконной функции добавим следующие строки:

case WM_RBUTTONDOWN: // нажата правая кнопка мыши

hdc = GetDC(hwnd); // получить DC

strcpy(str, “Нажата правая кнопка”);

TextOut(hdc, LOWORD(lParam), HIWORD(lParam), str, strlen(str));

ReleaseDC(hwnd, hdc); // освободить DC

break;

case WM_LBUTTONDOWN: // нажата левая кнопка мыши

hdc = GetDC(hwnd); // получить DC

strcpy(str, “Нажата левая кнопка”);

TextOut(hdc, LOWORD(lParam), HIWORD(lParam), str, strlen(str));

ReleaseDC(hwnd, hdc); // освободить DC

break;

При нажатии кнопки мыши координаты курсора x и y передаются в lParam. Поскольку текст в данном случае выводится, начиная с позиции (LOWORD(lParam), HIWORD(lParam)), то при нажатии кнопки мыши сообщение об этом будет выводиться в текущей позиции курсора.

Параметр wParam будет содержать информацию, определенную комбинацией флагов:

MK_CONTROL - в момент нажатия кнопки мыши была нажата клавиша [Ctrl];

MK_SHIFT - то же для клавиши SHIFT;

MK_LBUTTON - была нажата левая кнопка мыши;

MK_RBUTTON - была нажата правая кнопка мыши;

MK_MBUTTON - была нажата средняя кнопка мыши.

Генерация сообщения WM_PAINT. Программа имеет возможность вызвать генерацию и посылку операционной системой сообщения о запросе на перерисовку окна. Операционная система передаст это сообщение в удобное для себя время. Это позволяет эффективно использовать время центрального процессора.

Чтобы заставить Windows послать сообщение WM_PAINT, программа должна вызвать функцию

BOOL InvalidateRect(HWND hwnd, CONST RECT *lpRect, BOOL fErase);

где hwnd – дескриптор окна, которому должно быть адресовано сообщение WM_PAINT, lpRect – указатель на структуру RECT, задающую прямоугольную область в окне, которая должна быть перерисована. Если lpRect = NULL, то окно перерисовывается полностью. Если fErase не равен нулю, то вначале выполняется перерисовка заполнения, т.е. содержимое перерисовываемой области вначале стирается.

Для демонстрации способа генерации запроса о перерисовке модифицируем каркасную программу следующим образом:

 добавим внешние переменные

char str[80] = “”;

int X = 1, Y = 1;

 главная программа не изменяется;

 перепишем оконную функцию таким образом, что вывод на экран производится с помощью обработки сообщения WM_PAINT. Выводится строка из буфера. При обработке других сообщений этот буфер заполняется и вызывается генерация сообщения WM_PAINT.

Ниже приведём текст модифицированной оконной функции.

LRESULT CALLBACK WindowFunc(HWND hwnd,

UINT message,

WPARAM wParam,

LPARAM lParam)

{

HDC hdc;

PAINTSTRUCT paintstruct;

switch(message)

{

case WM_CHAR:

X = Y = 1; // выводим в левом верхнем углу

sprintf(str, “%c”, (char)wParam); // заполнить буфер

InvalidateRect(hwnd, NULL, 1); // генерация WM_PAINT

break;

case WM_PAINT:

hdc = BeginPaint(hwnd, &paintstruct); //получить DC

TextOut(hdc, X, Y, str, strlen(str)); // вывод

EndPaint(hwnd, &paintstruct); //освободить DC

break;

case WM_RBUTTONDOWN: // нажата правая кнопка мыши

hdc = GetDC(hwnd); // получить DC

strcpy(str, “Нажата правая кнопка”);

TextOut(hdc, LOWORD(lParam), HIWORD(lParam), str, strlen(str));

ReleaseDC(hwnd, hdc); // освободить DC

break;

case WM_LBUTTONDOWN: // нажата левая кнопка мыши

hdc = GetDC(hwnd); // получить DC

strcpy(str, “Нажата левая кнопка”);

TextOut(hdc, LOWORD(lParam), HIWORD(lParam), str, strlen(str));

ReleaseDC(hwnd, hdc); // освободить DC

break;

case WM_DESTROY:

PostQuitMessage(0); //сообщение о завершении

break;

default: //обработка остальных сообщений

return DefWindowProc(hwnd, message, wParam, lParam);

}

return 0;

}

Генерация сообщений таймера. Можно устанавливать таймер, который с заданной периодичностью будет посылать программе сообщение WM_TIMER. Для установки таймера применяется функция

UINT SetTimer(HWND hwnd, UINT nID, UINT wLength, TIMEPROC lpTFunc);

где hwnd – дескриптор окна, nID -идентификатор устанавливаемого таймера (можно использовать несколько таймеров), wLength – временной интервал в миллисекундах, lpTFunc – функция обработки сообщений таймера. Если TFunc = NULL, то для обработки сообщений таймера будет вызываться оконная функция. Для отключения таймера вызывается функция

BOOL KillTimer(HWND hwnd, UINT nID);

где nID – идентификатор таймера, а hwnd – дескриптор окна, использующего таймер.

Например, если в программе, демонстрирующей генерацию WM_PAINT, поставить после вызова функции ShowWindow(hwnd, nWinMode); вызов подпрограммы установки таймера:

SetTimer(hwnd, 1, 1000, NULL);

а после цикла обработки сообщений:

KillTimer(hwnd, 1);

то вывод окна, в котором показывается день недели, месяц, число, время и год, осуществляется с помощью оконной функции:

LRESULT CALLBACK WindowFunc(HWND hwnd,

UINT message,

WPARAM wParam,

LPARAM lParam)

{

HDC hdc;

PAINTSTRUCT paintstruct;

struct tm *newtime;

time_t t;

switch(message)

{

case WM_PAINT:

hdc = BeginPaint(hwnd, &paintstruct); //получить DC

TextOut(hdc, X, Y, str, strlen(str)); //вывод буфера

EndPaint(hwnd, &paintstruct); //освободить DC

break;

case WM_TIMER:

t = time(NULL);

newtime = localtime(&t); //получить текущее время

strcpy(str, asctime(newtime)); // запись в буфер

str[strlen(str)-1] = ‘\0’;

InvalidateRect(hwnd, NULL, 1);

break;

case WM_DESTROY:

PostQuitMessage(0); //сообщение о завершении

break;

default: //обработка остальных сообщений

return DefWindowProc(hwnd, message, wParam, lParam);

}

return 0;

}

Окна сообщений. Возможен вывод информации с ожиданием реакции пользователя. Это средство является самым простым элементом интерфейса и называется окном сообщения. Для создания этого элемента используется функция:

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]