【学习笔记】背景图时钟的笔记
背景图时钟.asm-----------------------------
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.386
.model flat, stdcall
option casemap :none
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Include 文件定义
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
include windows.inc
include user32.inc
includelib user32.lib
include kernel32.inc
includelib kernel32.lib
include Gdi32.inc
includelib Gdi32.lib
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Equ 等值定义
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
CLOCK_SIZE equ 150
ICO_MAIN equ 100
IDC_MAIN equ 100
IDC_MOVE equ 101
IDB_BACK1 equ 100
IDB_CIRCLE1 equ 101
IDB_MASK1 equ 102
IDB_BACK2 equ 103
IDB_CIRCLE2 equ 104
IDB_MASK2 equ 105
ID_TIMER equ 1
IDM_BACK1 equ 100
IDM_BACK2 equ 101
IDM_CIRCLE1 equ 102
IDM_CIRCLE2 equ 103
IDM_EXIT equ 104
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 数据段
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.data?
hInstance dd ?
hWinMain dd ?
hCursorMove dd ? ;移动的光标
hCursorMain dd ? ;不移动的光标
hMenu dd ?
hBmpBack dd ?
hDcBack dd ?
hBmpClock dd ?
hDcClock dd ?
dwNowBack dd ?
dwNowCircle dd ?
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 数据段
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.const
szClassName db 'Clock',0
dwPara180 dw 180
dwRadius dw CLOCK_SIZE/2
szMenuBack1 db '使用格子背景(&A)',0
szMenuBack2 db '使用花布背景(&B)',0
szMenuCircle1 db '使用淡蓝色边框(&C)',0
szMenuCircle2 db '使用粉红色边框(&D)',0
szMenuExit db '退出(&X)...',0
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 代码段
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.code
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 计算时钟圆周上某个角度对应的 X 坐标
; X = 圆心X + Sin(角度) * 半径
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_CalcX proc _dwDegree,_dwRadius
local @dwReturn
fild dwRadius
fild _dwDegree
fldpi
fmul ;角度*Pi
fild dwPara180
fdivp st(1),st ;角度*Pi/180
fsin ;Sin(角度*Pi/180)
fild _dwRadius
fmul ;半径*Sin(角度*Pi/180)
fadd ;X+半径*Sin(角度*Pi/180)
fistp @dwReturn
mov eax,@dwReturn
ret
_CalcX endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 计算时钟圆周上某个角度对应的 Y 坐标
; Y = 圆心Y - Cos(角度) * 半径
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_CalcY proc _dwDegree,_dwRadius
local @dwReturn
fild dwRadius
fild _dwDegree
fldpi
fmul
fild dwPara180
fdivp st(1),st
fcos
fild _dwRadius
fmul
fsubp st(1),st
fistp @dwReturn
mov eax,@dwReturn
ret
_CalcY endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 画 _dwDegree 角度的线条,半径=_dwRadius
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_DrawLine proc _hDC,_dwDegree,_dwRadius
local @dwX1,@dwY1,@dwX2,@dwY2
invoke _CalcX,_dwDegree,_dwRadius
mov @dwX1,eax
invoke _CalcY,_dwDegree,_dwRadius
mov @dwY1,eax
add _dwDegree,180
invoke _CalcX,_dwDegree,10
mov @dwX2,eax
invoke _CalcY,_dwDegree,10
mov @dwY2,eax
invoke MoveToEx,_hDC,@dwX1,@dwY1,NULL
invoke LineTo,_hDC,@dwX2,@dwY2
ret
_DrawLine endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_CreateClockPic proc ;画时钟指针
local @stTime:SYSTEMTIME
pushad
invoke BitBlt,hDcClock,0,0,CLOCK_SIZE,CLOCK_SIZE,hDcBack,0,0,SRCCOPY
;********************************************************************
; 画时钟指针
;********************************************************************
invoke GetLocalTime,addr @stTime
invoke CreatePen,PS_SOLID,1,0
invoke SelectObject,hDcClock,eax
invoke DeleteObject,eax
movzx eax,@stTime.wSecond
mov ecx,360/60
mul ecx ;秒针度数 = 秒 * 360/60
invoke _DrawLine,hDcClock,eax,60
;********************************************************************
invoke CreatePen,PS_SOLID,2,0
invoke SelectObject,hDcClock,eax
invoke DeleteObject,eax
movzx eax,@stTime.wMinute
mov ecx,360/60
mul ecx ;分针度数 = 分 * 360/60
invoke _DrawLine,hDcClock,eax,55
;********************************************************************
invoke CreatePen,PS_SOLID,3,0
invoke SelectObject,hDcClock,eax
invoke DeleteObject,eax
movzx eax,@stTime.wHour
.if eax >= 12
sub eax,12
.endif
mov ecx,360/12
mul ecx
movzx ecx,@stTime.wMinute
shr ecx,1
add eax,ecx
invoke _DrawLine,hDcClock,eax,50
;********************************************************************
invoke GetStockObject,NULL_PEN
invoke SelectObject,hDcClock,eax
invoke DeleteObject,eax
popad
ret
_CreateClockPic endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_CreateBackGround proc ;建立背景
local @hDc,@hDcCircle,@hDcMask ;创建局部变量
local @hBmpBack,@hBmpCircle,@hBmpMask ;创建局部变量
;********************************************************************
; 建立需要的临时对象
;********************************************************************
invoke GetDC,hWinMain ;获取设备环境句柄
mov @hDc,eax ;保存到局部变量hDc
invoke CreateCompatibleDC,@hDc ;创建兼容的设备环境句柄
mov hDcBack,eax ;存储句柄到hDcBack
invoke CreateCompatibleDC,@hDc ;创建兼容的设备环境句柄
mov hDcClock,eax ;存储句柄到hDcClock
invoke CreateCompatibleDC,@hDc ;创建兼容的设备环境句柄
mov @hDcCircle,eax ;存储句柄到@hDcCircle
invoke CreateCompatibleDC,@hDc ;创建兼容的设备环境句柄
mov @hDcMask,eax ;存储句柄到@hDcMask
invoke CreateCompatibleBitmap,@hDc,CLOCK_SIZE,CLOCK_SIZE ;创建与指定的设备环境相关的设备兼容的位图
mov hBmpBack,eax
invoke CreateCompatibleBitmap,@hDc,CLOCK_SIZE,CLOCK_SIZE ;创建与指定的设备环境相关的设备兼容的位图
mov hBmpClock,eax
invoke ReleaseDC,hWinMain,@hDc
;ReleaseDC 函数释放设备上下文环境(DC)供其他应用程序使用。
;函数的效果与设备上下文环境类型有关。它只释放公用的和设备上下文环境,对于类或私有的则无效。
invoke LoadBitmap,hInstance,dwNowBack ;格子背景8x8像素
mov @hBmpBack,eax
invoke LoadBitmap,hInstance,dwNowCircle ;淡蓝色边框
mov @hBmpCircle,eax
mov eax,dwNowCircle
inc eax ;eax的ID是101自增1是102==用于图案1的透明图
invoke LoadBitmap,hInstance,eax ;透明图像句柄
mov @hBmpMask,eax
invoke SelectObject,hDcBack,hBmpBack ;将兼容的位图句柄与兼容的设备环境句柄相关联
invoke SelectObject,hDcClock,hBmpClock
invoke SelectObject,@hDcCircle,@hBmpCircle
invoke SelectObject,@hDcMask,@hBmpMask
;********************************************************************
; 以背景图片填充
;********************************************************************
invoke CreatePatternBrush,@hBmpBack ;创建位图画刷
push eax
invoke SelectObject,hDcBack,eax ;将位图画刷与hDcBack(时钟背景)句柄关联
invoke PatBlt,hDcBack,0,0,CLOCK_SIZE,CLOCK_SIZE,PATCOPY
;使用当前选入指定设备环境中的刷子绘制给定的矩形区域,通过使用给出的光栅操作来对该刷子的颜色和表面颜色进行组合
;hdc :设备环境句柄。
;nXLeft :指定要填充的矩形左上角的X轴坐标,坐标按逻辑单位表示。
;nYLeft :指定要填充的矩形左上角的Y轴坐标,坐标按逻辑单位表示。
;nWidth :指定矩形的宽度,按逻辑单位表示宽度。
;nHeight:指定矩形的高度,按逻辑单位表示高度。
;dwRop :指定光栅操作码。该操作码可以取下列值,这些值的含义如下:
;PATCOPY:将指定的模式拷贝到目标位图中。
;PATINVERT:使用布尔XOR(异或)操作符将指定模式的颜色与目标矩形的颜色进行组合。
;DSTINVERT:将目标矩形反向。
;BLACKNESS:使用物理调色板中与索引0相关的颜色填充目标矩形。(对于缺省的物理调色板而言,该颜色为黑色)。
;WHITENESS:使用物理调色板中与索引1有关的颜色来填充目标矩形。(对于缺省的物理调色板而言,该颜色为白色)。
pop eax
invoke DeleteObject,eax ;用完了就释放了(卸磨杀驴)
;********************************************************************
; 画上钟面
;********************************************************************
invoke BitBlt,hDcBack,0,0,CLOCK_SIZE,CLOCK_SIZE,@hDcMask,0,0,SRCAND
;and二进制操作,黑色:0,白色:1,黑色部分是黑色,白色部分不变
invoke BitBlt,hDcBack,0,0,CLOCK_SIZE,CLOCK_SIZE,@hDcCircle,0,0,SRCPAINT
;or二进制操作,黑色:0,白色:1,有一个为真,结果为真。
invoke DeleteDC,@hDcCircle ;释放设备环境句柄和工具
invoke DeleteDC,@hDcMask
invoke DeleteObject,@hBmpBack
invoke DeleteObject,@hBmpCircle
invoke DeleteObject,@hBmpMask
ret
_CreateBackGround endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_DeleteBackGround proc
invoke DeleteDC,hDcBack
invoke DeleteDC,hDcClock
invoke DeleteObject,hBmpBack
invoke DeleteObject,hBmpClock
ret
_DeleteBackGround endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_Init proc
local @hBmpBack,@hBmpCircle ;背景、圆环
;********************************************************************
; 初始化菜单
;********************************************************************
invoke CreatePopupMenu ;创建弹出式下拉式菜单
mov hMenu,eax ;将菜单句柄放入hMenu
invoke AppendMenu,hMenu,0,IDM_BACK1,offset szMenuBack1 ;插入第一个菜单:使用格子背景
invoke AppendMenu,hMenu,0,IDM_BACK2,offset szMenuBack2 ;插入第二个菜单:使用花布背景
invoke AppendMenu,hMenu,MF_SEPARATOR,0,NULL ;画一条水平区分线
invoke AppendMenu,hMenu,0,IDM_CIRCLE1,offset szMenuCircle1 ;插入第三个菜单:使用淡蓝色边框
invoke AppendMenu,hMenu,0,IDM_CIRCLE2,offset szMenuCircle2 ;插入第三个菜单:使用粉红色边框
invoke AppendMenu,hMenu,MF_SEPARATOR,0,NULL ;画一条水平区分线
invoke AppendMenu,hMenu,0,IDM_EXIT,offset szMenuExit ;插入第四个菜单:退出
invoke CheckMenuRadioItem,hMenu,IDM_BACK1,IDM_BACK2,IDM_BACK1,NULL
;设置单选框按钮
invoke CheckMenuRadioItem,hMenu,IDM_CIRCLE1,IDM_CIRCLE2,IDM_CIRCLE1,NULL
;设置单选框按钮
;********************************************************************
; 设置圆形窗口并设置“总在最前面”
;********************************************************************
invoke CreateEllipticRgn,0,0,CLOCK_SIZE+0,CLOCK_SIZE+0 ;创建一个椭圆矩形左上角和右下角坐标
push eax ;将句柄压入堆栈
invoke SetWindowRgn,hWinMain,eax,TRUE ;设置窗口的可绘图区域
pop eax ;恢复椭圆的句柄
invoke DeleteObject,eax ;释放设备对象句柄
invoke SetWindowPos,hWinMain,HWND_TOPMOST,0,0,0,0,\ ;设置和获取窗口位置
SWP_NOMOVE or SWP_NOSIZE
;该函数改变一个子窗口,弹出式窗口或顶层窗口的尺寸,位置和Z序。
; 子窗口,弹出式窗口,及顶层窗口根据它们在屏幕上出现的顺序排序、顶层窗口设置的级别最高,并且被设置为Z序的第一个窗口。
;编辑本段参数
; hWnd:窗口句柄。
; hWndlnsertAfter:在z序中的位于被置位的窗口前的窗口句柄。该参数必须为一个窗口句柄,或下列值之一:
; HWND_BOTTOM:将窗口置于Z序的底部。如果参数hWnd标识了一个顶层窗口,则窗口失去顶级位置,并且被置在其他窗口的底部。
; HWND_NOTOPMOST:将窗口置于所有非顶层窗口之上(即在所有顶层窗口之后)。如果窗口已经是非顶层窗口则该标志不起作用。
; HWND_TOP:将窗口置于Z序的顶部。
; HWND_TOPMOST:将窗口置于所有非顶层窗口之上。即使窗口未被激活窗口也将保持顶级位置。
; 查看该参数的使用方法,请看说明部分。
; x:以客户坐标指定窗口新位置的左边界。
; Y:以客户坐标指定窗口新位置的顶边界。
; cx:以像素指定窗口的新的宽度。
; cy:以像素指定窗口的新的高度。
; uFlags:窗口尺寸和定位的标志。该参数可以是下列值的组合:
; SWP_ASNCWINDOWPOS:如果调用进程不拥有窗口,系统会向拥有窗口的线程发出需求。这就防止调用线程在其他线程处理需求的时候发生死锁。
; SWP_DEFERERASE:防止产生WM_SYNCPAINT消息。
; SWP_DRAWFRAME:在窗口周围画一个边框(定义在窗口类描述中)。
; SWP_FRAMECHANGED:给窗口发送WM_NCCALCSIZE消息,即使窗口尺寸没有改变也会发送该消息。如果未指定这个标志,只有在改变了窗口尺寸时才发送WM_NCCALCSIZE。
; SWP_HIDEWINDOW;隐藏窗口。
; SWP_NOACTIVATE:不激活窗口。如果未设置标志,则窗口被激活,并被设置到其他最高级窗口或非最高级组的顶部(根据参数hWndlnsertAfter设置)。
; SWP_NOCOPYBITS:清除客户区的所有内容。如果未设置该标志,客户区的有效内容被保存并且在窗口尺寸更新和重定位后拷贝回客户区。
; SWP_NOMOVE:维持当前位置(忽略X和Y参数)。
; SWP_NOOWNERZORDER:不改变z序中的所有者窗口的位置。
; SWP_NOREDRAW:不重画改变的内容。如果设置了这个标志,则不发生任何重画动作。适用于客户区和非客户区(包括标题栏和滚动条)和任何由于窗回移动而露出的父窗口的所有部分。如果设置了这个标志,应用程序必须明确地使窗口无效并区重画窗口的任何部分和父窗口需要重画的部分。
; SWP_NOREPOSITION;与SWP_NOOWNERZORDER标志相同。
; SWP_NOSENDCHANGING:防止窗口接收WM_WINDOWPOSCHANGING消息。
; SWP_NOSIZE:维持当前尺寸(忽略cx和Cy参数)。
; SWP_NOZORDER:维持当前Z序(忽略hWndlnsertAfter参数)。
; SWP_SHOWWINDOW:显示窗口。
;********************************************************************
; 建立背景
;********************************************************************
mov dwNowBack,IDB_BACK1 ;格子背景8x8像素
mov dwNowCircle,IDB_CIRCLE1 ;淡蓝色边框
invoke _CreateBackGround ;调用_CreateBackGround(画时钟背景图)
invoke _CreateClockPic ;调用_CreateClockPic(画时钟指针)
invoke SetTimer,hWinMain,ID_TIMER,1000,NULL ;创建一个定时器,间隔:1s
ret
_Init endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_Quit proc
invoke KillTimer,hWinMain,ID_TIMER
invoke DestroyWindow,hWinMain
invoke PostQuitMessage,NULL
invoke _DeleteBackGround ;删除图像
invoke DestroyMenu,hMenu
ret
_Quit endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_ProcWinMain proc uses ebx edi esi hWnd,uMsg,wParam,lParam
local @stPS:PAINTSTRUCT
local @hDC
local @stPos:POINT
mov eax,uMsg
;********************************************************************
.if eax == WM_TIMER
invoke _CreateClockPic ;画时钟指针子程序
invoke InvalidateRect,hWnd,NULL,FALSE ;重画时不擦除背景,并且窗口过程会处理WM_PAINT消息
;********************************************************************
.elseif eax == WM_PAINT
invoke BeginPaint,hWnd,addr @stPS
mov @hDC,eax
mov eax,@stPS.rcPaint.right
sub eax,@stPS.rcPaint.left ;eax存储了长度
mov ecx,@stPS.rcPaint.bottom
sub ecx,@stPS.rcPaint.top ;ecx存储了宽度
invoke BitBlt,@hDC,@stPS.rcPaint.left,\
@stPS.rcPaint.top,eax,ecx,hDcClock,\
@stPS.rcPaint.left,@stPS.rcPaint.top,SRCCOPY
;对指定的源设备环境区域中的像素进行位块(bit_block)转换,以传送到目标设备环境
;hdcDest :指向目标设备环境的句柄。
;nXDest :指定目标矩形区域左上角的X轴逻辑坐标。
;nYDest :指定目标矩形区域左上角的Y轴逻辑坐标。
;nWidth :指定源和目标矩形区域的逻辑宽度。
;nHeight :指定源和目标矩形区域的逻辑高度。
;hdcSrc :指向源设备环境的句柄。
;nXSrc :指定源矩形区域左上角的X轴逻辑坐标。
;nYSrc :指定源矩形区域左上角的Y轴逻辑坐标。
;dwRop :指定光栅操作代码。这些代码将定义源矩形区域的颜色数据,如何与目标矩形区域的颜色数据组合以完成最后的颜色。
;SRCCOPY :将源矩形区域直接拷贝到目标矩形区域。
;dwRop:指定光栅操作代码。这些代码将定义源矩形区域的颜色数据,如何与目标矩形区域的颜色数据组合以完成最后的颜色。
;BLACKNESS :表示使用与物理调色板的索引0相关的色彩来填充目标矩形区域,(对缺省的物理调色板而言,该颜色为黑色)。
;DSTINVERT :表示使目标矩形区域颜色取反。
;MERGECOPY :表示使用布尔型的AND(与)操作符将源矩形区域的颜色与特定模式组合一起。
;MERGEPAINT :通过使用布尔型的OR(或)操作符将反向的源矩形区域的颜色与目标矩形区域的颜色合并。
;NOTSRCCOPY :将源矩形区域颜色取反,于拷贝到目标矩形区域。
;NOTSRCERASE :使用布尔类型的OR(或)操作符组合源和目标矩形区域的颜色值,然后将合成的颜色取反。
;PATCOPY :将特定的模式拷贝到目标位图上。
;PATPAINT :通过使用布尔OR(或)操作符将源矩形区域取反后的颜色值与特定模式的颜色合并。然后使用OR(或)操作符将该操作的结果与目标矩形区域内的颜色合并。
;PATINVERT :通过使用XOR(异或)操作符将源和目标矩形区域内的颜色合并。
;SRCAND :通过使用AND(与)操作符来将源和目标矩形区域内的颜色合并。
;SRCCOPY :将源矩形区域直接拷贝到目标矩形区域。
;SRCERASE :通过使用AND(与)操作符将目标矩形区域颜色取反后与源矩形区域的颜色值合并。
;SRCINVERT :通过使用布尔型的XOR(异或)操作符将源和目标矩形区域的颜色合并。
;SRCPAINT :通过使用布尔型的OR(或)操作符将源和目标矩形区域的颜色合并。
;WHITENESS :使用与物理调色板中索引1有关的颜色填充目标矩形区域。(对于缺省物理调色板来说,这个颜色就是白色)。
invoke EndPaint,hWnd,addr @stPS
;********************************************************************
.elseif eax == WM_CREATE
mov eax,hWnd
mov hWinMain,eax
invoke _Init ;窗口初始化
;********************************************************************
.elseif eax == WM_COMMAND
mov eax,wParam
.if ax == IDM_BACK1 ;使用格子背景
mov dwNowBack,IDB_BACK1
invoke CheckMenuRadioItem,hMenu,IDM_BACK1,IDM_BACK2,IDM_BACK1,NULL
.elseif ax == IDM_BACK2 ;使用花布背景
mov dwNowBack,IDB_BACK2
invoke CheckMenuRadioItem,hMenu,IDM_BACK1,IDM_BACK2,IDM_BACK2,NULL
.elseif ax == IDM_CIRCLE1 ;使用淡蓝色边框
mov dwNowCircle,IDB_CIRCLE1
invoke CheckMenuRadioItem,hMenu,IDM_CIRCLE1,IDM_CIRCLE2,IDM_CIRCLE1,NULL
.elseif ax == IDM_CIRCLE2 ;使用粉红色边框
mov dwNowCircle,IDB_CIRCLE2
invoke CheckMenuRadioItem,hMenu,IDM_CIRCLE1,IDM_CIRCLE2,IDM_CIRCLE2,NULL
.elseif ax == IDM_EXIT
call _Quit
xor eax,eax
ret
.endif
invoke _DeleteBackGround ;删除内存空间所有图像
invoke _CreateBackGround ;绘画时钟背景
invoke _CreateClockPic ;绘画时钟指针
invoke InvalidateRect,hWnd,NULL,FALSE ;使窗口客户区无效,并且发送WM_PAINT消息
;********************************************************************
.elseif eax == WM_CLOSE
call _Quit
;********************************************************************
; 按下右键时弹出一个POPUP菜单
;********************************************************************
.elseif eax == WM_RBUTTONDOWN
invoke GetCursorPos,addr @stPos
invoke TrackPopupMenu,hMenu,TPM_LEFTALIGN,@stPos.x,@stPos.y,NULL,hWnd,NULL
;********************************************************************
; 由于没有标题栏,下面代码用于按下左键时移动窗口
; UpdateWindow:即时刷新,否则要等到放开鼠标时窗口才会重画
;********************************************************************
.elseif eax == WM_LBUTTONDOWN ;检测鼠标左键按下
invoke SetCursor,hCursorMove ;设置光标为抓住的手势
invoke UpdateWindow,hWnd ;更新窗口
invoke ReleaseCapture
;从当前线程中的窗口释放鼠标捕获,并恢复通常的鼠标输入处理,捕获鼠标的窗口接收所有的鼠标输入(无论光标的位置在哪里)除非点击鼠标键时,光标热点在另一个线程的窗口中
invoke SendMessage,hWnd,WM_NCLBUTTONDOWN,HTCAPTION,0
;WM_NCLBUTTONDOWN是在左击非客户区(Caption标题栏)时响应
;HTCAPTION:移动窗口
invoke SetCursor,hCursorMain ;设置光标为抓取手型
;********************************************************************
.else
invoke DefWindowProc,hWnd,uMsg,wParam,lParam
ret
.endif
;********************************************************************
xor eax,eax
ret
_ProcWinMain endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_WinMain proc
local @stWndClass:WNDCLASSEX
local @stMsg:MSG
invoke GetModuleHandle,NULL
mov hInstance,eax
invoke LoadCursor,hInstance,IDC_MOVE ;载入文件光标资源(按下左键时抓住的手势)
mov hCursorMove,eax
invoke LoadCursor,hInstance,IDC_MAIN ;载入文件光标资源(松开左键时的手势)
mov hCursorMain,eax
;********************************************************************
; 注册窗口类
;********************************************************************
invoke RtlZeroMemory,addr @stWndClass,sizeof @stWndClass
invoke LoadIcon,hInstance,ICO_MAIN
mov @stWndClass.hIcon,eax
mov @stWndClass.hIconSm,eax
push hCursorMain
pop @stWndClass.hCursor
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 szClassName
invoke RegisterClassEx,addr @stWndClass
;********************************************************************
; 建立并显示窗口
;********************************************************************
invoke CreateWindowEx,NULL,\
offset szClassName,offset szClassName,\
WS_POPUP or WS_SYSMENU,\
100,100,CLOCK_SIZE,CLOCK_SIZE,\
NULL,NULL,hInstance,NULL
mov hWinMain,eax
invoke ShowWindow,hWinMain,SW_SHOWNORMAL
invoke UpdateWindow,hWinMain
;********************************************************************
; 消息循环
;********************************************************************
.while TRUE
invoke GetMessage,addr @stMsg,NULL,0,0
.break .if eax == 0
invoke TranslateMessage,addr @stMsg
invoke DispatchMessage,addr @stMsg
.endw
ret
_WinMain endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
start:
call _WinMain
invoke ExitProcess,NULL
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
end start
背景图时钟.rc
-----------------------------------------
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
#include <resource.h>
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
#define ICO_MAIN 100
#define IDC_MAIN 100
#define IDC_MOVE 101
#define IDB_BACK1 100
#define IDB_CIRCLE1 101
#define IDB_MASK1 102
#define IDB_BACK2 103
#define IDB_CIRCLE2 104
#define IDB_MASK2 105
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
ICO_MAIN ICON "Main.ico" //文件图标
IDC_MAIN CURSOR "Main.cur" //鼠标静止光标
IDC_MOVE CURSOR "Move.cur" //鼠标移动光标
IDB_BACK1 BITMAP "Back1.bmp" //格子背景8x8像素
IDB_CIRCLE1 BITMAP "Circle1.bmp" //淡蓝色边框
IDB_MASK1 BITMAP "Mask1.bmp" //用于图案1的透明图
IDB_BACK2 BITMAP "Back2.bmp" //花色背景8x8像素
IDB_CIRCLE2 BITMAP "Circle2.bmp" //粉红色边框
IDB_MASK2 BITMAP "Mask2.bmp" //用于图案2的透明图 radasm工具的工程。学习的挺困难的 ProcWinMain endp 好可爱{:5_92:}
页:
[1]