程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 更多編程語言 >> 匯編語言 >> 匯編教程之“繪制”文本串

匯編教程之“繪制”文本串

編輯:匯編語言

我們將做更多的實踐去了解有關文本的諸多屬性如字體和顏色等。

理論:

Windows 的顏色系統是用RGB值來表示的,R 代表紅色,G 代表綠色,B 代表蘭色。如果您想指定一種顏色就必須給該顏色賦相關的 RGB 值,RGB 的取值范圍都是從 0 到 255,譬如您想要得到純紅色,就必須對RGB賦值(255,0,0),純白色是 (255,255,255)。從我們下面的例子中您可以看出來要想運用好這套基於數字的顏色系統並不容易,這要求您必須對混色和顏色匹配有良好的感覺。

您可以用函數 SetTextColor 和 SetBkColor 來“繪制”背景色和字符顏色,但是必須傳遞一個“設備環境”的句柄和 RGB 值作為參數。RGB 的結構體的定義如下:

RGB_value struct
unused db 0
blue db ?
green db ?
red db ?
RGB_value ends

其中第一字節為 0 而且始終為 0,其它三個字節分別表示蘭色、綠色和紅色,剛好和 RGB 的次序相反。這個結構體用起來挺別扭,所以我們重新定義一個宏用它來代替。該宏接收紅綠藍三個參數,並在 eax 寄存器中返回 32 位的 RGB 值,宏的定義如下:

RGB macro red,green,blue
xor eax,eax
mov ah,blue
shl eax,8
mov ah,green
mov al,red
endm

您可以把該宏放到頭文件中以方便使用。

您可以調用 CreateFont 和 CreateFontIndirect 來創建自己的字體,這兩個函數的差別是前者要求 您傳遞一系列的參數,而後著只要傳遞一個指向 LOGFONT 結構的指針。這樣就使得後者使用起來更方便,尤其當您需要頻繁創建字體時。在我們的例子中由於只要創建一種字體,故用 CreateFont 就足夠了。在調用該函數後會返回所創建的字體的句柄,然後把該句柄選進“設備環境”使其成為當前字體,隨後所有的“繪制”文本串的函數在被調用時都要把該句柄作為一個參數傳遞

例子:

.386
.model flat,stdcall
option casemap:none
WinMain proto :DWORD,:DWORD,:DWORD,:DWORD
include \masm32\include\windows.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
include \masm32\include\gdi32.inc
includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\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
.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
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

分析:

CreateFont 函數產生一種邏輯字體,它盡可能地接近參數中指定的各相關值。這個函數大概是所有 Windows API函數中所帶參數最多的一個。它返回一個指向邏輯字體的句柄供調用 SelectObject 函數使用。下面我們詳細講解該函數的參數:

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: 希望使用的字體的高度,0為缺省。

nWidth: 希望使用的字體的寬度,一般情況下最好用0, 這樣 Windows 將會自動為您選擇一個和高度匹配的值。因為在我們的例子中那樣做的話會使得字符因太小而無法顯示,所以 我 們設定它為16。

nEscapement: 每一個字符相對前一個字符的旋轉角度,一般設成0。900代表轉90度,1800轉190度,2700轉270度。

nOrientation: 字體的方向。

nWeight: 字體筆畫的粗細。

Windows 為我們預定義了如下值:

FW_DONTCARE 等於 0

FW_THIN 等於 100

FW_EXTRALIGHT 等於 200

FW_ULTRALIGHT 等於 200

FW_LIGHT 等於 300

FW_NORMAL 等於 400

FW_REGULAR 等於 400

FW_MEDIUM 等於 500

FW_SEMIBOLD 等於 600

FW_DEMIBOLD 等於 600

FW_BOLD 等於 700

FW_EXTRABOLD 等於 800

FW_ULTRABOLD 等於 800

FW_HEAVY 等於 900

FW_BLACK 等於 900

cItalic: 0為正常,其它值為斜體。

cUnderline: 0為正常,其它值為有下劃線。

cStrikeOut: 0為正常,其它值為刪除線。

cCharSet: 字體的字符集。一般選擇OEM_CHARSET,它使得 Windows 會選用和操作系統相關的字符集。

cOutputPrecision: 指定我們選擇的字體接近真實字體的精度。 一般選用OUT_DEFAULT_PRECIS,它決定了缺省的映射方式。

cClipPrecision: 指定我們選擇的字體在超出裁剪區域時的裁剪精度。 一般選用CLIP_DEFAULT_PRECIS,它決定了裁剪精度。

cQuality: 指定輸出字體的質量。它指出GDI應如何盡可能的接近真實 字體,一共有三種方式:DEFAULT_QUALITY, PROOF_QUALITY 和DRAFT_QUALITY。

cPitchAndFamily:字型和字體家族。

lpFacename: 指定字體的名稱。

上面的描述不一定好理解,您如果要的到更多的信息,應參考 WIN32 API 指南。

invoke SelectObject, hdc, eax
mov hfont,eax

在我們得到了指向邏輯字體的句柄後必須調用 SelectObject 函數把它選擇進“設備環境”,我們還可以調用該函數把諸如此類的像顏色、筆、畫刷 等GDI對象選進“設備環境”。該函數會返回一個舊的“設備環境”的句柄。您必須保存該句柄,以便在完成“繪制”工作後再把它選回。在調用 SelectObject 函數後一切的繪制函數都是針對該“設備環境”的。

RGB 200,200,50
invoke SetTextColor,hdc,eax
RGB 0,0,255
invoke SetBkColor,hdc,eax

我們用宏 RGB 產生顏色,然後分別調用 SetTextColor 和 SetBkColor。

invoke TextOut,hdc,0,0,ADDR TestString,SIZEOF TestString

我們調用 TextOut 在客戶區用我們前面選定的字體和顏色“繪制”文本串。

invoke SelectObject,hdc, hfont

在我們“繪制”完成後,必須恢復“設備環境”。我們必須每一次都這麼做。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved