?? lion-tut-c05.htm
字號:
<html>
<head>
<link rel="stylesheet" href="../../asm.css">
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<title>Iczelion 的 Win32asm 教程</title>
</head>
<body bgcolor="#FFFFFF" background="../../images/back01.jpg">
<p align="center"><font size="5"><u><strong><font color="#0000FF">第五課 </font><font size="5"><u><strong><font color="#0000FF">學習更多關于“繪制”文本串的知識</font></strong></u></font></strong></u></font></p>
<hr size="1">
<p>我們將做更多的實踐去了解有關文本的諸多屬性如字體和顏色等。 </p>
<p><font color="#FF0000">理論:</font></p>
<p>Windows 的顏色系統是用RGB值來表示的,R 代表紅色,G 代表綠色,B 代表蘭色。如果您想指定一種顏色就必須給該顏色賦相關的 RGB 值,RGB
的取值范圍都是從 0 到 255,譬如您想要得到純紅色,就必須對RGB賦值(255,0,0),純白色是 (255,255,255)。從我們下面的例子中您可以看出來要想運用好這套基于數字的顏色系統并不容易,這要求您必須對混色和顏色匹配有良好的感覺。</p>
<p> 您可以用函數 SetTextColor 和 SetBkColor 來“繪制”背景色和字符顏色,但是必須傳遞一個“設備環境”的句柄和 RGB 值作為參數。RGB
的結構體的定義如下: </p>
<p>RGB_value struct<br>
unused db 0<br>
blue db ?<br>
green db ?<br>
red db ?<br>
RGB_value ends</p>
<p> 其中第一字節為 0 而且始終為 0,其它三個字節分別表示蘭色、綠色和紅色,剛好和 RGB 的次序相反。這個結構體用起來挺別扭,所以我們重新定義一個宏用它來代替。該宏接收紅綠藍三個參數,并在
eax 寄存器中返回 32 位的 RGB 值,宏的定義如下:</p>
<p> RGB macro red,green,blue<br>
xor eax,eax<br>
mov ah,blue<br>
shl eax,8<br>
mov ah,green<br>
mov al,red<br>
endm </p>
<p>您可以把該宏放到頭文件中以方便使用。 </p>
<p>您可以調用 CreateFont 和 CreateFontIndirect 來創建自己的字體,這兩個函數的差別是前者要求 您傳遞一系列的參數,而后著只要傳遞一個指向
LOGFONT 結構的指針。這樣就使得后者使用起來更方便,尤其當您需要頻繁創建字體時。在我們的例子中由于只要創建一種字體,故用 CreateFont 就足夠了。在調用該函數后會返回所創建的字體的句柄,然后把該句柄選進“設備環境”使其成為當前字體,隨后所有的“繪制”文本串的函數在被調用時都要把該句柄作為一個參數傳遞
</p>
<p><font color="#FF0000">例子:</font></p>
<p> <font color="#006666">.386 <br>
.model flat,stdcall <br>
option casemap:none </font></p>
<p><font color="#006666">WinMain proto :DWORD,:DWORD,:DWORD,:DWORD </font>
<p><font color="#006666">include \masm32\include\windows.inc <br>
include \masm32\include\user32.inc <br>
include \masm32\include\kernel32.inc <br>
include \masm32\include\gdi32.inc <br>
includelib \masm32\lib\user32.lib <br>
includelib \masm32\lib\kernel32.lib <br>
includelib \masm32\lib\gdi32.lib </font>
<p><font color="#006666">RGB macro red,green,blue <br>
xor eax,eax <br>
mov ah,blue <br>
shl eax,8 <br>
mov ah,green <br>
mov al,red <br>
endm </font>
<p><font color="#006666">.data <br>
ClassName db "SimpleWinClass",0 <br>
AppName db "Our First Window",0 <br>
TestString db "Win32 assembly is great and easy!",0 <br>
FontName db "script",0 </font>
<p><font color="#006666">.data? <br>
hInstance HINSTANCE ? <br>
CommandLine LPSTR ? </font>
<p><font color="#006666">.code <br>
start: <br>
invoke GetModuleHandle, NULL <br>
mov hInstance,eax <br>
invoke GetCommandLine<br>
mov CommandLine,eax<br>
invoke WinMain, hInstance,NULL,CommandLine, SW_SHOWDEFAULT
<br>
invoke ExitProcess,eax </font>
<p><font color="#006666">WinMain proc hInst:HINSTANCE,hPrevInst:HINSTANCE,CmdLine:LPSTR,CmdShow:DWORD
<br>
LOCAL wc:WNDCLASSEX <br>
LOCAL msg:MSG <br>
LOCAL hwnd:HWND <br>
mov wc.cbSize,SIZEOF WNDCLASSEX <br>
mov wc.style, CS_HREDRAW or CS_VREDRAW <br>
mov wc.lpfnWndProc, OFFSET WndProc <br>
mov wc.cbClsExtra,NULL <br>
mov wc.cbWndExtra,NULL <br>
push hInst <br>
pop wc.hInstance <br>
mov wc.hbrBackground,COLOR_WINDOW+1 <br>
mov wc.lpszMenuName,NULL <br>
mov wc.lpszClassName,OFFSET ClassName <br>
invoke LoadIcon,NULL,IDI_APPLICATION <br>
mov wc.hIcon,eax <br>
mov wc.hIconSm,eax <br>
invoke LoadCursor,NULL,IDC_ARROW <br>
mov wc.hCursor,eax <br>
invoke RegisterClassEx, addr wc <br>
invoke CreateWindowEx,NULL,ADDR ClassName,ADDR AppName,\
<br>
WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,\
<br>
CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,NULL,NULL,\
<br>
hInst,NULL <br>
mov hwnd,eax <br>
invoke ShowWindow, hwnd,SW_SHOWNORMAL <br>
invoke UpdateWindow, hwnd <br>
.WHILE TRUE <br>
invoke GetMessage, ADDR msg,NULL,0,0 <br>
.BREAK .IF (!eax) <br>
invoke TranslateMessage, ADDR msg <br>
invoke DispatchMessage, ADDR msg <br>
.ENDW <br>
mov eax,msg.wParam <br>
ret <br>
WinMain endp </font>
<p><font color="#006666">WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
<br>
LOCAL hdc:HDC <br>
LOCAL ps:PAINTSTRUCT <br>
LOCAL hfont:HFONT </font>
<p><font color="#006666"> .IF uMsg==WM_DESTROY <br>
invoke PostQuitMessage,NULL <br>
.ELSEIF uMsg==WM_PAINT <br>
invoke BeginPaint,hWnd, ADDR ps <br>
mov hdc,eax <br>
invoke CreateFont,24,16,0,0,400,0,0,0,OEM_CHARSET,\
<br>
OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,\ <br>
DEFAULT_QUALITY,DEFAULT_PITCH or FF_SCRIPT,\ <br>
ADDR FontName <br>
invoke SelectObject, hdc, eax <br>
mov hfont,eax <br>
RGB 200,200,50
<br>
invoke SetTextColor,hdc,eax <br>
RGB 0,0,255 <br>
invoke SetBkColor,hdc,eax <br>
invoke TextOut,hdc,0,0,ADDR TestString,SIZEOF
TestString <br>
invoke SelectObject,hdc, hfont <br>
invoke EndPaint,hWnd, ADDR ps <br>
.ELSE <br>
invoke DefWindowProc,hWnd,uMsg,wParam,lParam
<br>
ret <br>
.ENDIF <br>
xor eax,eax <br>
ret <br>
WndProc endp </font>
<p><font color="#006666">end start </font>
<p><font color="#FF0000">分析:</font></p>
<p> CreateFont 函數產生一種邏輯字體,它盡可能地接近參數中指定的各相關值。這個函數大概是所有 Windows API函數中所帶參數最多的一個。它返回一個指向邏輯字體的句柄供調用
SelectObject 函數使用。下面我們詳細講解該函數的參數:</p>
<p> <font color="#006666">CreateFont proto \<br>
nHeight:DWORD,\<br>
nWidth:DWORD,\<br>
nEscapement:DWORD,\<br>
nOrientation:DWORD,\<br>
nWeight:DWORD,\ <br>
cItalic:DWORD,\ <br>
cUnderline:DWORD,\<br>
cStrikeOut:DWORD,\<br>
cCharSet:DWORD,\<br>
cOutputPrecision:DWORD,\<br>
cClipPrecision:DWORD,\<br>
cQuality:DWORD,\<br>
cPitchAndFamily:DWORD,\<br>
lpFacename:DWORD</font></p>
<p> nHeight: 希望使用的字體的高度,0為缺省。<br>
nWidth: 希望使用的字體的寬度,一般情況下最好用0, 這樣 Windows 將會自動為您選擇一個和高度匹配的值。因為在我們的例子中那樣做的話會使得字符因太小而無法顯示,所以
我 們設定它為16。<br>
nEscapement: 每一個字符相對前一個字符的旋轉角度,一般設成0。900代表轉90度,1800轉190度,2700轉270度。<br>
nOrientation: 字體的方向。<br>
nWeight: 字體筆畫的粗細。</p>
<p> Windows 為我們預定義了如下值: </p>
<p>FW_DONTCARE 等于 0<br>
FW_THIN 等于 100<br>
FW_EXTRALIGHT 等于 200<br>
FW_ULTRALIGHT 等于 200<br>
FW_LIGHT 等于 300<br>
FW_NORMAL 等于 400<br>
FW_REGULAR 等于 400<br>
FW_MEDIUM 等于 500<br>
FW_SEMIBOLD 等于 600<br>
FW_DEMIBOLD 等于 600<br>
FW_BOLD 等于 700<br>
FW_EXTRABOLD 等于 800<br>
FW_ULTRABOLD 等于 800<br>
FW_HEAVY 等于 900<br>
FW_BLACK 等于 900</p>
<p> cItalic: 0為正常,其它值為斜體。 <br>
cUnderline: 0為正常,其它值為有下劃線。<br>
cStrikeOut: 0為正常,其它值為刪除線。<br>
cCharSet: 字體的字符集。一般選擇OEM_CHARSET,它使得 Windows 會選用和操作系統相關的字符集。<br>
cOutputPrecision: 指定我們選擇的字體接近真實字體的精度。 一般選用OUT_DEFAULT_PRECIS,它決定了缺省的映射方式。<br>
cClipPrecision: 指定我們選擇的字體在超出裁剪區域時的裁剪精度。 一般選用CLIP_DEFAULT_PRECIS,它決定了裁剪精度。<br>
cQuality: 指定輸出字體的質量。它指出GDI應如何盡可能的接近真實 字體,一共有三種方式:DEFAULT_QUALITY, PROOF_QUALITY
和DRAFT_QUALITY。<br>
cPitchAndFamily:字型和字體家族。<br>
lpFacename: 指定字體的名稱。 </p>
<p>上面的描述不一定好理解,您如果要的到更多的信息,應參考 WIN32 API 指南。 </p>
<p><font color="#006666">invoke SelectObject, hdc, eax<br>
mov hfont,eax</font></p>
<p> 在我們得到了指向邏輯字體的句柄后必須調用 SelectObject 函數把它選擇進“設備環境”,我們還可以調用該函數把諸如此類的像顏色、筆、畫刷
等GDI對象選進“設備環境”。該函數會返回一個舊的“設備環境”的句柄。您必須保存該句柄,以便在完成“繪制”工作后再把它選回。在調用 SelectObject
函數后一切的繪制函數都是針對該“設備環境”的。 </p>
<p><font color="#006666">RGB 200,200,50<br>
invoke SetTextColor,hdc,eax<br>
RGB 0,0,255 <br>
invoke SetBkColor,hdc,eax</font></p>
<p> 我們用宏 RGB 產生顏色,然后分別調用 SetTextColor 和 SetBkColor。</p>
<p> <font color="#006666">invoke TextOut,hdc,0,0,ADDR TestString,SIZEOF TestString</font></p>
<p> 我們調用 TextOut 在客戶區用我們前面選定的字體和顏色“繪制”文本串。 </p>
<p><font color="#006666">invoke SelectObject,hdc, hfont</font></p>
<p> 在我們“繪制”完成后,必須恢復“設備環境”。我們必須每一次都這么做。 </p>
<hr size="1">
<div align="center">
<script language="JavaScript1.1" src=http://ad.t2t2.com/textclick.asp?user=bigluo&style=4&bkcolor=no></script>
<br>
</div>
<!-- 10:1 文本廣告交換 -->
<div align="center">
<script language="JavaScript1.1" src=http://coolsite21.com:90/c21.dll?Type=PT&id=1047&col=6&ReferID=1047&v=0></script>
<!-- 10:1 文本廣告交換 --> </div>
<hr size="1">
<br>
<div align="center"> 翻譯:Lxx,校對:LuoYunBin's Win32 ASM Page,<a href="http://asm.yeah.net">http://asm.yeah.net</a></div>
</body>
</html>
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -