第7章 图形操作

GDI (Graphics Device Interface) 图形设备接口

1 GDI 原理

include gdi32.inc
include gdi32.lib

2 GDI程序结构
when where how
当窗口由被覆盖恢复时,会向用户程序发送一个WM_PAINT消息


GDI程序的结构

对于刷新速度比较快的程序使用A结构
对于刷新速度比较慢的程序使用B结构
3 WM_PAINT 消息
when
windows系统发送WM_PAINT消息的情形


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 copy程序效果

创建DC
CreateDC
CreateCompatibleDC
用完了要使用DeleteDC 删除

1.3 色彩与坐标

1 windows中的色彩

win32中用一个32位的整数来表示 一个尝试为24位的颜色
0-7 表示红色 8-15 表示绿色 16-23表示蓝色

windows中的坐标系

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


image.png

...

你可能感兴趣的:(第7章 图形操作)