当前位置:中国易下载软件教材中心文章中心编程语言汇编语言 → 汇编语言教学(4)

汇编语言教学(4)

减小字体 增大字体 作者:佚名  来源:不详  发布时间:2007-8-21 1:04:21
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
喜欢这些内容嘛,请告诉你身边的朋友,易下载中心-QQ资源-itnetcn.com一起享受这份乐趣,本站内容来源互联网
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

第四课 绘制文本SAE海岸线网络安全资讯站
本课中,我们将学习如何在窗口的客户区“绘制”字符串。我们还将学习关于“设备环境”的概念。SAE海岸线网络安全资讯站
SAE海岸线网络安全资讯站
理论:SAE海岸线网络安全资讯站
SAE海岸线网络安全资讯站
Windows 中的文本是一个GUI(图形用户界面)对象。每一个字符实际上是由许多的像素点组成,这些点在有笔画的地方显示出来,这样就会出现字符。这也是为什么我说“绘制”字符,而不是写字符。通常您都是在您应用程序的客户区“绘制”字符串(尽管您也可以在客户区外“绘制”)。Windows 下的“绘制”字符串方法和 Dos 下的截然不同,在 Dos 下,您可以把屏幕想象成 85 x 25 的一个平面,而 Windows 下由于屏幕上同时有几个应用程序的画面,所以您必须严格遵从规范。Windows 通过把每一个应用程序限制在他的客户区来做到这一点。当然客户区的大小是可变的,您随时可以调整。SAE海岸线网络安全资讯站
SAE海岸线网络安全资讯站
在您在客户区“绘制”字符串前,您必须从 Windows 那里得到您客户区的大小,确实您无法像在 DOS 下那样随心所欲地在屏幕上任何地方“绘制”,绘制前您必须得到 Windows 的允许,然后 Windows 会告诉您客户区的大小,字体,颜色和其它 GUI 对象的属性。您可以用这些来在客户区“绘制”。SAE海岸线网络安全资讯站
SAE海岸线网络安全资讯站
什么是“设备环境”(DC)呢? 它其实是由 Windows 内部维护的一个数据结构。一个“设备环境”和一个特定的设备相连。像打印机和显示器。对于显示器来说,“设备环境”和一个个特定的窗口相连。SAE海岸线网络安全资讯站
SAE海岸线网络安全资讯站
“设备环境”中的有些属性和绘图有关,像:颜色,字体等。您可以随时改动那些缺省值,之所以保存缺省值是为了方便。您可以把“设备环境”想象成是Windows 为您准备的一个绘图环境,而您可以随时根据需要改变某些缺省属性。SAE海岸线网络安全资讯站
SAE海岸线网络安全资讯站
当应用程序需要绘制时,您必须得到一个“设备环境”的句柄。通常有几种方法。SAE海岸线网络安全资讯站
SAE海岸线网络安全资讯站
在 WM_PAINT 消息中使用 call BeginPaint SAE海岸线网络安全资讯站
在其他消息中使用 call GetDC SAE海岸线网络安全资讯站
call CreateDC 建立你自己的 DC SAE海岸线网络安全资讯站
您必须牢记的是,在处理单个消息后你必须释放“设备环境”句柄。不要在一个消息处理中获得 “设备环境”句柄,而在另一个消息处理中在释放它。SAE海岸线网络安全资讯站
SAE海岸线网络安全资讯站
我们在Windows 发送 WM_PAINT 消息时处理绘制客户区,Windows 不会保存客户区的内容,它用的是方法是“重绘”机制(譬如当客户区刚被另一个应用程序的客户区覆盖),Windows 会把 WM_PAINT 消息放入该应用程序的消息队列。重绘窗口的客户区是各个窗口自己的责任,您要做的是在窗口过程处理 WM_PAINT 的部分知道绘制什么和何如绘制。 SAE海岸线网络安全资讯站
SAE海岸线网络安全资讯站
您必须了解的另一个概念是“无效区域”。Windows 把一个最小的需要重绘的正方形区域叫做“无效区域”。当 Windows 发现了一个”无效区域“后,它就会向该应用程序发送一个 WM_PAINT 消息,在 WM_PAINT 的处理过程中,窗口首先得到一个有关绘图的结构体,里面包括无效区的坐标位置等。您可以通过调用BeginPaint 让“无效区”有效,如果您不处理 WM_PAINT 消息,至少要调用缺省的窗口处理函数 DefWindowProc ,或者调用 ValidateRect 让“无效区”有效。否则您的应用程序将会收到无穷无尽的 WM_PAINT 消息。SAE海岸线网络安全资讯站
SAE海岸线网络安全资讯站
下面是响应该消息的步骤: SAE海岸线网络安全资讯站
SAE海岸线网络安全资讯站
取得“设备环境”句柄 SAE海岸线网络安全资讯站
绘制客户区 SAE海岸线网络安全资讯站
释放“设备环境”句柄 SAE海岸线网络安全资讯站
注意,您无须显式地让“无效区”有效,这个动作由 BeginPaint 自动完成。您可以在 BeginPaint 和 Endpaint 之间,调用所有的绘制函数。几乎所有的GDI 函数都需要“设备环境”的句柄作为参数。SAE海岸线网络安全资讯站
SAE海岸线网络安全资讯站
内容: SAE海岸线网络安全资讯站
SAE海岸线网络安全资讯站
我们将写一个应用程序,它会在客户区的中心显示一行 "Win32 assembly is great and easy!"SAE海岸线网络安全资讯站
SAE海岸线网络安全资讯站
.386 SAE海岸线网络安全资讯站
.model flat,stdcall SAE海岸线网络安全资讯站
option casemap:none SAE海岸线网络安全资讯站
SAE海岸线网络安全资讯站
WinMain proto :DWORD,:DWORD,:DWORD,:DWORD SAE海岸线网络安全资讯站
SAE海岸线网络安全资讯站
include \masm32\include\windows.inc SAE海岸线网络安全资讯站
include \masm32\include\user32.inc SAE海岸线网络安全资讯站
includelib \masm32\lib\user32.lib SAE海岸线网络安全资讯站
include \masm32\include\kernel32.inc SAE海岸线网络安全资讯站
includelib \masm32\lib\kernel32.lib SAE海岸线网络安全资讯站
SAE海岸线网络安全资讯站
.DATA SAE海岸线网络安全资讯站
ClassName db "SimpleWinClass",0 SAE海岸线网络安全资讯站
AppName db "Our First Window",0 SAE海岸线网络安全资讯站
OurText db "Win32 assembly is great and easy!",0 SAE海岸线网络安全资讯站
SAE海岸线网络安全资讯站
.DATA? SAE海岸线网络安全资讯站
hInstance HINSTANCE ? SAE海岸线网络安全资讯站
CommandLine LPSTR ? SAE海岸线网络安全资讯站
SAE海岸线网络安全资讯站
.CODE SAE海岸线网络安全资讯站
start: SAE海岸线网络安全资讯站
invoke GetModuleHandle, NULL SAE海岸线网络安全资讯站
mov hInstance,eax SAE海岸线网络安全资讯站
invoke GetCommandLineSAE海岸线网络安全资讯站
mov CommandLine,eaxSAE海岸线网络安全资讯站
invoke WinMain, hInstance,NULL,CommandLine, SW_SHOWDEFAULT SAE海岸线网络安全资讯站
invoke ExitProcess,eax SAE海岸线网络安全资讯站
SAE海岸线网络安全资讯站
WinMain proc hInst:HINSTANCE, hPrevInst:HINSTANCE, CmdLine:LPSTR, CmdShow:DWORD SAE海岸线网络安全资讯站
LOCAL wc:WNDCLASSEX SAE海岸线网络安全资讯站
LOCAL msg:MSG SAE海岸线网络安全资讯站
LOCAL hwnd:HWND SAE海岸线网络安全资讯站
mov wc.cbSize,SIZEOF WNDCLASSEX SAE海岸线网络安全资讯站
mov wc.style, CS_HREDRAW or CS_VREDRAW SAE海岸线网络安全资讯站
mov wc.lpfnWndProc, OFFSET WndProc SAE海岸线网络安全资讯站
mov wc.cbClsExtra,NULL SAE海岸线网络安全资讯站
mov wc.cbWndExtra,NULL SAE海岸线网络安全资讯站
push hInst SAE海岸线网络安全资讯站
pop wc.hInstance SAE海岸线网络安全资讯站
mov wc.hbrBackground,COLOR_WINDOW+1 SAE海岸线网络安全资讯站
mov wc.lpszMenuName,NULL SAE海岸线网络安全资讯站
mov wc.lpszClassName,OFFSET ClassName SAE海岸线网络安全资讯站
invoke LoadIcon,NULL,IDI_APPLICATION SAE海岸线网络安全资讯站
mov wc.hIcon,eax SAE海岸线网络安全资讯站
mov wc.hIconSm,eax SAE海岸线网络安全资讯站
invoke LoadCursor,NULL,IDC_ARROW SAE海岸线网络安全资讯站
mov wc.hCursor,eax SAE海岸线网络安全资讯站
invoke RegisterClassEx, addr wc SAE海岸线网络安全资讯站
invoke CreateWindowEx,NULL,ADDR ClassName,ADDR AppName,\ SAE海岸线网络安全资讯站
WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,\ SAE海岸线网络安全资讯站
CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,NULL,NULL,\ SAE海岸线网络安全资讯站
hInst,NULL SAE海岸线网络安全资讯站
mov hwnd,eax SAE海岸线网络安全资讯站
invoke ShowWindow, hwnd,SW_SHOWNORMAL SAE海岸线网络安全资讯站
invoke UpdateWindow, hwnd SAE海岸线网络安全资讯站
.WHILE TRUE SAE海岸线网络安全资讯站
invoke GetMessage, ADDR msg,NULL,0,0 SAE海岸线网络安全资讯站
.BREAK .IF (!eax) SAE海岸线网络安全资讯站
invoke TranslateMessage, ADDR msg SAE海岸线网络安全资讯站
invoke DispatchMessage, ADDR msg SAE海岸线网络安全资讯站
.ENDW SAE海岸线网络安全资讯站
mov eax,msg.wParam SAE海岸线网络安全资讯站
ret SAE海岸线网络安全资讯站
WinMain endp SAE海岸线网络安全资讯站
SAE海岸线网络安全资讯站
WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM SAE海岸线网络安全资讯站
LOCAL hdc:HDC SAE海岸线网络安全资讯站
LOCAL ps:PAINTSTRUCT SAE海岸线网络安全资讯站
LOCAL rect:RECT SAE海岸线网络安全资讯站
.IF uMsg==WM_DESTROY SAE海岸线网络安全资讯站
invoke PostQuitMessage,NULL SAE海岸线网络安全资讯站
.ELSEIF uMsg==WM_PAINT SAE海岸线网络安全资讯站
invoke BeginPaint,hWnd, ADDR ps SAE海岸线网络安全资讯站
mov hdc,eax SAE海岸线网络安全资讯站
invoke GetClientRect,hWnd, ADDR rect SAE海岸线网络安全资讯站
invoke DrawText, hdc,ADDR OurText,-1, ADDR rect, \ SAE海岸线网络安全资讯站
DT_SINGLELINE or DT_CENTER or DT_VCENTER SAE海岸线网络安全资讯站
invoke EndPaint,hWnd, ADDR ps SAE海岸线网络安全资讯站
.ELSE SAE海岸线网络安全资讯站
invoke DefWindowProc,hWnd,uMsg,wParam,lParam SAE海岸线网络安全资讯站
ret SAE海岸线网络安全资讯站
.ENDIF SAE海岸线网络安全资讯站
xor eax, eax SAE海岸线网络安全资讯站
ret SAE海岸线网络安全资讯站
WndProc endp SAE海岸线网络安全资讯站
end start SAE海岸线网络安全资讯站
SAE海岸线网络安全资讯站
分析: SAE海岸线网络安全资讯站
SAE海岸线网络安全资讯站
这里的大多数代码和第三课中的一样。我只解释其中一些不相同的地方。SAE海岸线网络安全资讯站
SAE海岸线网络安全资讯站
LOCAL hdc:HDCSAE海岸线网络安全资讯站
LOCAL ps:PAINTSTRUCTSAE海岸线网络安全资讯站
LOCAL rect:RECTSAE海岸线网络安全资讯站
SAE海岸线网络安全资讯站
这些局部变量由处理 WM_PAINT 消息中的 GDI 函数调用。hdc 用来存放调用 BeginPaint 返回的“设备环境”句柄。ps 是一个 PAINTSTRUCT 数据类型的变量。通常您不会用到其中的许多值,它由 Windows 传递给 BeginPaint,在结束绘制后再原封不动的传递给 EndPaint。rect 是一个 RECT 结构体类型参数,它的定义如下:SAE海岸线网络安全资讯站
SAE海岸线网络安全资讯站
RECT Struct left LONG ?SAE海岸线网络安全资讯站
top LONG ?SAE海岸线网络安全资讯站
right LONG ?SAE海岸线网络安全资讯站
bottom LONG ?SAE海岸线网络安全资讯站
RECT endsSAE海岸线网络安全资讯站
SAE海岸线网络安全资讯站
left 和 top 是正方形左上角的坐标。right 和 bottom 是正方形右下角的坐标。客户区的左上角的坐标是 x=0,y=0,这样对于 x=0,y=10 的坐标点就在它的下面。SAE海岸线网络安全资讯站
SAE海岸线网络安全资讯站
invoke BeginPaint,hWnd, ADDR psSAE海岸线网络安全资讯站
mov hdc,eaxSAE海岸线网络安全资讯站
invoke GetClientRect,hWnd, ADDR rectSAE海岸线网络安全资讯站
invoke DrawText, hdc,ADDR OurText,-1, ADDR rect, \ SAE海岸线网络安全资讯站
DT_SINGLELINE or DT_CENTER or DT_VCENTERSAE海岸线网络安全资讯站
invoke EndPaint,hWnd, ADDR psSAE海岸线网络安全资讯站
SAE海岸线网络安全资讯站
在处理 WM_PAINT 消息时,您调用BeginPaint函数,传给它一个窗口句柄和未初始化的 PAINTSTRUCT 型参数。调用成功后在 eax 中返回“设备环境”的句柄。下一次,调用 GetClientRect 以得到客户区的大小,大小放在 rect 中,然后把它传给 DrawText。DrawText 的语法如下: SAE海岸线网络安全资讯站
SAE海岸线网络安全资讯站
DrawText proto hdc:HDC, lpString:DWORD, nCount:DWORD, lpRect:DWORD, uformat:DWORD SAE海岸线网络安全资讯站
SAE海岸线网络安全资讯站
DrawText是一个高层的调用函数。它能自动处理像换行、把文本放到客户区中间等这些杂事。所以您只管集中精力“绘制”字符串就可以了。我们会在下一课中讲解低一层的函数 TextOut,该函数在一个正方形区域中格式化一个文本串。它用当前选择的字体、颜色和背景色。它处理换行以适应正方形区域。它会返回以设备逻辑单位度量的文本的高度,我们这里的度量单位是像素点。让我们来看一看该函数的参数: SAE海岸线网络安全资讯站
SAE海岸线网络安全资讯站
hdc: “设备环境”的句柄。 SAE海岸线网络安全资讯站
lpString:要显示的文本串,该文本串要么以NULL结尾,要么在nCount中指出它的长短。 SAE海岸线网络安全资讯站
nCount:要输出的文本的长度。若以NULL结尾,该参数必须是-1。 SAE海岸线网络安全资讯站
lpRect: 指向要输出文本串的正方形区域的指针,该方形必须是一个裁剪区,也就是说超过该区域的字符将不能显示。 SAE海岸线网络安全资讯站
uformat:指定如何显示。我们可以用 or 把以下标志或到一块: SAE海岸线网络安全资讯站
DT_SINGLELINE:是否单行显示。 SAE海岸线网络安全资讯站
DT_CENTER:是否水平居中。 SAE海岸线网络安全资讯站
DT_VCENTER :是否垂直居中。 SAE海岸线网络安全资讯站
SAE海岸线网络安全资讯站
SAE海岸线网络安全资讯站
结束绘制后,必须调用 EndPaint 释放“设备环境”的句柄。 好了,现在我们把“绘制”文本串的要点总结如下:SAE海岸线网络安全资讯站
SAE海岸线网络安全资讯站
必须在开始和结束处分别调用 BeginPaint 和 EndPaint; SAE海岸线网络安全资讯站
在 BeginPaint 和 EndPaint 之间调用所有的绘制函数; SAE海岸线网络安全资讯站
如果在其它的消息处理中重新绘制客户区,您可以有两种选择:SAE海岸线网络安全资讯站
(1)用GetDC和ReleaseDC代替BeginPaint和EndPaint;SAE海岸线网络安全资讯站
(2)调用InvalidateRect或UpdateWindow让客户区无效,这将迫使WINDOWS把WM_PAINT放入应用程序消息队列,从而使得客户区重绘。SAE海岸线网络安全资讯站