win32asm制作像素画画布

发布时间 2023-07-16 15:57:33作者: 邱云

 

类似于像素画软件中鼠标点击便绘制出一个小方块。

可以对窗口DC使用PatBlt函数。

1 invoke PatBlt,hDC,xDest,yDest,dwWidth,dwHeight,dwROP

dwWidth和dwHeight作为绘制的小方块的宽和高。dwROP决定方块图案。

在对WM_LBUTTONDOWN消息的处理中,获取此时鼠标的位置,根据鼠标的位置求出应该传给PatBlt函数的xDest和yDest参数的值。

例如:当鼠标点击的位置是(x+10,y+4),我们需要的(xDest,yDest)应该是(x,y)。

选取方块区域的左上角是因为PatBlt函数是将当前画刷的图案拷贝到hDC中以(xDest,yDest)为左上角坐标,dwWidth为宽度,dwHeight为高度的区域中。

不对鼠标位置进行处理的话,就不能绘制出规则排列的小方块。

还可以在窗口DC上画出网格,同样可以使用PatBlt函数,不过这次绘制的是宽度为1,高度为画布长度的竖线 和 宽度为画布长度,高度为1的横线。每隔相同距离绘制一次。

 一个简单的例子:

  1 .386
  2 .model flat,stdcall
  3 option casemap:none
  4 
  5 include         windows.inc     
  6 include         gdi32.inc
  7 includelib      gdi32.lib
  8 include         user32.inc      
  9 includelib      user32.lib
 10 include         kernel32.inc
 11 includelib      kernel32.lib
 12 ;================================================
 13         .const
 14 szClassName     db      'canvas',0
 15 szCaptionMain   db      'Can I draw Pixel?',0
 16 
 17         .data
 18 dwPixelSize     dd        16
 19         .data?
 20 hInstance       dd      ?
 21 hWinMain        dd      ?
 22 hDC             dd        ?
 23 dwPosx          dd        ?
 24 dwPosy          dd        ?
 25 ;================================================
 26         .code
 27 ;================================================
 28 _DrawGrid        proc    _hDC
 29                 local    @count
 30                 mov      @count,0
 31         ;========
 32         ;竖线
 33         ;========
 34         vertical:
 35                 invoke    PatBlt,_hDC,@count,0,1,320,BLACKNESS
 36                 add       @count,16
 37                 cmp      @count,320
 38                 jng      vertical
 39                 
 40                 mov       @count,0
 41         ;========
 42         ;横线
 43         ;========
 44         horizontal:
 45                 invoke    PatBlt,_hDC,0,@count,320,1,BLACKNESS
 46                 add       @count,16
 47                 cmp      @count,320
 48                 jng      horizontal
 49                 
 50                 ret
 51 _DrawGrid        endp
 52 ;================================================
 53 _AdjustPos        proc    _xPos,_yPos
 54                 push    eax
 55                 push    edx
 56                 xor        eax,eax
 57                 xor        edx,edx
 58                 mov        eax,_xPos
 59                 idiv      dwPixelSize
 60                 shl        eax,4
 61                 mov        dwPosx,eax
 62                 
 63                 xor        eax,eax
 64                 xor        edx,edx
 65                 mov        eax,_yPos
 66                 idiv      dwPixelSize
 67                 shl        eax,4
 68                 mov        dwPosy,eax
 69                 
 70                 pop        edx
 71                 pop        eax
 72                 ret
 73 _AdjustPos        endp
 74 ;================================================
 75 _ProcWinMain    proc    uses ebx edi esi,hWnd,uMsg,wParam,lParam
 76                 local   @stPs:PAINTSTRUCT
 77                 local   @stRect:RECT
 78                 local   @stPos:POINT
 79                 local   @hDc
 80 
 81                 mov     eax,uMsg
 82 ;*********************************************************************
 83                .if     eax ==  WM_PAINT
 84                         invoke  BeginPaint,hWnd,addr @stPs
 85                         mov     @hDc,eax
 86                         invoke    _DrawGrid,@hDc
 87                         invoke  EndPaint,hWnd,addr @stPs
 88 ;*********************************************************************
 89                 .elseif eax ==    WM_LBUTTONDOWN
 90                         invoke    GetCursorPos,addr @stPos
 91                         invoke    ScreenToClient,hWnd,addr @stPos
 92                         invoke    GetDC,hWnd
 93                         mov        hDC,eax
 94                         invoke    _AdjustPos,@stPos.x,@stPos.y
 95                         invoke    PatBlt,hDC,dwPosx,dwPosy,16,16,BLACKNESS
 96                         invoke    ReleaseDC,hWnd,hDC
 97 ;*********************************************************************
 98                 .elseif eax ==  WM_CLOSE
 99                         invoke  DestroyWindow,hWinMain
100                         invoke  PostQuitMessage,NULL
101 ;*********************************************************************
102                 .else
103                         invoke  DefWindowProc,hWnd,uMsg,wParam,lParam
104                         ret
105                 .endif
106 
107                 xor     eax,eax
108                 ret
109 
110 _ProcWinMain    endp
111 ;================================================
112 _WinMain        proc
113                 local   @stWndClass:WNDCLASSEX
114                 local   @stMsg:MSG
115 
116                 invoke  GetModuleHandle,NULL
117                 mov     hInstance,eax
118                 invoke  RtlZeroMemory,addr @stWndClass,sizeof @stWndClass
119                                                       
120                 invoke  LoadCursor,0,IDC_ARROW
121                 mov     @stWndClass.hCursor,eax
122                 push    hInstance
123                 pop     @stWndClass.hInstance
124                 mov     @stWndClass.cbSize,sizeof WNDCLASSEX
125                 mov     @stWndClass.style,CS_HREDRAW or CS_VREDRAW or CS_CLASSDC
126                 mov     @stWndClass.lpfnWndProc,offset _ProcWinMain
127                 mov     @stWndClass.hbrBackground,COLOR_WINDOW + 1
128                 mov     @stWndClass.lpszClassName,offset szClassName
129                 invoke  RegisterClassEx,addr @stWndClass
130         ;Create MainWindow
131                 invoke  CreateWindowEx,NULL,\
132                         offset szClassName,offset szCaptionMain,\
133                         WS_OVERLAPPED or WS_SYSMENU,\
134                         100,100,336,352,\
135                         NULL,NULL,hInstance,NULL
136                 mov     hWinMain,eax
137 
138                 invoke  ShowWindow,hWinMain,SW_SHOWNORMAL
139                 invoke  UpdateWindow,hWinMain
140                 
141                 .while  TRUE
142                         invoke  GetMessage,addr @stMsg,NULL,0,0
143                         .break  .if eax == 0
144                         invoke  TranslateMessage,addr @stMsg
145                         invoke  DispatchMessage,addr @stMsg
146                 .endw
147                 ret
148 
149 _WinMain        endp
150 ;================================================
151 start:
152     call    _WinMain
153     invoke  ExitProcess,NULL
154 end start