Главная » Win32 API » Сообщение WMPAINT и его обработка

0

Если окно перемещается по экрану с помощью клавиатуры или мыши, то сохранение в неизменном виде содержимого клиентской об­ласти окна обеспечивают системные программы. Если часть окна за­слоняется при разворачивании пунктов меню, то временно закрытую область ОС также сохраняет сама и потом восстанавливает. Если же необходимо развернуть свернутое окно, или растянуть окно, или на фоне главного окна перемещается дочернее, то Windows уже не пере­рисовывает все окно, а посылает самому приложению сообщение WMPAINT. Приложение, получив это сообщение, должно перерисо­вать содержимое клиентской области окна, содержимое же заголовка окна перерисовывает Windows. Обработка WMPAINT включается в оконную функцию любого приложения, которое что-либо выводит на экран, Приложение может само информировать Windows, что ему тре­буется послать сообщение WMPAINT. Это осуществляется с исполь­зованием функций InvalidateRect, InvalidateRgn, UpdateWindow. In-validateRect объявляет заданную прямоугольную область окна повре­жденной, что приводит к генерации Windows сообщения WMPAINT. UpdateWindow передает WMPAINT непосредственно в оконную функцию.

Рассмотрим классический алгоритм обработки в оконной функции сообщения WMPAINT:

1) Получить у системы контекст устройства для окна. Для этого вызывается функция BeginPaint, имеющая два параметра. Первый -это дескриптор окна, в который будет направлен вывод изображения. Второй параметр это адрес структуры PAINTSTRUCT, которую BeginPaint заполняет данными. Описание PAINTSTRUCT для MASM32 находится в windows.inc, а для С в winuser.h.

PAINTSTRUCT STRUCT
hDC    DWORD
?         ; дескриптор выделяемого контекста устройства

fErase DWORD ?       ; флаг перерисовки фона окна

rcPaint RECT <>        ; область вырезки

fRestore DWORD ?      ; зарезервировано flncUpdate DWORD ? ; зарезервировано

rgbReserved BYTE 32 dup(?) ; зарезервировано PAINTSTRUCT ENDS

Рассмотрим поля структуры. Если при заполнении структуры WNDCLASS не задать кисть для закрашивания фона окна, то функция BeginPaint установит флаг перерисовки окна ненулевым. Это означа­ет, что приложение должно само закрашивать фон окна, иначе оно бу­дет прозрачным. Этот режим практически не используется, и при зада­нии кисти флаг перерисовки фона устанавливается равным нулю. Об­ласть вырезки представляет собой структуру RECT, описывающую прямоугольную область, которую необходимо перерисовать:

RECT STRUCT

left        dd ? ; Х-координата левого верхнего угла
top       dd ? ; Y-координата левого верхнего угла

right      dd ? ; Х-координата правого нижнего угла bottom dd ? ; Y-координата правого нижнего угла RECT ENDS

Координаты области вырезки указываются относительно начала клиентской области окна, и, если перерисовывается вся клиентская об­ласть, то при расчете размеров вырезки из размеров окна вьгаитается толщина рамки и ширина заголовка. Перерисовка всей клиентской об­ласти самый простой вариант, однако по координатам области вы­резки можно реализовать перерисовку только испорченной области, что и делают функции GDI, даже если пользователь решил перерисо­вать все.

Функция BeginPaint возвращает дескриптор контекста монитора для клиентской области окна.

2)         Установить свои режимы рисования или характеристики инст­рументов и сформировать требуемое изображение с помощью функ­ций GDI, требующих контекст в качестве одного из параметров;

3)                   С помощью вызова функции EndPaint вернуть Windows кон­текст устройства, возвратив его в исходное состояние. Параметры EndPaint те же, что и у BeginPaint.

В программе на MASM32 это реализуется следующим образом:

include \masm32\include\gdi32.inc includelib \masm32\lib\gdi32.lib

В WndProc:

LOCAL hDC  :DWORD LOCAL Ps   :PAINTSTRUCT

.if Msg = WM_PAINT

invoke BeginPaint,hWin,ADDR Ps

mov hDC, eax invoke Paint_Proc,hWin,hDC invoke EndPaint,hWin,ADDR Ps

Если контекст монитора необходим вне обработки WMPAINT, то его можно получить функцией GetDC (для клиентской области окна) или GetWindowDC (для всего окна), а освободить функцией Re-leaseDC. Контекст, полученный с помощью GetDC, позволяет работать не с регионом, а со всей клиентской областью, и не требует объявления региона испорченным для генерации WMPAINT, в отличие от BeginPaint.

Для получения дескриптора контекста принтера используется функция CreateDC, а для его освобождения функция DeleteDC.

Научившись получать в программе дескриптор контекста устрой­ства, рассмотрим, как вывести на монитор графическую информацию.

Источник: Сучкова, Л.И. Win32 API: основы программирования: учебное пособие/ Л.И. Сучкова; АлтГТУ им. ИИ. Ползунова. -Барнаул, АлтГТУ, 2010. 138 с, ил.

По теме:

  • Комментарии