Главная » Win32 API » Примеры вывода в клиентскую область окна графики и текста

0

Пусть в приложении необходимо выводить в клиентскую область окна текст, графические примитивы и растровое изображение. Для то­го чтобы можно было выполнять этот вывод независимо и в нужной последовательности, будем при нажатии клавиши «1» выводить стро­ки текста, при нажатии клавиши «2» выводить графические фигуры, а при нажатии «3» растровое изображение. Тогда выбор при выводе будем запоминать в переменной w при обработке сообщения об отпус­кании клавиши WMKEYUP, а собственно вывод будем реализовы-вать в функциях Font_Draw,   Graf_Draw и Paint_Proc:

.elseif uMsg == WM_KEYUP . if wParam=VK_l

mov w,1 . elseif wParam=VK_2

mov w,2 . elseif wParam=VK_3

mov w,3 .endif

invoke InvalidateRect,hWin,NULL,TRUE .elseif uMsg == WM_PAINT

invoke BeginPaint,hWin,ADDR Ps mov hDC, eax .if w==l

invoke Font_Draw,Ps.hdc .elseif w==2

invoke Graf_Draw,Ps.hdc .elseif w==3

invoke Pa±nt_Proc,hWin,hDC .endif invoke EndPaint,hWin,ADDR Ps return 0

Демонстрационная функция для вывода текста:

Font_Draw proc hDC :HDC LOCAL hObj :DWORD LOCAL hOldObj :DWORD s z Text s z S tring, " *As sembler* " szText FontO,"Times New Roman" s z Text Fontl,"Century Go thic" szText Font2,"Monotype Corsiva" RGB 34,57,94 invoke SetBkColor,hDC,eax

;выведем текст OEM-шрифтом, дескриптор уже существует invoke GetStockObject,OEM_FIXED_FONT mov hObj,eax

invoke SelectObject,hDC,hobj mov h01dObj,eax

invoke TextOut,hDC,20,20,offset szString,ll invoke SelectObject,hDC,h01dObj invoke DeleteObject,hobj

;выведем текст системным шрифтом

invoke GetStockObject,SYSTEM_FONT

mov hObj,eax

invoke SelectObject,hDC,hObj

mov h01dObj,eax

invoke TextOut,hDC,450,450,offset szString,ll

invoke SelectObject,hDC,h01dObj

invoke DeleteObject,hObj

;заполняем структуру типа LOGFONT mov Font.IfHeight,40 mov Font.lfWidth,15 mov Font.lfEscapement,150 ;наклон mov Font.IfOrientation,50 ;наклон букв mov Font.lfWeight,1000    ;толщина mov Font.IfItalic,FALSE mov Font.lfUnderline,TRUE mov Font.IfS trikeOut,FALSE

mov Font.lfCharSet,ANSI_CHARSET ;начертание mov Font.lfOutPrecision,OUT_OUTLINE_PRECIS mov Font.IfClipPrecision,CLIP_DEFAULT_PRECIS

mov Font.lfQuality,DRAFT_QUALITY

mov Font. IfPitchAndFamily, 0

invoke lstrcpy, addr Font.IfFaceName, addr FontO ; копируем имя гарнитуры шрифта из FontO

invoke CreateFontIndirect,addr Font

mov hObj,eax

invoke SelectObject,hDC,hObj

invoke SetTextColor,hDC,155

invoke TextOut,hDC,250,100,offset szString,ll

invoke DeleteObject,hObj ; изменим параметры шрифта и цвет текста при выводе

INVOKE lstrcpy, addr Font.IfFaceName, addr Fontl

mov Font.IfHeight,20

mov Font.lfWidth,30

mov Font.lfEscapement,0

mov Font.lfUnderline,FALSE

mov Font.IfS trikeOut,TRUE

invoke CreateFontIndirect,addr Font

mov hObj,eax

invoke SelectObject,hDC,hObj

invoke SetTextColor,hDC,249

invoke TextOut,hDC,50,350,offset szString,ll

invoke DeleteObject,hObj ; еще раз изменим параметры шрифта и цвет текста

invoke lstrcpy, addr Font.IfFaceName, addr Font2

mov Font.IfHeight,20

mov Font.lfWidth,15

mov Font.lfUnderline,FALSE

mov Font.lfWeight,100

mov Font.IfS trikeOut,FALSE

mov Font.IfItalic,TRUE invoke CreateFontIndirect,addr Font

mov hObj,eax

invoke  SelectObject,hDC,hObj

invoke  SetTextColor,hDC,50

invoke  TextOut,hDC,60,160,offset  szString,ll

invoke DeleteObject,hObj

ret Font_Draw endp

Демонстрационная функция для вывода графических примитивов:

Graf_Draw proc hDC:HDC LOCAL hObj:DWORD

LOCAL Xb:LOGBRUSH LOCAL pi:POINT LOCAL p2:POINT LOCAL p3:POINT LOCAL p4:POINT

invoke MoveToEx,hDC,5 0,10,NULL invoke LineTo,hDC,300,10

invoke CreatePen,PS_SOLID or PS_DOT,l,25

invoke SelectObject,hDC,eax

mov hObj,eax

invoke MoveToEx,hDC,5 0,3 0,NULL

invoke LineTo  ,hDC,300,30

invoke SelectObject,hDC,hObj

invoke DeleteObj ect,eax

mov lb.lbS tyle,BS_HATCHED

mov lb.lbColor,9452311

mov Xb.lbHatch,HS_BDIAGONAL

invoke CreateBrushlndirect,addr 1±>

invoke SelectObject,hDC,eax

invoke Rectangle,hDC,300,300,500,500

invoke Arc,hDC,200,200,300,90,310,90,310,590

invoke DeleteObj ect,eax

mov pi.x,250

mov pi.y,300

mov p2.x,550

mov p2.y,300

mov p3.x,400

mov p3.y,200

mov lb.lbS tyle,BS_HATCHED

mov Xb.lbColor,14950000

mov Xb.lbHatch,HS_DIAGCROSS

invoke CreateBrushlndirect,addr 1±>

invoke SelectObject,hDC,eax

invoke Polygon,hDC,addr p3,3

invoke DeleteObj ect,eax

mov Xb.lbStyle,BS_SOLID

mov Xb.lbColor,00FF0000h

mov 1±). lbHatch, 0

invoke CreateBrushlndirect,addr 1±>

invoke SelectObject,hDC,eax

invoke Ellipse,hDC,375,230,425 ,280

invoke DeleteObj ect,eax

invoke CreatePen,PS_SOLID,8,255000 invoke  SelectObject,hDC,eax mov hObj,eax

mov li>. lbS tyle, BS_HATCHED mov Xb.lbColor,000000FFh mov 1±>. lbHatch, 0

invoke CreateBrushlndirect,addr 1±> invoke  SelectObject,hDC,eax

invoke Pie,hDC,10,120,110,220,350,120,90,120 invoke Pie,hDC,10,120,110,220,90,430,90,200 invoke Pie,hDC,10,120,110,220,-800,0,-800,800 invoke DeleteObj ect,eax invoke  SelectObject,hDC,hObj invoke DeleteObj ect,eax ret Graf_Draw endp

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

Пусть имеются 4 кадра imgl.bmp, img2.bmp img3.bmp, img4.bmp из мультфильма, приведенные на рисунке 2.2. Эти растровые изображе­ния опишем в файле ресурсов следующим образом:

100  BITMAP MOVEABLE                                 PURE LOADONCALL DISCARDABLE "imgl.bmp"

200  BITMAP MOVEABLE                                 PURE LOADONCALL DISCARDABLE "img2.bmp"

300  BITMAP MOVEABLE                                 PURE LOADONCALL DISCARDABLE "img3.bmp"

400  BITMAP MOVEABLE                                 PURE LOADONCALL DISCARDABLE "img4.bmp"

Идентификаторы растровых изображений при таком описании -это числа 100, 200, 300, 400.

Для того чтобы реализовать вывод мультфильма в клиентскую об­ласть окна, необходимо организовать циклический перебор номеров картинок и вывод текущей картинки. Обозначим номер картинки через nPicture и опишем эту переменную в WinMain:

nPicture dw  0

imgl.bmp

img4.bmp

Рисунок 2.2

Собственно перебор номеров картинок осуществляется при обра­ботке сообщения WMPAINT в оконной функции:

WndProc proc

hWin        :DWORD,

uMsg        :DWORD,

wParam    :DWORD,

lParam      :DWORD

LOCAL hDC LOCAL  Ps LOCAL hold

DWORD

PAINTSTRUCT

DWORD

.if uMsg == WM CREATE

.elseif uMsg == WM_PAINT invoke Sleep,200 задержка, чтобы изображения не менялись очень быстро выбор номера следующей картинки так, чтобы номера изменялись циклически от 100 до 400 .if nPicture == 400

mov nPicture,100 .elseif

add nPicture,100

.endif

invoke LoadBitmap,hInstance,nPicture ; загрузим текущую картинку

mov hBmp, eax ; запомним ее дескриптор

invoke BeginPaint,hWin,ADDR Ps ; получим контекст устройства и запомним его в еах

mov hDC, eax ; вызовем функцию рисования

invoke Paint_Proc,hWin,hDC ; вернем контекст устройства системе

invoke EndPaint,hWin,ADDR Ps ; обновление всей клиентской области окна hWnd ; недействительной

invoke RedrawWindow,hWnd,NULL, NULL,

RDW_INVALIDATE return 0 .elseif uMsg == WM_DESTROY

invoke PostQuitMessage,NULL ; посылка сообщения WM_QUIT в очередь потока .endif

invoke DefWindowPrос,hWin,uMsg,wParam,lParam ret WndProc endp

В функции PaintProc осущетвляется вывод текущего растра:

Paint_Proc proc hWin   :DWORD, hDC    :DWORD

LOCAL   hold   :DWORD

LOCAL   memDC  :DWORD ; создаем совместимый контекст

invoke CreateCompatibleDC,hDC

mov memDC, eax ; выбираем в совместимый контекст дескриптор растра

invoke SelectObject,memDC,hBmp ; и сохраняем дескриптор старого изображения

mov hold, eax ; выводим растр

invoke BitBlt,hDC,238,30,352,288,memDC,0,0,SRCCOPY ; возвращаем в совместимый контекст дескриптор старого ; изображения

invoke SelectObject,hDC,hold

invoke DeleteDC,memDC

return 0 Paint_Proc endp

Для реализации вывода последовательности изображений в разных местах клиентской области можно использовать таймер и при обра­ботке сообщения WMTIMER в оконной функции изменять номер изображения и координаты вывода:

.elseif uMsg == WM_TIMER inc nom_±mg .if nom_±mg =  500

mov nom_±mg,   100 .endif ;   увеличим координату х изображения

inc x_img

; увеличим координату у изображения

inc y_img

В функции вывода растра загружается изображение с номером nomimg и затем выводится:

invoke LoadBitmap,   hlnstance   ,nom_img mov img_BMP,eax invoke CreateCompatibleDC,hDC mov memDC,   eax

invoke  SelectObj ect,memDC,img_BMP mov hold,   eax ;вывод изображения invoke BitBlt,hDC,x_img,y_img,100,60,memDC,0,0,SRCCOPY invoke  SelectObject,hDC,hold

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

delay MACRO  num

invoke GetTickCount mov dval,   eax add dval,   num .while eax < dval

invoke GetTickCount .endw ENDM

Рассмотрим вывод движущегося объекта, например, автомобиля, причем при движении будем использовать несколько растров с авто­мобилем, которые отличаются углом поворота колес и наличием вы­хлопных газов.

Ресурсы описаны в файле rsrc.rc:

1  BITMAP MOVEABLE   PURE LOADONCALL DISCARDABLE "carl.bmp"

2  BITMAP MOVEABLE   PURE LOADONCALL DISCARDABLE "car2.bmp"

3  BITMAP MOVEABLE   PURE LOADONCALL DISCARDABLE "car3.bmp"

4  BITMAP MOVEABLE   PURE LOADONCALL DISCARDABLE "car4.bmp"

5  BITMAP MOVEABLE   PURE LOADONCALL DISCARDABLE "car5.bmp"

6  BITMAP MOVEABLE   PURE LOADONCALL DISCARDABLE "car6.bmp"

Библиотеки, прототипы функций и макроопределения описаны в файле line:

; включаемые файлы

include с:\MASM32\INCLUDE\windows.inc include с:\MASM32\INCLUDE\masm32.inc include с:\MASM32\lNCLUDE\gdi32.inc include с:\MASM32\INCLUDE\user32.inc include с:\MASM32\lNCLUDE\kernel32.inc ; включаемые библиотеки

includelib с:\MASM32\LIB\masm32.lib includelib с:\MASM32\LIB\gdi32.lib includelib с:\MASM32\LIB\user32.lib includelib с:\MASM32\LIB\kernel32.lib ; прототипы функций

WinMain PROTO :DWORD

WndProc PROTO :DWORD,:DWORD,:DWORD,:DWORD Paint_Proc   PROTO :DWORD,:DWORD , :DWORD Pause PROTO: DWORD ; Макросы

szText MACRO Name, Text:VARARG LOCAL 1Ы jmp 1Ы Name db Text,0 1Ы: ENDM

m2m MACRO Ml, M2 push M2 pop Ml ENDM

return MACRO arg mov eax, arg ret ENDM .data

szDisplayName db "Пример ",0
sze                          dd 0

var3                        dd 0

hWnd                        dd 0

hlnstance    dd 0
hBmp                        dd 0

x_x                          dd 0

; координата автомобиля

Текст программы, реализующей вывод растровых изображений:

.model flat, stdcall

option casemap :none

include 1.inc

. code

start:

invoke GetModuleHandle, NULL mov hlnstance, eax invoke WinMain,hlnstance invoke ExitProcess,eax ; главная функция WinMain proc hlnst:DWORD

LOCAL wc   :WNDCLASSEX

LOCAL msg  :MSG

szText szClassName,"myClass"

mov wc.cbSize,                       sizeof WNDCLASSEX

mov wc.style,                         CS_BYTEALIGNWINDOW

mov wc.lpfnWndProc,    offset WndProc

mov wc.cbClsExtra,     NULL

mov wc.cbWndExtra,     NULL

m2m wc.hlnstance,      hlnst

mov wc.hbrBackground,  COLOR_WINDOW

mov wc.lpszMenuName,   NULL

mov wc.lpszClassName,  offset szClassName

m2m wc.hlcon,                      NULL

invoke LoadCursor,NULL,IDC_ARROW

mov wc.hCursor,        eax

m2m wc.hlconSm,       NULL

invoke RegisterClassEx, ADDR wc

invoke CreateWindowEx,WS_EX_LEFT,

ADDR szClassName, ADDR szDisplayName, WS_OVERLAPPEDWINDOW, 200,300,420,200, NULL,NULL, hlnst,NULL mov hWnd,eax invoke ShowWindow,hWnd,SW SHOWNORMAL

invoke UpdateWindow,hWnd StartLoop:

invoke GetMessage,ADDR msg,NULL,0,0 cmp eax, 0 je ExitLoop

invoke DispatchMessage,  ADDR msg jmp StartLoop ExitLoop:

return msg.wParam WinMain endp

; оконная функция WndProc proc hWin   :DWORD, uMsg   :DWORD, wParam :DWORD, lParam :DWORD LOCAL count    :DWORD LOCAL pic    :DWORD

Local cordx:DWORD ; локальная координата х LOCAL hDC    :DWORD LOCAL Ps     :PAINTSTRUCT LOCAL tm     :TEXTMETRIC LOCAL hPen   :DWORD LOCAL hPenp  :DWORD szText TT,"My car" szText TTl,"Best" .if uMsg == WM_CREATE invoke GetDC,hWin mov hDC,eax

invoke CreatePen,PS_DASHDOT,20,00f59411h ; создание пера

mov hPen,eax ; сохранение дескриптора пера invoke ReleaseDC,hWin, hDC return 0 .elseif uMsg=WM_PAINT

invoke BeginPaint,hWin,ADDR Ps mov hDC, eax mov count,0 mov pic,1 mov cordx,20

.while count<17  ;цикл вывода изображения invoke LoadBitmap,hInstance,pic mov hBmp, eax inc count

add cordx,5

invoke Paint_Proc,hWin,hDC,cordx

invoke Pause,12000

.if pic==l

mov pic,2 .else

mov pic,1 .endif .endw

mov count,0 mov pic,3

.while count<12   ;цикл вывода изображения invoke LoadBitmap,hInstance,pic mov hBmp, eax inc count add cordx,10

invoke Paint_Proc,hWin,hDC,cordx invoke Pause,10000 .if pic==3

mov pic,4 .else

mov pic,3 .endif .endw

mov count,0 mov pic,5

.while count<14                                                          ;цикл

вывода изображения

invoke LoadBitmap,hInstance,pic

mov hBmp, eax

inc count

add cordx,15

invoke Paint_Proc,hWin,hDC,cordx

invoke Pause,8000

.if pic==5

mov pic,6 .else

mov pic,5 .endif .endw

invoke SetBkMode,hDC,l  ;прозрачный фон invoke SetTextColor,hDC,00f3434h ; смена цвета шрифта

invoke TextOut,hDC,140,10,ADDR TT,8 ; вывод строки ТТ

invoke SelectObject,hDC,hPen ; выбор дескриптора шрифта

mov hPenp,eax ; сохранение дескриптора по умолчанию

invoke SetTextColor,hDC,003252ffh ; смена цвета шрифта mov eax,10h

invoke TextOut,hDC,230,10,ADDR TT1,4 ;вывод строки ТТ1

invoke SelectObject,hDC,hPenp invoke EndPaint,hWin,ADDR Ps return 0 .elseif uMsg == WM_DESTROY

invoke DeleteObject,hPen ;удаление дескриптора пера

invoke PostQuitMessage,NULL return 0 .endif

invoke DefWindowProc,hWin,uMsg,wParam,IPar am ret WndProc endp ; процедура рисования

Paint_Proc proc hWin:DWORD, hDC:DWORD, cord:DWORD LOCAL hold:DWORD LOCAL memDC :DWORD invoke CreateCompatibleDC,hDC mov memDC, eax

invoke SelectObject,memDC,hBmp mov hold, eax ; копирование из памяти в окно .if cord>=225 invoke BitBlt,hDC,cord,50,120,80,memDC,0,0,SRCPAINT .else

invoke BitBlt,hDC,cord,50,120,80,memDC,0,0,SRCCOPY .endif

invoke SelectObject,hDC,hold invoke DeleteDC,memDC return 0 Paint_Proc endp ; функция для задержки Pause proc m:DWORD .while m>0 push m .while m>0 dec m .endw pop m

sub m,l .endw return 0 Pause endp

2.7 Упражнения

Написать программу, осуществляющую:

1.               Вывод текста с использованием не менее чем двух типов шрифтов

2.               Вывод графических примитивов (прямоугольники, эллипсы, дуги и т.п.) с использованием различных перьев и кистей для заливки;

3.               Вывод мини-мультфильма по сюжету.

Примеры заданий для мультфильма:

1.                    Море с видимой линией горизонта и плывущий кораблик.

2.                    Распускающийся цветок.

3.                    Кот, бегущий за мышкой.

4.                    Домик, из трубы которого идет дым.

5.                    Снеговик, тающий после появления солнышка.

6.                    С яблони падает яблоко.

7.                    Солнечное затмение.

8.                    На ясном небе появляется тучка, идет дождь, затем появляется радуга.

9.                    Золотая рыбка плавает в аквариуме.

10.              В прозрачный стакан капает вода из крана, уровень воды уве­личивается.

11.              Полет ракеты в космосе.

12.              Движущийся автомобиль с мигалкой.

13.              Карандаш, рисующий несколько разноцветных линий.

14.              Летящая бабочка.

15.              Цыпленок, клюющий зерно.

16.              Полет Винни-Пуха на воздушном шарике.

17.              Прыжок человека с парашютом с самолета.

18.              Полет летающей тарелки с изменением ее цвета.

19.              Человек, перепрыгивающий через препятствие.

20.              Часы с движущимися стрелками.

21.              Часы с электронным циферблатом.

22.              Часы с кукушкой.

23.              Паровоз тянет вагон, из трубы идет дым.

24.              Всплывающая подводная лодка.

25.   Закат солнца.

2.8 Контрольные вопросы

1.     Что такое GDI?

2.     Что такое контекст устройства?

3.     Какие графические объекты Вы знаете?

4.     Что такое регион? Перечислите типы регионов.

5.     Как обрабатывается сообщение WMPAINT?

6.     Какое назначение имеют функции GetDC и ReleaseDC?

7.     Поясните логику работы с инструментами рисования. Какие функ­ции при этом используются и где вызываются?

8.     Поясние назначение функции SelectObject.

9.     Какое перо используется по умолчанию?

10.      Какие параметры указываются для задания пера?

11.      Как запросить для использования дескриптор стандартной кисти?

12.      Какие функции используются для создания нестандартных кистей?

13.      Перечислите параметры шрифта.

14.      Какие шрифты GDI Вы знаете?

15.      Что такое базовая линия для физического шрифта?

16.      Как изменить цвет символов?

17.      Что такое системная палитра?

18.      Как формируется логическая палитра?

19.      Какие типы растров Вы знаете?

20.      Поясните использование ресурсов в приложении.

21.      Зачем используется идентификатор ресурса?

22.      Что такое совместимый контекст?

23.      Как осуществляется вывод DDB-растра?

24.      Какие параметры имеет функция BitBlt?

25.      Какое назначение имеет функция StretchBlt?

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

По теме:

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