GDI (Graphics Device Interface) 图形设备接口
1 GDI 原理
include gdi32.inc
include gdi32.lib
2 GDI程序结构
when where how
当窗口由被覆盖恢复时,会向用户程序发送一个WM_PAINT消息
对于刷新速度比较快的程序使用A结构
对于刷新速度比较慢的程序使用B结构
3 WM_PAINT 消息
when
windows系统发送WM_PAINT消息的情形
无效区域
窗口重绘的API
BeginPaint
ValidateRect
EndPaint
1.2 设备环境
设备环境 抽象 绘图的设备
应用程序
设备环境
设备
dcCopy.asm
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Sample code for < Win32ASM Programming 3rd Edition>
; by 罗云彬, http://www.win32asm.com.cn
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; DcCopy.asm
; 测试设备环境的代码,将一个窗口 DC 对应的象素拷贝到另一个窗口中
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 使用 nmake 或下列命令进行编译和链接:
; ml /c /coff DcCopy.asm
; Link /subsystem:windows DcCopy.obj
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.386
.model flat,stdcall
option casemap:none
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Include 文件定义
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
include windows.inc
include gdi32.inc
includelib gdi32.lib
include user32.inc
includelib user32.lib
include kernel32.inc
includelib kernel32.lib
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
ID_TIMER equ 1
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 数据段
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.data?
hInstance dd ?
hWin1 dd ?
hWin2 dd ?
.const
szClass1 db 'SourceWindow',0
szClass2 db 'DestWindow',0
szCaption1 db '请尝试用别的窗口覆盖本窗口!',0
szCaption2 db '本窗口图像拷贝自另一窗口',0
szText db 'Win32 Assembly, Simple and powerful !',0
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.code
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 定时器过程
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_ProcTimer proc _hWnd,uMsg,_idEvent,_dwTime
local @hDc1,@hDc2
local @stRect:RECT
invoke GetDC,hWin1
mov @hDc1,eax
invoke GetDC,hWin2
mov @hDc2,eax
invoke GetClientRect,hWin1,addr @stRect
invoke BitBlt,@hDc2,0,0,@stRect.right,@stRect.bottom,\
@hDc1,0,0,SRCCOPY
;BOOL BitBlt(
; HDC hdcDest, // handle to destination device context
; int nXDest, // x-coordinate of destination rectangle's upper-left corner
; int nYDest, // y-coordinate of destination rectangle's upper-left corner
; int nWidth, // width of destination rectangle
; int nHeight, // height of destination rectangle
; HDC hdcSrc, // handle to source device context
; int nXSrc, // x-coordinate of source rectangle's upper-left corner
; int nYSrc, // y-coordinate of source rectangle's upper-left corner
; DWORD dwRop // raster operation code
; );
invoke ReleaseDC,hWin1,@hDc1
invoke ReleaseDC,hWin2,@hDc2
ret
_ProcTimer endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 窗口过程
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_ProcWinMain proc uses ebx edi esi,hWnd,uMsg,wParam,lParam
local @stPs:PAINTSTRUCT
local @stRect:RECT
;typedef struct _RECT { // rc
; LONG left;
; LONG top;
; LONG right;
; LONG bottom;
;} RECT;
local @hDc
mov eax,uMsg
mov ecx,hWnd
;********************************************************************
.if eax == WM_PAINT && ecx == hWin1 ;第一个窗口的WM_PAINT消息
invoke BeginPaint,hWnd,addr @stPs
;HDC BeginPaint(
; HWND hwnd, // handle to window
; LPPAINTSTRUCT lpPaint // pointer to structure for paint information
; );
;typedef struct tagPAINTSTRUCT { // ps
; HDC hdc;
; BOOL fErase;
; RECT rcPaint;
; BOOL fRestore;
; BOOL fIncUpdate;
; BYTE rgbReserved[32];
;} PAINTSTRUCT;
mov @hDc,EAX ;使用hDc保存返回的device context 句柄
invoke GetClientRect,hWnd,addr @stRect
;获取用户区的绘图区域 RECT表示一个矩形区域
;BOOL GetClientRect(
; HWND hWnd, // handle of window
; LPRECT lpRect // address of structure for client coordinates
; );
invoke DrawText,@hDc,addr szText,-1,\
addr @stRect,\
DT_SINGLELINE or DT_CENTER or DT_VCENTER
;绘制文本
;int DrawText(
; HDC hDC, // handle to device context
; LPCTSTR lpString, // pointer to string to draw
; int nCount, // string length, in characters
; LPRECT lpRect, // pointer to structure with formatting dimensions
; UINT uFormat // text-drawing flags
; );
invoke EndPaint,hWnd,addr @stPs
;********************************************************************
.elseif eax == WM_CLOSE
invoke PostQuitMessage,NULL
invoke DestroyWindow,hWin1
invoke DestroyWindow,hWin2
;********************************************************************
.else
invoke DefWindowProc,hWnd,uMsg,wParam,lParam
ret
.endif
;********************************************************************
xor eax,eax
ret
_ProcWinMain endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_WinMain proc
local @stWndClass:WNDCLASSEX
local @stMsg:MSG
local @hTimer
invoke GetModuleHandle,NULL
mov hInstance,EAX ;获取模块句柄
invoke RtlZeroMemory,addr @stWndClass,sizeof @stWndClass ;将窗口类结构体置0
;********************************************************************
;初始化窗口类
invoke LoadCursor,0,IDC_ARROW
mov @stWndClass.hCursor,EAX;将光标设置为箭头
push hInstance
pop @stWndClass.hInstance
mov @stWndClass.cbSize,sizeof WNDCLASSEX
mov @stWndClass.style,CS_HREDRAW or CS_VREDRAW
mov @stWndClass.lpfnWndProc,offset _ProcWinMain
mov @stWndClass.hbrBackground,COLOR_WINDOW + 1
mov @stWndClass.lpszClassName,offset szClass1
invoke RegisterClassEx,addr @stWndClass ;注册窗口类
;创建第一个窗口 sourcewindow
invoke CreateWindowEx,WS_EX_CLIENTEDGE,offset szClass1,offset szCaption1,\
WS_OVERLAPPEDWINDOW,\
450,100,300,300,\
NULL,NULL,hInstance,NULL
mov hWin1,EAX ;将第一个窗口的句柄保存至hWin1
;显示窗口
invoke ShowWindow,hWin1,SW_SHOWNORMAL
;更新窗口
invoke UpdateWindow,hWin1
;********************************************************************
;创建第二个窗口 destwindow 与第一个窗口使用同一个窗口过程
mov @stWndClass.lpszClassName,offset szClass2
invoke RegisterClassEx,addr @stWndClass
invoke CreateWindowEx,WS_EX_CLIENTEDGE,offset szClass2,offset szCaption2,\
WS_OVERLAPPEDWINDOW,\
100,100,300,300,\
NULL,NULL,hInstance,NULL
mov hWin2,EAX ;将第二个窗口的句柄保存至hWin2
invoke ShowWindow,hWin2,SW_SHOWNORMAL
invoke UpdateWindow,hWin2
;********************************************************************
; 设置定时器
;********************************************************************
;创建定时器
invoke SetTimer,NULL,NULL,100,addr _ProcTimer
mov @hTimer,EAX
;hTimer保存定时器ID
;********************************************************************
; 消息循环
;********************************************************************
.while TRUE
invoke GetMessage,addr @stMsg,NULL,0,0
.break .if eax == 0
invoke TranslateMessage,addr @stMsg
invoke DispatchMessage,addr @stMsg
.endw
;********************************************************************
; 清除定时器
;********************************************************************
;程序退出前撤销定时器
invoke KillTimer,NULL,@hTimer
ret
_WinMain endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
start:
call _WinMain
invoke ExitProcess,NULL
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
end start
效果
创建DC
CreateDC
CreateCompatibleDC
用完了要使用DeleteDC 删除
1.3 色彩与坐标
1 windows中的色彩
win32中用一个32位的整数来表示 一个尝试为24位的颜色
0-7 表示红色 8-15 表示绿色 16-23表示蓝色
windows中的坐标系
SetMapMode可以改变坐标系
2 编制图形
2.1 画笔和画刷
SelectObject
CreatePen
CreateSolidBrush
CreateHatchBrush
CreatePatternBrush
CreateBrushIndirect
2.2 绘制像素点
SetPixel
GetPixel
GetDIBits
2.3 绘制图形
1 绘制线条
LineTo
Polyline
PolylineTo
PolyBezier
PolyBezierTo
Arc
ArcTo
移动当前点位置
MoveToEx
GetCurrentPositionEx
...