НАЦІОНАЛЬНИЙ УНІВЕРСИТЕТ “ЛЬВІВСЬКА ПОЛІТЕХНІКА”
Лабораторна робота №2
з дисципліни “ Операційні системи ”
“Робота з методами DirectDraw ”
Bиконав:
студент групи КН – 20
Лектор: Зербіно Д. Д.
Керівник лабораторних занять: Зербіно Д. Д.
Львів – 2012
Мета ( Зрозуміти принципи та навчитись використовувати методи DirectDraw.
ТЕОРЕТИЧНІ ПОЛОЖЕННЯ
Для роботи з графікою існує обширний набір функцій GDI (Graphics Device Interface) – інтерфейс графічного пристрою. Ці функції універсальні як для малювання як на екрані, так і на принтері, але платою за універсальність є швидкодія. Створити більш-менш динамічну графічну програму з використанням лише GDI-функцій (наприклад, SetPixel) практично неможливо. На допомогу приходять методи прямого запису даних у відео-пам’ять, які дають максимальну швидкодію.
Методи DirectDraw включаються в концепцію DirextX, який включає в себе також методи DirectSound та Direct3D, які постійно поновлюються. Саме тому компанія Microsoft вирішила, що зручніше поновлювати таблицю віртуальних методів, ніж кожний раз створювати нові API-функції для нових версій методів, і реалізувала їх як звичайні методи абстрактних COM-об’єктів.
Для створення екземпляру об’єкту DirectDraw можна використовувати звичайний механізм створення COM-об’єктів за допомогою API-функції CoCreateInstance, яку ви використовували в лабораторній роботі №1. Після створення його необхідно ініциалізувати методом ініціалізації (див. таблицю 5), але цього можна не робити, якщо використовувати спеціалізовану API-функцію DirectDrawCreate. Параметрами цієї функції є ідентифікатор версії (або 0 ( для поточної версії), адреса змінної, яка буде містити вказівник на об’єкт після виконання функції, а також зарезервований параметр (що дорівнює 0).
Особливістю використання об’єкту DirectDraw є те, що він вимагає наявність вікна. Вікно можна створити з довільними параметрами, навіть не видимим. Виконання функції DirectDrawCreate необхідно робити тоді, коли вікно вже створене, тобто у віконній процедурі при обробці повідомлення WM_CREATE. Одразу ж після створення об’єкту DirectDraw необхідно викликати його 20-й метод “SetCooperativeLevel” (таблиця 5), який встановить ексклюзивні права на область відео-пам’яті, яку ви використовуєте та зарезервує повноекранний відео-буфер, який електронними засобами відео-карти буде відображатись на екрані монітору. Після цього необхідно переключити відео-карту у потрібний відео-режим за допомогою 21-го методу “SetDisplayMode”. В параметрах цього метода необхідно вказати ширину та висоту екрану в пікселях, а також кількість біт на один піксель.
Таблиця 5
№
Адр.
Назва методу
параметри
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
18
19
20
21
22
00
04
08
0c
10
14
18
1c
20
24
28
2c
30
34
38
3c
40
44
48
4c
50
54
58
QueryInterface
AddRef
Release
Compact
CreateClipper
CreatePalette
CreateSurface
DuplicateSurface
EnumDisplayModes
EnumSurfaces
FlipToGDISurface
GetCaps
GetDisplayMode
GetFourCCCodes
GetGDISurface
GetMonitorFrequency
GetScanLine
GetVerticalBlankStatus
Initialize
RestoreDisplayMode
SetCooperativeLevel
SetDisplayMode
WaitForVerticalBlank
riid, LPVOID ppvObj
LPDIRECTDRAWCLIPPER FAR*, Iunknown
LPPALET, LPDIRECTDRAWPAL, IUnknown
LPDDSURF, LPDIRECTDRAWSURF, IUnknown
LPDIRECTDRAWSURF, LPDIRECTDRAWSURF
LPDDSURF, LPVOID, LPDDENUMMODCALLBACK
LPDDSURF,LPVOID,LPDDENUMSURFACESCALLB
LPDDCAPS;
LPDWORD
*
*
*
LPBOOL
GUID
HWND, DWORD
DWORD, DWORD,DWORD
DWORD, HANDLE
Після того, як відео-карта переключена у відповідний режим, можна створити об’єкт Surface, методи якого показані в таблиці 6. Для створення цього об’єкту використовуємо 7-й метод DirectDraw: “CreateSurface” (таблиця 5). Результатом цього методу буде вказівник LPS на новий об’єкт Surface, який представляє видиму відео-сторінку, і методи якого представлені в таблиці 6 (див. програму далі). Одним з параметрів цього метода є вказівник на структуру DDSURFACEDESC2, в якій буде записана адреса відео-сторінки (lpSurface), в яку можна буде записати відео-дані.
Для роботи з іншою відео-сторінкою, яка в даний момент не видима необхідно отримати іншу таблицю віртуальних методів за допомогою метода “GetAttachedSurface” об’єкта LPS (таблиця 6, див. програму далі). В результаті виконання цього методу отримуємо вказівник DDBACK на таблицю віртуальних методів для роботи з невидимою відео-сторінкою. Тепер утворені всі необхідні компоненти DirectDraw і можна приступати до малювання.
Таблиця 6
№
Адр.
Назва методу
параметри
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
26
27
28
29
30
31
32
33
34
35
36
00
04
08
0c
10
14
18
1c
20
24
28
2c
30
34
38
3c
40
44
48
4c
50
54
58
5c
60
64
68
6c
70
74
78
7c
80
84
88
8c
QueryInterface
AddRef
Release
AddAttachedSurface
AddOverlayDirtyRect
Blt
BltBatch
BltFast
DeleteAttachedSurface
EnumAttachedSurfaces
EnumOverlayZOrders
Flip
GetAttachedSurface
GetBltStatus
GetCaps
GetClipper
GetColorKey
GetDC
GetFlipStatus
GetOverlayPosition
GetPalette
GetPixelFormat
GetSurfaceDesc
Initialize
IsLost
Lock
ReleaseDC
Restore
SetClipper
SetColorKey
SetOverlayPosition
SetPalette
Unlock
UpdateOverlay
UpdateOverlayDisplay
UpdateOverlayZOrder
REFIID riid, LPVOID ppvObj
LPDIRECTDRAWSURFACE
LPRECT
LPRECT,LPDIRECT, LPRECT,DWRD, LPDDBLT
LPDDBLTBATCH, DWORD, DWORD
DWORD,DWORD,LPDIRECT, LPRECT,DWORD
DWORD,LPDIRECTDRAWSURFACE) PURE
LPVOID,LPDDENUMSURFACESCALLBACK
DWORD,LPVOID,LPDDENUMSCALLBACK
LPDIRECTDRAWSURFACE, DWORD
LPDDSCAPS, LPDIRECTDRAWSURFACE
DWORD
LPDDSCAPS
PURE,LPDIRECTDRAWCLIPPER FAR
DWORD, LPDDCOLORKEY
HDC
DWORD
LPLONG, LPLONG
LPDIRECTDRAWPALETTE FAR
LPDDPIXELFORMAT
LPDDSURFACEDESC
LPDIRECTDRAW, LPDDSURFACEDESC
LPRECT,LPDDSURFACEDESC,DWORD,HANDLE
HDC
LPDIRECTDRAWCLIPPER
DWORD, LPDDCOLORKEY
LONG, LONG
LPDIRECTDRAWPALETTE
LPVOID
LPRECT, LPDIR,LPRECT,DWD, LPDDOVERLAX
DWORD
DWORD, LPDIRECTDRAWSURFACE
Для малювання в програмі необхідно створити таймер, і при надходженні у віконну процедуру повідомлення WM_TIMER необхідно переключити відео-сторінки. Таким чином можна досягти плавності малювання об’єктів, які рухаються, тому що коли на екрані зображена одна відео-сторінка, процес виводу змінює відео-дані іншої сторінки, яка в даний момент не видима.
Для запису у відео-сторінку необхідно, щоб вона була фізично присутня в пам’яті, тому перед записом необхідно застосувати метод Lock з таблиці віртуальних методів об’єкту DDBACK невидимої відео-сторінки. Ця таблиця має таку ж саму структуру, як і таблиця 6, але всі методи відносяться до невидимої відео-сторінки.
В результаті виконання 26-го метода “Lock” змінна lpSurface буде містити початок невидимої відео-сторінки, яку використовує процедура малювання. Після закінчення малювання використовується 12-й метод “Flip” з таблиці віртуальних методів для видимої відео-сторінки LPS. Метод “Flip” фактично міняє місцями відео-сторінки на екрані монітору, але вказівники LPS і DDBACK як і раніше містять адреси методів для роботи з видимою і невидимою відео-сторінками. Після малювання бажано розблокувати відео-сторінку методом “Unlock” (№33 у таблиці 6).
Програмна реалізація:
Вміст файла keyboard.txt:
VK_RIGHT equ 27h
VK_LEFT equ 25h
VK_UP equ 26h
VK_DOWN equ 28h
.data
x1 dd 40
x2 dd 260
x3 dd 110
x4 dd 25
x5 dd 49
x6 dd 70
x7 dd 75
x8 dd 90
x9 dd 100
x10 dd 140
x11 dd 160
x12 dd 210
x13 dd 205
x14 dd 265
x15 dd 250
x16 dd 220
x17 dd 260
x18 dd 215
x19 dd 204
x20 dd 165
x21 dd 170
x22 dd 199
x23 dd 200
.code
cmp msWPARAM, VK_RIGHT
jnz END_RIGHT
add x1,2
add x2,2
add x3,2
add x4,2
add x5,2
add x6,2
add x7,2
add x8,2
add x9,2
add x10,2
add x11,2
add x12,2
add x13,2
add x14,2
add x15,2
add x16,2
add x17,2
add x18,2
add x19,2
add x20,2
add x21,2
add x22,2
add x23,2
END_RIGHT:
cmp msWPARAM, VK_LEFT
jnz END_LEFT
dec x1
dec x2
dec x3
dec x4
dec x5
dec x6
dec x7
dec x8
dec x9
dec x10
dec x11
dec x12
dec x13
dec x14
dec x15
dec x16
dec x17
dec x18
dec x19
dec x20
dec x21
dec x22
dec x23
END_LEFT:
Вміст файла MAIN.txt:
.586
.model flat, stdcall
extrn CreateWindowExA:Proc, RegisterClassA:Proc, GetMessageA:Proc
extrn GetProcAddress:proc, LoadLibraryA:proc, DeleteObject:proc
extrn DispatchMessageA:Proc, DefWindowProcA:Proc, MessageBoxA:Proc
extrn SetTimer:Proc, ShowCursor:Proc, TextOutA:Proc, Ellipse:Proc
extrn lstrlen:Proc, SetBkMode:Proc, ExitProcess:Proc, SetTextColor:proc, CreateFontIndirectA:proc, SelectObject:proc
extrn GetDC:Proc, ReleaseDC:Proc, CreateCompatibleDC:Proc, CreateDIBSection:Proc, GetDeviceCaps:Proc
extrn CreateFileA:Proc, GetFileSize:Proc, CloseHandle:Proc, ReadFile:Proc
extrn CreateStreamOnHGlobal:Proc, OleLoadPicture:Proc, MulDiv:Proc
extrn GlobalAlloc:Proc, GlobalLock:Proc, GlobalUnlock:Proc, GlobalFree:Proc
extrn LoadImageA:proc, GetObjectA:Proc, _wsprintfA:proc, CreateSolidBrush: proc
extrn CreatePen: Proc, MoveToEx: proc, LineTo: proc, Ellipse: proc, Rectangle: proc, CreateSolidBrush: proc
LR_LOADFROMFILE equ 10h
LR_DEFAULTSIZE equ 40h
LR_CREATEDIBSECTION equ 2000h
SetCooperativeLevel equ 50h
SetDisplayMode equ 54h
CreateSurface equ 18h
Surface_Lock equ 64h
Surface_Unlock equ 80h
Surface_Restore equ 6Ch
Surface_GetDC equ 44h
Surface_ReleaseDC equ 68h
GetAttachedSurface equ 30h
Surface_Flip equ 2Ch
WM_CREATE equ 1h
WM_KEYDOWN equ 100h
WM_TIMER equ 113h
WS_POPUP equ 80000000h
DDSD_CAPS equ 000001h
DDSD_PITCH equ 000008h
DDSD_BACKBUFFERCOUNT equ 000020h
DDSCAPS_PRIMARYSURFACE equ 200h
DDSCAPS_FRONTBUFFER equ 20h
DDSCAPS_BACKBUFFER equ 04h
DDSCAPS_FLIP equ 10h
DDSCAPS_COMPLEX equ 08h
DDLOCK_WAIT equ 1
DDFLIP_WAIT equ 1
DDSCL_FULLSCREEN equ 1h
DDSCL_EXCLUSIVE equ 10h
DDSCAPS_VIDEOMEMORY EQU 00004000h
;=======================================================
.data
ddraw_dll db "ddraw.dll",0
hLib dd 0
DirectDrawCreate1 dd 0
DirectDrawCreate2 db "DirectDrawCreate",0
wc: dd 0, offset WndProc, 7 dup(0), offset WndClassName
msg:
msHWND dd 0
msMESSAGE dd 0
msWPARAM dd 0
msLPARAM dd 0
msTIME dd 0
ptX dd 0
ptY dd 0
NewHWnd dd 0
WndClassName db "DeepPurple",0
TEXT1 db "by Nykytenko",0
;--------------------------------
SCREEN_WIDTH dd 1024;800;1280
SCREEN_HEIGHT dd 768;600;1024;
SCREEN_BPP dd 32
;-------------------------------
LPDD dd 0 ; ddraw interface pointer
LPS dd 0
DDBACK dd 0
LOGFONTA:
lfHeight DD 50 ; Висота
lfWidth DD 20 ; Ширина
lfEscapement DD 3600 ; Кут нахилу * 10
lfOrientation DD 0 ;
lfWeight DD 1000 ; Жирнiсть (1000-Bold)
lfItalic DB 1 ; Курсив
lfUnderline DB 1 ; Пiдкреслення
lfStrikeOut DB 0
lfCharSet DB 1 ; 255 – шрифти DOS
lfOutPrecision DB 0
lfClipPrecision DB 0
lfQuality DB 1
lfPitchAndFamily DB 0
lfFaceName DB 'Algerian' ; Назва фонту
Reserv DB 32-6 dup(0)
hfont dd 0
DDSURFACEDESC2:
dd 108,DDSD_CAPS or DDSD_BACKBUFFERCOUNT,0,0
lPitch dd 0 ; СКІЛЬКИ БАЙТ ЗНАХОДИТЬСЯ В РЯДКУ ЕКРАНУ
dwBackBufferCount dd 1,0,0,0
lpSurface dd 0,16 dup(0) ; вказівник на початок відео-сторінки
ddsCaps dd DDSCAPS_PRIMARYSURFACE or DDSCAPS_FLIP or DDSCAPS_COMPLEX ;or DDSCAPS_VIDEOMEMORY
dwTextureStage dd 0
BEGIN_COLOR dd 00
HDC dd 0
X dd 0
Y dd 0
X1 dd 0
Y1 dd 0
HV dd 1
VV DD 1
R db 0
G db 0
B db 0
flg_color dd 1
ImageName db "0.bmp",0
ADR_BMPSCR1 dd 0
FORMAT_EAX DB "eax= %Xh",0
HRedPen dd 0
OldPos dd 0,0
HGreenPen dd 0
HYELLPen dd 0
HBRUSHRED dd 0
HBRUSHGRAY dd 0
HBRUSHBLACK dd 0
HBRUSHYELL dd 0
HBLACKPen dd 0
HBRUSHGreen dd 0
HGOLDPen dd 0
HFont dd 0
;===============================================
.data?
BUFOBJECT db 260 dup(?) ; адреса обов'язково повинна бути парною
CopyVideo dd 2000*768 dup(?)
;======================================================
.code
Start:
call CreatePen,0, 2, 0000ffh
mov HRedPen, eax
call CreatePen,0, 2, 00ff00h
mov HGreenPen, eax
call CreatePen,0, 2, 06fff0h
mov HYELLPen, eax
call CreatePen,0, 3, 465945h
mov HBLACKPen, eax
call CreatePen,0, 2, 4F7942h
mov HGOLDPen, eax
Call CreateSolidBrush, 00FF00h
mov HBRUSHGreen, eax
Call CreateSolidBrush, 0000ffh
mov HBRUSHRED, eax
Call CreateSolidBrush, 3D2B1Fh
mov HBRUSHBLACK, eax
Call CreateSolidBrush, 06fff0h
mov HBRUSHYELL, eax
call CreateFontIndirectA, offset LOGFONTA
mov HFont, eax
call LoadImageA,0,offset ImageName,0,0,0,LR_LOADFROMFILE or LR_CREATEDIBSECTION or LR_DEFAULTSIZE
cmp eax,0
jz STOP
mov ADR_BMPSCR1,eax
call GetObjectA,ADR_BMPSCR1,0,0
call GetObjectA,ADR_BMPSCR1,eax,offset BUFOBJECT
cmp eax,0
jz STOP
;---------------------------------
call LoadLibraryA, offset ddraw_dll
mov hLib, eax
call GetProcAddress, hLib, offset DirectDrawCreate2
mov DirectDrawCreate1,eax
;--------------------------------
call RegisterClassA,offset wc
call CreateWindowExA,0,eax,0,WS_POPUP,1,1,1,1,0,0,0,0
mov NewHWnd,eax
call ShowCursor,0
call SetTimer,NewHWnd,0,10,offset WndProc
;===================================================
msg_loop: call GetMessageA,offset msg,NewHWnd,0,0
cmp eax,-1
jz STOP
cmp msMESSAGE,WM_KEYDOWN
jnz CONTINUE_LOOP
cmp msWPARAM,1bh
jz STOP
;-----------------
include keyboard.txt
;-----------------
CONTINUE_LOOP:
call DispatchMessageA,offset msg
jmp msg_loop
STOP: call ExitProcess,0
; LPDD -> SetDisplayMode(...)
; LPDD -> CreateSurface(...)
; LPS -> GetAttachedSurface(...)
;=====================================================
WndProc proc hwnd:DWORD, wmsg:DWORD, wparam:DWORD, lparam:DWORD
cmp wmsg,WM_CREATE ; Створення об’єктів DirectDraw та Surface
jnz TIMER
call [DirectDrawCreate1], 0, offset LPDD, 0
mov eax,LPDD
mov eax, [eax]
call [eax+SetCooperativeLevel],LPDD, hwnd, DDSCL_EXCLUSIVE OR DDSCL_FULLSCREEN
mov eax,LPDD
mov eax, [eax]
call [eax+SetDisplayMode],LPDD, SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP
mov eax, LPDD
mov eax, [eax]
call dword ptr [eax+CreateSurface],LPDD, offset DDSURFACEDESC2, offset LPS,0
or eax,eax
jnz STOP
; в результаты створився об'єкт іншого типу: Surface з таблицею методів LPS
mov ddsCaps,DDSCAPS_BACKBUFFER
mov eax,LPS
mov eax, [eax]
call dword ptr [eax+GetAttachedSurface],LPS, offset ddsCaps, offset DDBACK
or eax,eax
jnz STOP
;---------------------------------------------------------------------------------------------------
TIMER: cmp wmsg,WM_TIMER
jnz EXIT1 ; Обробка подій від таймеру
mov eax,DDBACK
mov eax, [eax]
call dword ptr [eax+Surface_Lock], DDBACK, 0, offset DDSURFACEDESC2, DDLOCK_WAIT, 0
or eax,eax
jnz NO_PAINT
; сторінка з'являється в реальній лінійній адресі lpSurface, яка є елементом структури DDSURFACEDESC2
; DDLOCK_WAIT означає, що чектиме, доки метод не виконається
call PAINT ; Ваша процедура малювання
mov eax,LPS
mov eax, [eax]
call [eax+Surface_Flip],LPS,0,0 ; обміняти місцями відео-сторінки
NO_PAINT:
EXIT1: call DefWindowProcA, hwnd, wmsg, wparam, lparam
ret
WndProc endp
;=====================================================
PAINT:
;================== фрагмент, що малює прямим записом даних у відео-сторінку
pushad
cld ; автоінкрементна адресація по EDI в команді STOSD
;jmp zzz
mov edx,SCREEN_HEIGHT
;---------
add BEGIN_COLOR,0705h
mov eax,BEGIN_COLOR
and eax,0ffffffh
mov edx,SCREEN_HEIGHT
mov ebx,offset CopyVideo ;lpSurface ; початок відео-сторінки
L_BLT: mov edi,ebx
mov ecx,SCREEN_WIDTH
dec flg_color
jnz NO_COLOR
mov flg_color,5 ; щоб колір змінювався не так швидко
add eax,000103h ; зміна червоної і синьої компоненти на 1
NO_COLOR:
push ebx
push eax
mov ebx,edi
sub ebx,offset CopyVideo
add ebx,lpSurface ; перейшли в адресу відео-сторінки
not ax
L_BLT2:
push eax
stosd ; Прямий запис (stosd) в копію відео-пам’яті в циклі по ECX
mov [ebx],eax ; Прямий запис по [ebx] у відео-пам’ять в циклі по ECX
add ebx,4
pop eax
dec ecx
jnz L_BLT2
pop eax ; repnz = repeat if not zero
pop ebx
add ebx,lPitch ; Перехід на новий рядок
dec edx ; цикл по SCREEN_HEIGHT
jnz L_BLT
;---------------------------------------- переведення координат X,Y в адресу lpSurface
mov edi,X
mov eax,Y
mul dword ptr lPitch
shl edi,2
add edi,eax
add edi,offset CopyVideo ;lpSurface
;----------------------------------------
mov esi,offset BUFOBJECT
mov ecx,[esi+4]
mov ebx,[esi+12]
mov eax,[esi+8]
dec eax
mul ebx
mov edx,[esi+8]
mov esi,[esi+20]
add esi,eax
L_BMP2:
push ebx
push edx
push edi
push esi
push ecx
mov ebx,edi
sub ebx,offset CopyVideo ; знайшли зміщення в середині відео-сторінки
add ebx,lpSurface ; знайшли лінійну адресу комірки відео-пам'яті, яка відповідає даному зміщенню
mov dl,PROZORIST ; коефіциєнт прозорості для BMP
mov dh,255
sub dh,dl ; коефіциєнт прозорості для фону
L_BMP1:
; mov eax,[esi] ; читання з BMP
;------------------------------------------------- змішування кольорів по їх коефіцієнтах прозорості
.data
RED dw 0
Green dw 0
Blue dw 0
PROZORIST db 1
.code
mov al,[esi]
mul dl
mov RED,ax
mov al,[esi+1]
mul dl
mov Green,ax
mov al,[esi+2]
mul dl
mov Blue,ax
;-------------
mov al,[edi]
mul dh
add ax,RED
mov [ebx],ah ; запис у відео-сторінку
mov al,[edi+1]
mul dh
add ax,Green
mov [ebx+1],ah ; запис у відео-сторінку
mov al,[edi+2]
mul dh
add ax,Blue
mov [ebx+2],ah ; запис у відео-сторінку
;-------------------------------------------------
add edi,4
add ebx,4
add esi,3 ; перехід на наступний піксель в BMP
dec ecx ; лічильник пікселів по горизонталі
jnz L_BMP1
pop ecx ; лічильник пікселів по горизонталі
pop esi
pop edi
pop edx
pop ebx
sub esi,ebx ; перехід на наступний рядок в BMP
add edi,lPitch ; перехід на наступний рядок на екрані
dec edx ; лічильник пікселів по вертикалі
jnz L_BMP2
inc PROZORIST ; збільшили прозорість
;----------------------------------------
popad
;=======================================================
mov eax,DDBACK
mov eax, [eax]
call [eax+Surface_Unlock],DDBACK,0
; сторінка розблоковується (стає віртуальною) для того, щоб її передати
; у бібліотеку GDI32.dll
mov eax,DDBACK
mov eax, [eax]
call [eax+Surface_GetDC],DDBACK,offset HDC
; отримали графічний контекст тіньової відео-сторінки
; і тепер можна використовувати стандартні GDI-функції.
call SetBkMode,HDC,1
call SelectObject,HDC,HBRUSHYELL
Call Rectangle,HDC,x1,430,x2,375
Call MoveToEx,HDC,x1,375,offset OldPos
Call LineTo,HDC,x1,325
Call LineTo,HDC,x9,325
Call LineTo,HDC,x21,375
Call MoveToEx,HDC,x3,330,offset OldPos
Call LineTo,HDC,x21,330
call SelectObject,HDC,HBRUSHBLACK
call SelectObject,HDC,HBLACKPen
Call Ellipse, HDC, x6,418,x9,458
Call Ellipse, HDC, x21,418,x23,458
call SelectObject,HDC,HFont
call lstrlen,offset TEXT1
call TextOutA,HDC,X1,Y1,offset TEXT1,eax
;=============================== закінчили малювання засобами GDI
mov eax,DDBACK
mov eax, [eax]
call [eax+Surface_ReleaseDC],DDBACK,HDC
;--------------------------
mov eax,HV ; цього можна і не робити, якщо не змінюват координати тексту
add X1,eax
mov eax,VV
add Y1,eax
cmp X1,500 ;570 ; межі за які не виходить текст
jb M1
neg HV
M1: cmp Y1,400 ;530 ; межі за які не виходить текст
jb M2
neg VV
M2:
;-------------------------
ret
;---------------------------------- Процедура для перетворення EAX у 16-бітний колір
end Start
Скіншот виконання прорами:
Висновки: Для застосування до відео-сторінки функцій GDI (наприклад, вивід тексту) необхідно застосувати 18-й метод “GetDC” з таблиці віртуальних методів відповідної відео-сторінки. Після закінчення використання функцій GDI в даній відео-сторінці необхідно викликати 27-й метод “ReleaseDC”.