ALTE DOCUMENTE
|
||||||
. Предыдущая программа демонстрирует работу основных текстовых и системных функций Windows. Однако при ее выполнении снова возникает проблема, которая уже рассматривалась в гл. 3. Вы запускаете эту программу, отображаете текст, затем Ваше окно перекрывается другим окном - и текст теряется. Если же окно перекрывается не полностью, а частично, то пропадает часть текста. Решение проблемы состоит в том, что окно должно перерисовываться каждый раз при получении сообщения WM_PAINT
VM_PAINT
Наиболее общим методом является, конечно, последний, и мы им воспользуемся в данном случае. Как Вы увидите, Windows обеспечивает значительную поддержку этого метода.
WM_PAINT содержимое виртуального устройства должно копироваться на реальное устройство вывода (в реальное окно). Таким образом можно всегда сохранить содержимое окна, так что если окно было перекрыто другим окном, а затем снова стало активным, его содержимое всегда можно восстановить при получении сообщения WM_PAINT.
Дополнительные функции API. Поддержка виртуального окна осуществляется несколькими функциями API. Четыре из них - CreateCompatibleDC() SelectObject() GetStockObject() BitBlt()
CreateCompatibleBitmap() PatBlt() которые описываются ниже.
CreateCompatibleBitmap() создает в памяти растровое изображение, совместимое с заданным контекстом устройства. Это растровое изображение (bitmap) может использоваться при помощи ссылок на совместимый контекст устройства который создается при помощи функции CreateCompatibleDC(). Прототип этой функции таков:
HBITMAP CreateCompatibleBitmap HDC hdc int width int height
hdc width height NULL
PatBlt() заполняет заданную прямоугольную область, используя цвет и способ заполнения, определяемый текущей кистью. Кисть (brush) - это объект, задающий способ заполнения окна (или области). Заполнение некоторой области при помощи кисти обычно называется рисованием области. Прототип функции PatBlt()
BOOL PatBlt HDC hdc int X int Y int width
int height, DWORD dwRaster) ;
hdc Y width height dwRaster
dwRaster |
|
|
BLACKNESS | ||
WHITENESS | ||
PATCOPY | ||
PATINVERT |
Логическая операция OR (ИЛИ) для цвета области с текущей кистью |
|
DSTINVERT |
dwRaster PATCOPY
WM_PAINT
. Прежде всего необходимо создать виртуальный контекст устройства, совместимый с контекстом реального устройства. Это делается один раз - в начале выполнения программы при получении сообщения WM_CREATE. Созданный виртуальный контекст устройства будет существовать в течение всего времени выполнения программы. Приведем фрагмент программы, выполняющий эти действия:
case WM_CREATE: // Получаем размеры экрана
maxX=GetSystemMetrics(SM_CXSCREEN);
maxY=GetSystemMetrics(SM_CYSCREEN);
hdc=GetDC(hwnd); //Строим совместимый с окном растр
memdc=CreateCompatibleDC(hdc);
hbit=CreateCompatibleBitmap(hdc,maxX,maxY);
SelectObject(memdc,hbit);
hbrush=(HBRUSH)GetStockObject(WHITE_BRUSH);
SelectObject(memdc,hbrush);
PatBlt(memdc,0,0,maxX,maxY,PATCOPY);
ReleaseDC(hwnd,hdc);
break;
CreateCompatibleDC() memdc
hbit hbrush PatBlt()
WM_PAINT.) Из предыдущего примера приведем фрагмент программы обработки команды ID_SHOW, измененный для работы с виртуальным окном:
case ID_SHOW:
SetTextColor(memdc,RGB(0,0,0)); //
SetBkColor(memdc,RGB(0,255,255));//
GetTextMetrics(memdc,Stm); //
sprintf(str," %ld ",
tm.tmHeight);
TextOut(memdc,X,Y,str,strlen(str));//
Y=Y+tm.tmHeight+tm.tmExternalLeading; //
strcpy(str,"Это следующая строка");
TextOut(memdc,X,Y,str,strlen(str)); //
//
GetTextExtentPoint32(memdc,str,strlen(str),&size);
sprintf(str,"Длина предыдущей строки %ld единиц",
size.cx);
X=size.cx; // X в конец предыдущей строки
TextOut(memdc,X,Y,str,strlen(str));
Y=Y+tm.tmHeight+tm.tmExternalLeading; //
X=0; // X опять в начало */
sprintf(str,"Размеры экрана %d x %d",maxX,maxY);
TextOut(memdc,X,Y,str,strlen(str));
Y=Y+tm.tmHeight+tm.tmExternalLeading; //
//
InvalidateRect(hwnd,NULL,1);
break;
memdc InvalidateRect()
WM_PAINT
case WM_PAINT: // Перерисовка окна
hdc=BeginPaint(hwnd,&paintstruct); // Получить DC
// Теперь копируем растр из памяти на экран
BitBlt(hdc,0,0,maxX,maxY,memdc,0,0,SRCCOPY);
EndPaint(hwnd,&paintstruct); // DC
break;
memdc hdc BitBlt() SRCCOPY memdc WM_PAINT
#include <Windows.h>
#include <String.h>
#include <Stdio.h>
#include "Text.h"
LRESULT CALLBACK WindowFunc(HWND,UINT,WPARAM,LPARAM);
char szWinName[] = " "; //
char str[255]; // Буфер строки вывода
int X=0, Y=0; // Текущие координаты строки
int maxX, maxY; // Размеры экрана
HDC memdc; // DC виртуального окна
HBITMAP hbit; // Растр - это виртуальное окно
HBRUSH hbrush; //
int WINAPI WinMain (HINSTANCE hThisInst,
HINSTANCE hPrevInst,
LPSTR lpszArgs,
int nWinMode)
return msg. wParam;
}
// Windows и получает в качестве параметров сообщения
LRESULT CALLBACK WindowFunc HWND hwnd
UINT message,
WPARAM wParam,
LPARAM lParam)
break;
case WM_PAINT: //
hdc=BeginPaint(hwnd,&paintstruct); // DC
// Теперь копируем растр из памяти на экран
BitBlt(hdc,0,0,maxX,maxY,memdc,0,0,SRCCOPY);
EndPaint(hwnd,&paintstruct); // DC
break;
case WM_DESTROY: // Завершение программы
DeleteDC(memdc); // Удалить виртуальное окно
PostQuitMessage(0);
break;
default:
// Все сообщения, не обрабатываемые в данной
// функции, направляются на обработку по
// умолчанию
return DefWindowProc(hwnd,message,
wParam,lParam);
return 0;
}
PatBlt() ID_RESET
|