GDI程序结构

A.计算和刷新整个客户区的代码全部安排在WM_PAINT消息中完成。这种结构适合功能模块很短小且执行速度

    很快的情况。

B.功能模块和客户区刷新模块分别在不同的子程序中实现,功能模块单独一个子程序完成,这个子程序可以由

    用户通过选择菜单项在WM_COMMAND消息中执行,也可以新建另外一个线程来完成。这种结构适合功能模

    块有些复杂的时候。

设备环境

不同设备的不同属性就构成了一个绘图的“环境”,这个绘图的“环境”就是WIN32编程中图形操作的对象,把它叫做“设备环境”。设备环境实际上是一个数据结构,结构中保存的就是设备的属性,当对设备环境进行图形操作的时候,Windows可以根据这些属性找到对应的设备进行相关的操作。

需要注意的是,“设备环境”只是一个环境,使设备属性的一组定义,程序输出的图形数据透过“设备环境”被定向到了具体的设备上,“设备环境”本身并不存储这些数据。

获取设备环境的句柄

BeginPaintEndPaint函数只能用在WM_PAINT消息中,因为只有这时才存在无效区域。

非WM_PAINT消息中主动绘画客户区,这时必须用另外的方法获取hDC,GetDCReleaseDC

; 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
  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
  local @hDc

  mov eax,uMsg
  mov ecx,hWnd
;********************************************************************
  .if eax == WM_PAINT && ecx == hWin1
   invoke BeginPaint,hWnd,addr @stPs
   mov @hDc,eax
   invoke GetClientRect,hWnd,addr @stRect
   invoke DrawText,@hDc,addr szText,-1,\
    addr @stRect,\
    DT_SINGLELINE or DT_CENTER or DT_VCENTER
   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
;********************************************************************
  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
  invoke CreateWindowEx,WS_EX_CLIENTEDGE,offset szClass1,offset szCaption1,\
   WS_OVERLAPPEDWINDOW,\
   450,100,300,300,\
   NULL,NULL,hInstance,NULL
  mov hWin1,eax
  invoke ShowWindow,hWin1,SW_SHOWNORMAL
  invoke UpdateWindow,hWin1
;********************************************************************
  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
  invoke ShowWindow,hWin2,SW_SHOWNORMAL
  invoke UpdateWindow,hWin2
;********************************************************************
; 设置定时器
;********************************************************************
  invoke SetTimer,NULL,NULL,100,addr _ProcTimer
  mov @hTimer,eax
;********************************************************************
; 消息循环
;********************************************************************
  .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


评论

该日志第一篇评论

发表评论

评论也有版权!