Win32汇编学习(5):绘制文本2
这次我们将学习有关文本的诸多属性如字体和颜色等。
理论:
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 windows.inc
include user32.inc
includelib user32.lib
include kernel32.inc
includelib kernel32.lib
include gdi32.inc
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 Third Window",0
TestString db "Win32 汇编非常有意思",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
在客户区用我们前面选定的字体和颜色“绘制”文本串。 TextOut,hdc,x,y,lpString,nCount
invoke SelectObject,hdc, hfont
在我们“绘制”完成后,必须恢复“设备环境”。
测试图
Win32汇编学习(5):绘制文本2的更多相关文章
- Win32汇编学习(4):绘制文本
这次,我们将学习如何在窗口的客户区"绘制"字符串.我们还将学习关于"设备环境"的概念. 理论: "绘制"字符串 Windows 中的文本是一 ...
- Win32汇编学习(1):基本概念
背景知识 Windows 把每一个 Win32 应用程序放到分开的虚拟地址空间中去运行,也就是说每一个应用程序都拥有其相互独立的 4GB 地址空间,当然这倒不是说它们都拥有 4GB 的物理地址空间,而 ...
- Win32汇编学习(10):对话框(1)
现在我们开始学习一些有关GUI编程的有趣的部分:以对话框为主要界面的应用程序. 理论: 如果您仔细关注过前一个程序就会发现:您无法按TAB键从一个子窗口控件跳到另一个子窗口控件,要想转移的话只有 用鼠 ...
- Win32汇编学习(3):简单的窗口
这次我们将写一个 Windows 程序,它会在桌面显示一个标准的窗口,以此根据代码来学习如何创建一个简单的窗口. 理论: Windows 程序中,在写图形用户界面时需要调用大量的标准 Windows ...
- win32 汇编学习(2):消息框
这一次,我们将用汇编语言写一个 Windows 程序,程序运行时将弹出一个消息框并显示"你好,我的第一个Win32汇编程序". 理论知识 Windows 为编写应用程序提供了大量的 ...
- Win32汇编学习(11):对话框(2)
我们将进一步学习对话框,探讨如何把对话框当成输入设备.如果您看了前一篇文章,那就会发现这次的例子只有少量的改动,就是把我们的对话框窗口附属到主窗口上.另外,我们还要学习通用对话框的用法. 理论: 把对 ...
- Win32汇编学习(7):鼠标输入消息
这次我们将学习如何在我们的窗口过程函数中处理鼠标按键消息.例子演示了如何等待鼠标左键按下消息,我们将在按下的位置显示一个字符串. 理论: 和处理键盘输入一样,WINDOWS将捕捉鼠标动作并把它们发送到 ...
- Win32汇编学习(6):键盘输入消息
这次,我们将要学习WINDOWS程序是如何处理键盘消息的. 理论: 因为大多数的PC只有一个键盘,所以所有运行中的WINDOWS程序必须共用它.WINDOWS 将负责把击键消息送到具有输入焦点的那个应 ...
- Win32汇编学习(9):窗口控件
这次我们将探讨控件,这些控件是我们程序主要的输入输出设备. 理论: WINDOWS 提供了几个预定义的窗口类以方便我们的使用.大多数时间内,我们把它们用在对话框中,所以我们一般就它们叫做子窗口控件.子 ...
随机推荐
- 查询数据库中含clob,blob的表
查询含clob,blob的表select distinct ('TABLE "' || a.OWNER || '"."' || a.TABLE_NAME || '&quo ...
- vue2中使用 better-scroll
使用时有三个要点: 一:html部分 <div class="example" ref="divScroll"> <div> <p ...
- mybatis10--自连接多对一查询
查询老师对应的所有导师的信息 在09的基础上修改dao和mapper文件 public interface TeacherDao { /** * 根据老师的编号查询所有的导师信息 */ Teacher ...
- Windows 平台下局域网劫持测试工具 – EvilFoca
简介 安全测试工具可能含有攻击性,请谨慎适用于安全教学及学习用途,禁止非法利用! EvilFoca是Windows环境下基于.NET FrameWork的一款轻量级的劫持测试工具.与BackTrack ...
- CAutolock
顾名思义CAutolock就是自动锁的意思,它可以把它之下的代码区锁住一直到其自身被释放掉 后这块代码区中的公共资源才会被其他线程使用.当然这个代码区能尽量少就尽量少,毕竟不能让其他线 程 ...
- java学习(三)--- 修饰符
访问修饰符: default.public.private.protected 非访问修饰符 static: 静态方法,静态变量 final: final变量: final变量能够显示的初始化并且只能 ...
- freertos 建立任务超过几个后系统不能能运行
/* *** NOTE *********************************************************** If you find your application ...
- Codeforces 1136C - Nastya Is Transposing Matrices
题目链接:https://codeforces.com/problemset/problem/1136/C 题意: 给出 $n \times m$ 的矩阵 $A,B$,你可以对其中任意某个 $k \t ...
- InnoDB中锁的算法(3)
Ⅰ.隐式锁vs显示锁 session1: (root@localhost) [test]> show variables like 'tx_isolation'; +-------------- ...
- python摸爬滚打之day18----instance, type, issubclass和反射
1.issubclass(a,b) ----> 判断a是否是b的子类. isinstance(a,b) ----> 判断a这个对象是否是b类型的(可以向上判断, 即考虑继承关系往父类 ...