?? lion-tutorial04.htm
字號:
<html>
<head>
<link rel="stylesheet" href="../../asm.css">
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<title>Iczelion's win32 asm tutorial</title>
</head>
<body bgcolor="#FFFFFF" background="../../images/back01.jpg">
<p align="center">Tutorial 4: Painting with Text</p>
<hr size="1">
In this tutorial, we will learn how to "paint" text in the client area of a window.
We'll also learn about device context. <br>
You can download the source code <a href="files/tut04.zip">here</a>.
<h3> Theory:</h3>
Text in Windows is a type of GUI object. Each character is composed of numerous
pixels (dots) that are lumped together into a distinct pattern. That's why it's
called "painting" instead of "writing". Normally, you paint text in your own client
area (actually, you can paint outside client area but that's another story).
Putting text on screen in Windows is drastically different from DOS. In DOS, you
can think of the screen in 80x25 dimension. But in Windows, the screen are shared
by several programs. Some rules must be enforced to avoid programs writing over
each other's screen. Windows ensures this by limiting painting area of each window
to its own client area only. The size of client area of a window is also not constant.
The user can change the size anytime. So you must determine the dimensions of
your own client area dynamically. <br>
Before you can paint something on the client area, you must ask for permission
from Windows. That's right, you don't have absolute control of the screen as you
were in DOS anymore. You must ask Windows for permission to paint your own
client area. Windows will determine the size of your client area, font, colors
and other GDI attributes and sends a handle to device context back to your program.
You can then use the device context as a passport to painting on your client area.
<br>
What is a device context? It's just a data structure maintained internally by
Windows. A device context is associated with a particular device, such as a printer
or video display. For a video display, a device context is usually associated
with a particular window on the display. <br>
Some of the values in the device context are graphic attributes such as colors,
font etc. These are default values which you can change at will. They exist to
help reduce the load from having to specify these attributes in every GDI function
calls. <br>
You can think of a device context as a default environment prepared for you by
Windows. You can override some default settings later if you so wish. <br>
When a program need to paint, it must obtain a handle to a device context. Normally,
there are several ways to accomplish this.
<ul>
<b>call BeginPaint in response to WM_PAINT message.</b> <br>
<b>call GetDC in response to other messages.</b> <br>
<b>call CreateDC to create your own device context</b>
</ul>
One thing you must remember, after you're through with the device context handle,
you must release it during the processing of a single message. Don't obtain the
handle in response to one message and release it in response to another. <br>
Windows posts WM_PAINT messages to a window to notify that it's now time to repaint
its client area. Windows does not save the content of client area of a window.
Instead, when a situation occurs that warrants a repaint of client area (such
as when a window was covered by another and is just uncovered), Windows puts WM_PAINT
message in that window's message queue. It's the responsibility of that window
to repaint its own client area. You must gather all information about how to repaint
your client area in the WM_PAINT section of your window procedure, so the window
procudure can repaint the client area when WM_PAINT message arrives. <br>
Another concept you must come to terms with is the invalid rectangle. Windows
defines an invalid rectangle as the smallest rectangular area in the client area
that needs to be repainted. When Windows detects an invalid rectangle in the client
area of a window , it posts WM_PAINT message to that window. In response to WM_PAINT
message, the window can obtain a paintstruct structure which contains, among others,
the coordinate of the invalid rectangle. You call BeginPaint in response to WM_PAINT
message to validate the invalid rectangle. If you don't process WM_PAINT message,
at the very least you must call DefWindowProc or ValidateRect to validate the
invalid rectangle else Windows will repeatedly send you WM_PAINT message. <br>
Below are the steps you should perform in response to a WM_PAINT message:
<ul>
<b>Get a handle to device context with BeginPaint.</b> <br>
<b>Paint the client area.</b> <br>
<b>Release the handle to device context with EndPaint</b>
</ul>
Note that you don't have to explicitly validate the invalid rectangle. It's automatically
done by the BeginPaint call. Between BeginPaint-Endpaint pair, you can call any
GDI functions to paint your client area. Nearly all of them require the handle
to device context as a parameter.
<h3> Content:</h3>
We will write a program that displays a text string "Win32 assembly is great and
easy!" in the center of the client area. <br>
<blockquote><b>.386</b> <br>
<b>.model flat,stdcall</b> <br>
<b>option casemap:none</b>
<p><b>WinMain proto :DWORD,:DWORD,:DWORD,:DWORD</b>
<p><b>include \masm32\include\windows.inc</b> <br>
<b>include \masm32\include\user32.inc</b> <br>
<b>includelib \masm32\lib\user32.lib</b> <br>
<b>include \masm32\include\kernel32.inc</b> <br>
<b>includelib \masm32\lib\kernel32.lib</b>
<p><b>.DATA</b> <br>
<b>ClassName db "SimpleWinClass",0</b> <br>
<b>AppName db "Our First Window",0</b> <br>
<b>OurText db "Win32 assembly is great and easy!",0</b>
<p><b>.DATA?</b> <br>
<b>hInstance HINSTANCE ?</b> <br>
<b>CommandLine LPSTR ?</b>
<p><b>.CODE</b> <br>
<b>start:</b> <br>
<b> invoke GetModuleHandle, NULL</b> <br>
<b> mov hInstance,eax</b> <br>
<b> invoke GetCommandLine<br>
mov CommandLine,eax</b><br>
<b> invoke WinMain, hInstance,NULL,CommandLine, SW_SHOWDEFAULT</b>
<br>
<b> invoke ExitProcess,eax</b>
<p><b>WinMain proc hInst:HINSTANCE, hPrevInst:HINSTANCE, CmdLine:LPSTR, CmdShow:DWORD</b>
<br>
<b> LOCAL wc:WNDCLASSEX</b> <br>
<b> LOCAL msg:MSG</b> <br>
<b> LOCAL hwnd:HWND</b> <br>
<b> mov wc.cbSize,SIZEOF WNDCLASSEX</b> <br>
<b> mov wc.style, CS_HREDRAW or CS_VREDRAW</b>
<br>
<b> mov wc.lpfnWndProc, OFFSET WndProc</b> <br>
<b> mov wc.cbClsExtra,NULL</b> <br>
<b> mov wc.cbWndExtra,NULL</b> <br>
<b> push hInst</b> <br>
<b> pop wc.hInstance</b> <br>
<b> mov wc.hbrBackground,COLOR_WINDOW+1</b>
<br>
<b> mov wc.lpszMenuName,NULL</b> <br>
<b> mov wc.lpszClassName,OFFSET ClassName</b>
<br>
<b> invoke LoadIcon,NULL,IDI_APPLICATION</b> <br>
<b> mov wc.hIcon,eax</b> <br>
<b> mov wc.hIconSm,eax</b> <br>
<b> invoke LoadCursor,NULL,IDC_ARROW</b> <br>
<b> mov wc.hCursor,eax</b> <br>
<b> invoke RegisterClassEx, addr wc</b> <br>
<b> invoke CreateWindowEx,NULL,ADDR ClassName,ADDR AppName,\</b>
<br>
<b> WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,\</b>
<br>
<b> CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,NULL,NULL,\</b>
<br>
<b> hInst,NULL</b>
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -