全部博文(290)
分类:
2007-12-09 09:34:18
Tutorial 5: More about Text
更多的文本属性
We will experiment more with text attributes, ie. font and color.
Download the example file here.
我们将实验更多的文本属性,例如:字体和颜色。
Theory:
理论:
Windows color system is based on RGB values, R=red, G=Green, B=Blue. If you want to specify a color in Windows, you must state your desired color in terms of these three major colors. Each color value has a range from 0 to 255 (a byte value). For example, if you want pure red color, you should use 255,0,0. Or if you want pure white color, you must use 255,255,255. You can see from the examples that getting the color you need is very difficult with this system since you have to have a good grasp of how to mix and match colors.
Widnows的颜色系统是基于RGB值的,R= 红色 , G=绿色,B=蓝色.如果你想在文本中指定一颜色值,你必须根据上面上个主要的颜色值来声明它.每一个颜色可在0-255(一个字节的值)之间取值.例如:如果你想要纯红色,你应该使用255.0.0或者你想纯白色,你必须用255.255.255.从我们的例子中你能看到,在系统设置一个你需要的颜色是非常困难的,因为你必须深刻的了解如何混合和匹配这些颜色值.
For text color and background, you use SetTextColor and SetBkColor, both of them require a handle to device context and a 32-bit RGB value. The 32-bit RGB value's structure is defined as:
至于文本的颜色和背景色,你能用SetTextColor和SetBkColor函数,它们需要两个参数,一个是设备环境的句柄,一个是32位的RGB值.这个32位的RGB值的结构定义如下:
RGB_value struct
unused db 0
blue db ?
green db ?
red db ?
RGB_value ends
Note that the first byte is not used and should be zero. The order of the remaining three bytes is reversed,ie. blue, green, red. However, we will not use this structure since it's cumbersome to initialize and use. We will create a macro instead. The macro will receive three parameters: red, green and blue values. It'll produce the desired 32-bit RGB value and store it in eax. The macro is as follows:
注意第一个字节没有被使用并且应该为0。 剩下的三个字节是颠倒的。例如:蓝,绿,红。我们将不用这个结构,因为这个结构的初始化和使用是麻烦的。我们将创建一个宏来代替。 这个宏将接收这三个参数:红,绿和蓝的颜色值。它将创建你想要的32-位RGB颜色值并将这个值储存在eax中,这个宏如下:
RGB macro red,green,blue
xor eax,eax
mov ah,blue
shl eax,8 //逻辑左移,将蓝色保存在eax的第二个字节.
mov ah,green
mov al,red
endm
You can put this macro in the include file for future use.
You can "create" a font by calling CreateFont or CreateFontIndirect. The difference between the two functions is that CreateFontIndirect receives only one parameter: a pointer to a logical font structure, LOGFONT. CreateFontIndirect is the more flexible of the two especially if your programs need to change fonts frequently. However, in our example, we will "create" only one font for demonstration, we can get away with CreateFont. After the call to CreateFont, it will return a handle to a font which you must select into the device context. After that, every text API function will use the font we have selected into the device context.
你能将这个宏放在include文件中以便将来使用.你通过调用CreateFont或者是CreateFontIndirect 函数来创建一个字体.这两个API函数的不同之处在于CreateFontIndirect 函数仅接收一个参数: 一个指向逻辑字体的结构LOGFONT.CreateFontIndirect函数是这两个函数中最灵活的一个特别当你参数需要频繁的改变字体时.然而在我们的例子中,我们仅为这个实例创建一个字体.我们用CreateFont就可以了.它将返回一个字体句柄,你必须把这个句柄选进设备环境中.在这样做了之后,每一个API文本函数都将使用我们在设备环境中选进的这个字体.
Content:
内容:
.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
Analysis:
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
CreateFont creates a logical font that is the closest match to the given parameters and the font data available. This function has more parameters than any other function in Windows. It returns a handle to logical font to be used by SelectObject function. We will examine its parameters in detail.
CreateFont创建一种逻辑字体,这种字体与给定的参数的值是接近相等的并且这个字体的数据是可用的.比起其它在windows中的其它函数,这个参数有更多的值.它返回一个逻辑字体句柄被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 The desired height of the characters . 0 means use default size.
你想设置的字符的高度( 字符的高度),0意味着使用默认值.
nWidth The desired width of the characters. Normally this value should be 0 which allows Windows to match the width to the height. However, in our example, the default width makes the characters hard to read, so I use the width of 16 instead.
你想设置的字符的高度.通常这个值应该为0,0允许windows为字符的高度匹配一个合适的宽.然而在我们的例子中,这个默认的宽值将使字符阅读困难,所以我们用16这个值来代替默认值(也叫缺省值)
nEscapement Specifies the orientation of the next character output relative to the previous one in tenths of a degree. Normally, set to 0. Set to 900 to have all the characters go upward from the first character, 1800 to write backwards, or 2700 to write each character from the top down.
相对于上一个输出字符指定下一个输出字符向东旋转十分之一的度数.通常设为0, 900代表转90度,1800转190度,2700转270度。
nOrientation Specifies how much the character should be rotated when output in tenths of a degree. Set to 900 to have all the characters lying on their backs, 1800 for upside-down writing, etc.
指定当这个字符输出时被旋转多少度( 设定的值的10分之一) ,设置900将使所有的字符置后.1800将使它们倒置.等等.
nWeight Sets the line thickness of each character. Windows defines the following sizes:
设置每一个字符的笔画宽度, widows定义了下面几种尺寸:
FW_DONTCARE equ 0
FW_THIN equ 100
FW_EXTRALIGHT equ 200
FW_ULTRALIGHT equ 200
FW_LIGHT equ 300
FW_NORMAL equ 400
FW_REGULAR equ 400
FW_MEDIUM equ 500
FW_SEMIBOLD equ 600
FW_DEMIBOLD equ 600
FW_BOLD equ 700
FW_EXTRABOLD equ 800
FW_ULTRABOLD equ 800
FW_HEAVY equ 900
FW_BLACK equ 900
cItalic 0 for normal, any other value for italic characters.
通常为0,任何其它的值将使字体倾斜.
cUnderline 0 for normal, any other value for underlined characters.
通常为0,任何其它的值将给这个字体加上下划线.
cStrikeOut 0 for normal, any other value for characters with a line through the center.
通常为0,任何其它的值将使字符中间加上一横线(删除线)
cCharSet The character set of the font. Normally should be OEM_CHARSET which allows Windows to select font which is operating system-dependent.
设置这个字体的字符集。通常应该是OEM_CHARSET,这个值将允许windows选择与操作系统相关的字符集。
cOutputPrecision Specifies how much the selected font must be closely matched to the characteristics we want. Normally should be OUT_DEFAULT_PRECIS which defines default font mapping behavior.
指定我们选择的字体接近真实字体的精度。 一般选用OUT_DEFAULT_PRECIS,它定义为默认的映射状态
cClipPrecision Specifies the clipping precision. The clipping precision defines how to clip characters that are partially outside the clipping region. You should be able to get by with CLIP_DEFAULT_PRECIS which defines the default clipping behavior.
指定裁剪精度.这个裁剪精度定义了如何对在裁剪区域外面的字符进行修剪.你应该通过CLIP_DEFAULT_PRECTS来获取系统默认的裁剪方式.
cQuality Specifies the output quality. The output quality defines how carefully GDI must attempt to match the logical-font attributes to those of an actual physical font. There are three choices: DEFAULT_QUALITY, PROOF_QUALITY and DRAFT_QUALITY.
指定输出的质量.这个输出质量规定了图形设备接口如何谨慎的让逻辑字体和那些实际的物理字体尽可能的相一致.( 无论是在数量还是质量上)这里有三个选项:DEFAULT_QUALITY, PROOF_QUALITY and DRAFT_QUALITY.
cPitchAndFamily Specifies pitch and family of the font. You must combine the pitch value and the family value with "or" operator.
指定字体的间距和字体的家族.你必须用or操作将间距值和家族值联合在一起.
lpFacename A pointer to a null-terminated string that specifies the typeface of the font.
一个指向以NULL结束的字符串,这个字符串指定了字体的字面(名字).
The description above is by no means comprehensive. You should refer to your Win32 API reference for more details.
这上面的描述绝对不是容易理解的.你还应该参考你的WIN32API 手册来得到更多的详细资料.
invoke SelectObject, hdc, eax
mov hfont,eax
After we get the handle to the logical font, we must use it to select the font into the device context by calling SelectObject. SelectObject puts the new GDI objects such as pens, brushs, and fonts into the device context to be used by GDI functions. It returns the handle to the replaced object which we should save for future SelectObject call. After SelectObject call, any text output function will use the font we just selected into the device context.
在我们得到这个逻辑字体的句柄之后,我们必须通过调用SelectObject函数来将这个字体选进设备环境中才能使用它。SelectObject的作用是放置一个新的GDI对象例如 画笔,画刷,和字体等在设备环境中以便被GDI函数使用。它返回它替换的那个对象的句柄,我们应该保存这个句柄以便在将来SelectObjict调用。在selectObject函数调用之后,任何文本输出函数都将使用我们刚刚选进设备环境中的这个字体。
RGB 200,200,50
invoke SetTextColor,hdc,eax
RGB 0,0,255
invoke SetBkColor,hdc,eax
Use RGB macro to create a 32-bit RGB value to be used by SetColorText and SetBkColor.
用RGB宏创建的32位RGB值被用于SetColorText和SetBkColor函数中。
invoke TextOut,hdc,0,0,ADDR TestString,SIZEOF TestString
Call TextOut function to draw the text on the client area. The text will be in the font and color we specified previously.
调用TextOut函数在客户区中画一个文本。 这个文本将使用我先前指定的字体和颜色。
invoke SelectObject,hdc, hfont
When we are through with the font, we should restore the old font back into the device context. You should always restore the object that you replaced in the device context.
当我们不使用这个字体的时候,我们应该在设备环境中恢复它以前的字体。你只要在设备环境中替换了某一对象,你都应该恢复它。
This article come from Iczelion's asm page
风向改变 翻译于 12.9日