Iczelion’s Tutorial Win32 ASM Tutorial 5 : More about Text
Tìm hiu các thuc tính ca ch
Trong Windows, khi trình bày văn bn, các ký t đưc th hin theo nhiu dng
khác nhau. Đây là mt trong nhng đặc trưng cơ bn ca giao din đồ ha - người dùng
(GUI – Graphical User Interface). Để thc hin điu này, Windows h tr nhiu dng
font ch khác nhau. Trong phn này, chúng ta tìm hiu các vn đề chính v các font ch,
màu sc cũng như cách s dng chúng để trình bày văn bn.
Tìm hiu v h thng màu
H thng màu ca Windows có được xây dng da trên h thng màu RGB
(R=Red, G=Green, B=Blue) – hiu nôm na là mi màu có được bng cách trn 3 màu cơ
bn là Red (đỏ), Green (xanh lá cây), Blue (xanh lam). Nếu bn mun s dng mt màu
trên Windows, bn phi cho biết giá tr ca 3 thành phn màu R, G, B nói trên. Mi thành
phn màu tương ng vi mt s t 0 đến giá tr ln nht (tùy theo s bit cho mi đim
nh), thông thường t t 0 đến 255 (giá tr 1 byte).
Ví d, nếu bn mun có màu đỏ “thun túy” thì bn phi ch định giá tr ca R,G, B ln
lượt là 255,0,0 (R=255, G=0, và B=0). Hay nếu bn mun có màu trng “thun túy” thì
giá tr ln lượt là 255,255,255. Như vy, đểđược màu mà bn cn thì rt khó khăn vi
h thng như vy, tr khi bn phi biết được giá tr ca 3 thông s màu tương ng trong
mi màu để. Đối vi màu ch và màu nn, bn dùng hàm SetTextColor và SetBkColor,
c hai đều s dng mt handle ca DC và mt giá tr màu 32-bit RGB. H thng 32-bit
giá tr RGB được định nghĩa như sau:
RGB_value struct
unused db 0
blue db ?
green db ?
red db ?
RGB_value ends
Người dch: Benina (REA TEAM) Trang 1
Tng hp và hiu chnh: NhatPhuongLe (VNCERT TEAM)
Iczelion’s Tutorial Win32 ASM Tutorial 5 : More about Text
Chú ý, byte đầu tiên không được dùng và nó s bng zero. Th t ca 3 byte màu còn li
R, G, B b đảo ngược li thành Blue, Green, Red. Tuy nhiên bn s không dùng cu trúc
này vì khó khăn trong vic khi to giá tr ban đầu cho các thành phn màu và s dng
chúng. Thay vì vy, chúng ta s to mt macro. Marco này nhn 3 tham s: Red, Green
và Blue. Nó s to mt giá tr 32-bit RGB theo yêu cu và np nó vào thanh ghi EAX.
Macro được định nghĩa như sau:
RGB macro red,green,blue
xor eax,eax
mov ah,blue
shl eax,8
mov ah,green
mov al,red
endm
Bn có th đặt macro này vào trong file include để dùng sau này.
Tìm hiu v font
Font ch trong Windows được chia thành hai nhóm, gi là font GDI và font thiết b. Font GDI được lưu
tr dưới dng tp tin trên đĩa, trong khi font thiết b được thiết kế sn trong thiết b xut tương ng, ví d
máy in. Đối vi font GDI, Windows chuyn văn bn thành nh bitmap sau đó chuyn đến máy in để in.
Như vy, ưu đim ca font GDI là độc lp vi thiết b xut, tuy nhiên tc độ x lý in chm hơn.
Các font GDI thông thường gm có: font bitmap, font vector font TrueType.
Font bitmap được cu thành t ma trn pixel, có li đim là hin th nhanh, nhưng hn chế trong
vic th hin vi các kích thước khác nhau (do ch phóng to, thu nh, và khi phóng s b b nh).
Font vector th hin các ký t như là tp hp các nét v (s dng các hàm GDI), do đó linh động
và co gin hơn font bitmap, tuy nhiên được v khá chm và đường nét cũng không được mm mi
cho lm.
Font TrueType là dng font được s dng ph biến nht hin nay, được lưu tr dưới dng mt
tp các đim nh, kết hp mt s thut toán biến đổi. Do đó th hin sc xo các đường nét trên
màn hình và máy in. Chúng ta s kho sát các hàm x lý cho các font ch dng này.
Nhng lý thuyết v font phn trên, bn không cn nh. Tóm li, để to font (font logic),
bn gi hàm CreateFont hay CreatFontIndirect. Hàm CreateFontIndirect nhn con
tr cu trúc LOGFONT. Xét định nghĩa ca cu trúc LOGFONT :
typedef struct tagLOGFONT // lf
{ LONG lfHeight;
LONG lfWidth;
LONG lfEscapement;
LONG lfOrientation;
LONG lfWeight;
BYTE lfItalic;
BYTE lfUnderline;
BYTE lfStrikeOut;
BYTE lfCharSet;
BYTE lfOutPrecision;
BYTE lfClipPrecision;
BYTE lfQuality;
BYTE lfPitchAndFamily;
TCHAR lfFaceName[LF_FACESIZE];
} LOGFONT;
Người dch: Benina (REA TEAM) Trang 2
Tng hp và hiu chnh: NhatPhuongLe (VNCERT TEAM)
Iczelion’s Tutorial Win32 ASM Tutorial 5 : More about Text
Hàm CreateFontIndirect linh hot hơn, đặc bit là nếu các chương trình ca bn cn
thay đổi font thường xuyên. Tuy nhiên, trong ví d ca chúng ta , chúng ta “to” font ch
bng cách dùng hàm CreateFont. Sau li gi hàm, nó s tr v mt handle ca font mà
bn mun chn để hin th trong DC. Sau đó, các hàm API có chc năng xut ch ra màn
hình (TextOut, TabbedTextOut, ExtTextOut hoc DrawText) s s dng font mà
chúng ta đã chn trong DC.
Font logic là mt đối tượng GDI có handle kiu HFONT. Mt font logic là mt mô t ca mt font ch
thc tế. Tương t như viết v logic và chi sơn logic, font logic là mt đối tượng tru tượng, và tr thành
font thc tế trong DC khi ng dng gi hàm SelectObject.
Đầu tiên, ta cn định nghĩa các trường trong cu trúc LOGFONT theo mt trong hai cách sau :
Thiết lp các trường trong cu trúc LOGFONT da trên các đặc tính ca font bn quan tâm.
Trong trường hp này, khi gi hàm SelectObject, Windows s s dng mt thut toán "ánh x
font" để chn mt font tương thích nht hin có trên thiết b.
Chn font trong hp thoi Font, hàm ChooseFont s khi gán các giá tr trong cu trúc
LOGFONT theo thuc tính font được chn.
Để s dng font này trong các thao tác xut văn bn, trước hết ng dng cn khi to font logic, ri
chuyn cho DC. Vic to font logic được thc hin bng cách gi hàm CreateFont hoc hàm
CreateFontIndirect. Tuy nhiên, hàm CreateFont ít được s dng hơn do hàm cn gi các biến trong cu
trúc LOGFONT, trong khi hàm CreateFontIndirect ch cn biến con tr LOGFONT. C hai hàm đều
tr v handle ca font logic HFONT.
Trước khi ng dng có th xut văn bn, font logic cn được ánh x tương ng vi mt font vt lý trong
thiết b xut, hoc font np vào h điu hành. Tiến trình này được thc hin khi ng dng gi hàm
SelectObject. Khi đó, ta có th dùng hàm GetTextMetrics (hoc các hàm tương đương) xác định kích
thước và đặc trưng ca font thc để tính v trí và xut văn bn ra thiết b xut.
Sau khi dùng font, ta cn loi b font dùng hàm DeleteObject. Chú ý không được xoá font trong DC đang
thc thi, hoc font h thng.
.386
.model flat,stdcall
option casemap:none
WinMain proto :DWORD,:DWORD,:DWORD,:DWORD
include windows.inc
include user32.inc
include kernel32.inc
include gdi32.inc
includelib user32.lib
includelib kernel32.lib
includelib gdi32.lib
RGB macro red,green,blue
xor eax,eax
mov ah,blue
shl eax,8
mov ah,green
mov al,red
endm
.data
ClassName db "SimpleWinClass",0
AppName db "Our First Window",0
TestString db "Win32 assembly is great and easy!",0
FontName db "script",0
Người dch: Benina (REA TEAM) Trang 3
Tng hp và hiu chnh: NhatPhuongLe (VNCERT TEAM)
Iczelion’s Tutorial Win32 ASM Tutorial 5 : More about Text
.data?
hInstance HINSTANCE ?
CommandLine LPSTR ?
.code
start:
invoke GetModuleHandle, NULL
mov hInstance,eax
invoke GetCommandLine
mov CommandLine,eax
invoke WinMain, hInstance,NULL,CommandLine, SW_SHOWDEFAULT
invoke ExitProcess,eax
WinMain proc
hInst:HINSTANCE,hPrevInst:HINSTANCE,CmdLine:LPSTR,CmdShow:DWORD
LOCAL wc:WNDCLASSEX
LOCAL msg:MSG
LOCAL hwnd:HWND
mov wc.cbSize,SIZEOF WNDCLASSEX
mov wc.style, CS_HREDRAW or CS_VREDRAW
mov wc.lpfnWndProc, OFFSET WndProc
mov wc.cbClsExtra,NULL
mov wc.cbWndExtra,NULL
push hInst
pop wc.hInstance
mov wc.hbrBackground,COLOR_WINDOW+1
mov wc.lpszMenuName,NULL
mov wc.lpszClassName,OFFSET ClassName
invoke LoadIcon,NULL,IDI_APPLICATION
mov wc.hIcon,eax
mov wc.hIconSm,eax
invoke LoadCursor,NULL,IDC_ARROW
mov wc.hCursor,eax
invoke RegisterClassEx, addr wc
invoke CreateWindowEx,NULL,ADDR ClassName,ADDR AppName,\
WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,\
CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,NULL,NULL,\
hInst,NULL
mov hwnd,eax
invoke ShowWindow, hwnd,SW_SHOWNORMAL
invoke UpdateWindow, hwnd
.WHILE TRUE
invoke GetMessage, ADDR msg,NULL,0,0
.BREAK .IF (!eax)
invoke TranslateMessage, ADDR msg
invoke DispatchMessage, ADDR msg
.ENDW
mov eax,msg.wParam
ret
WinMain endp
WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
LOCAL hdc:HDC
LOCAL ps:PAINTSTRUCT
LOCAL hfont:HFONT
.IF uMsg==WM_DESTROY
invoke PostQuitMessage,NULL
.ELSEIF uMsg==WM_PAINT
invoke BeginPaint,hWnd, ADDR ps
mov hdc,eax
invoke CreateFont,24,16,0,0,400,0,0,0,OEM_CHARSET,\
OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,\
DEFAULT_QUALITY,DEFAULT_PITCH or
FF_SCRIPT,\
ADDR FontName
invoke SelectObject, hdc, eax
Người dch: Benina (REA TEAM) Trang 4
Tng hp và hiu chnh: NhatPhuongLe (VNCERT TEAM)
Iczelion’s Tutorial Win32 ASM Tutorial 5 : More about Text
mov hfont,eax
RGB 200,200,50
invoke SetTextColor,hdc,eax
RGB 0,0,255
invoke SetBkColor,hdc,eax
invoke TextOut,hdc,0,0,ADDR TestString,SIZEOF TestString
invoke SelectObject,hdc, hfont
invoke EndPaint,hWnd, ADDR ps
.ELSE
invoke DefWindowProc,hWnd,uMsg,wParam,lParam
ret
.ENDIF
xor eax,eax
ret
WndProc endp
end start
Phân tích mã lnh
invoke CreateFont,24,16,0,0,400,0,0,0,OEM_CHARSET,\
OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,\
DEFAULT_QUALITY,DEFAULT_PITCH or FF_SCRIPT,\
ADDR FontName
Hàm CreatFont to ra mt font logic, mà các tham s đầu vào ca hàm này tương ng vi
các trường ca cu trúc LOGFONT (lfHeight – nHeight; lfWidth – nWidth) cũng như các
font hin có. Hàm này có nhiu tham s hơn bt c hàm nào khác trong Windows. Nó tr
v mt handle ca font logic, dùng cho hàm SelectObject. Sau đây, là chi tiết các tham s
ca nó:
CreateFont proto nHeight:DWORD,\
nWidth:DWORD,\
nEscapement:DWORD,\
nOrientation:DWORD,\
nWeight:DWORD,\
cItalic:DWORD,\
cUnderline:DWORD,\
cStrikeOut:DWORD,\
cCharSet:DWORD,\
cOutputPrecision:DWORD,\
cClipPrecision:DWORD,\
cQuality:DWORD,\
cPitchAndFamily:DWORD,\
lpFacename:DWORD
nHeight: cho biết chiu cao ca phông ch, tính theo đơn v logic. 0 là kích thước mc
định.
nWidth: Chiu rng trung bình các ký t trong phông ch, tính theo đơn v logic. Nếu
thông s này bng 0, thì t l chiu rng, cao ca thiết b xut s trùng khp vi t l
chiu rng, cao ca các phông ch có sn. Tuy nhiên trong ví d này, tôi set nWidth
bng 16 để cho d nhìn so vi chiu rng mc định (=0)
nEscapement: cho biết góc độ (tính theo đơn v 0.1 độ hay 1/10 độ) ca mi hàng văn
bn được kết xut, gia escapement vector và trc x ca màn hình. Escapement vector là
đường k t ký t đầu tiên và ký t cui cùng trên cùng mt dùng. Còn góc độ s được
tính theo ngược chiu kim đồng h ca trc x. Thông thường, set là 0. Set là 900 tc là tt
Người dch: Benina (REA TEAM) Trang 5
Tng hp và hiu chnh: NhatPhuongLe (VNCERT TEAM)