GDI (Graphics Device Interface) 图形设备接口
1 GDI 原理
include gdi32.incinclude gdi32.lib
2 GDI程序结构
when where how 当窗口由被覆盖恢复时,会向用户程序发送一个WM_PAINT消息对于刷新速度比较快的程序使用A结构
对于刷新速度比较慢的程序使用B结构 3 WM_PAINT 消息 when windows系统发送WM_PAINT消息的情形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.incinclude gdi32.incincludelib gdi32.libinclude user32.incincludelib user32.libinclude kernel32.incincludelib kernel32.lib;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>ID_TIMER equ 1;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>; 数据段;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> .data?hInstance dd ?hWin1 dd ?hWin2 dd ? .constszClass1 db 'SourceWindow',0szClass2 db 'DestWindow',0szCaption1 db '请尝试用别的窗口覆盖本窗口!',0szCaption2 db '本窗口图像拷贝自另一窗口',0szText 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 CreateBrushIndirect2.2 绘制像素点
SetPixel
GetPixel GetDIBits2.3 绘制图形
1 绘制线条
LineTo
Polyline PolylineTo PolyBezier PolyBezierTo Arc ArcTo 移动当前点位置 MoveToEx GetCurrentPositionEx...