⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 clock.asm

📁 该示例实现了一个计算机同步时钟
💻 ASM
📖 第 1 页 / 共 2 页
字号:
           ;MoveToEx函数用来设置当前点的位置
           ;X1和Y1指出当前点的坐标
    invoke  LineTo,hDC,X2,Y2
           ;LineTo函数和MoveToEx函数配合起来使用
           ;用来绘制一条从点(X1,Y1)到(X2,Y2)的线段
    ret
_DrawLine  endp

;显示时钟
_ShowTime  proc  _hWnd,hDC
    local   stTime:SYSTEMTIME        ;SYSTEMTIME是一个结构,
                                     ;包括年月日时分秒等信息
                                     ;stTime是一个结构变量
    pushad
    
             
    invoke  GetLocalTime,addr stTime ;获取系统时间,返回到stTime中
    invoke  _CalcClock               ;调用子程序计算时钟在窗口中的位置和大小

    ;画时钟圆周上的点
    invoke  GetStockObject,WHITE_PEN 
        ;此函数得到画笔颜色,这里用白色画笔
        ;对象句柄,返回值放在eax中
    invoke  SelectObject,hDC,eax    
        ;SelectObject函数用来将GetStockObject函数
        ;得到的对象句柄放到hDC中
    
    ;画时钟圆心
    mov     eax,CentX          
    mov     ecx,CentX
    mov     ebx,CentY
    mov     edx,CentY
    sub     eax,6    ;圆心半径为6
    add     ecx,6
    sub     ebx,6
    add     edx,6
    invoke  Ellipse,hDC,eax,ebx,ecx,edx
    
    invoke  _DrawDot,hDC,90,4       ;90=360/4 ,画 4个大圆点,半径为4
    invoke  _DrawDot,hDC,30,3       ;30=360/12,画12个中圆点,半径为3
    invoke  _DrawDot,hDC,6,1        ;6=360/60 ,画60个小圆点,半径为1
    
    ;画时钟指针
    
    ;画秒针
    ;CreatePen函数可以自定义画笔
    invoke  CreatePen,PS_SOLID,1,00000ffh 
        ;1代表画笔粗度,00000ffh代表画笔颜色为红色
    invoke  SelectObject,hDC,eax
    invoke  DeleteObject,eax
    movzx   eax,stTime.wSecond      ;eax中放系统时间的秒值
    mov     ecx,6                   ;6=360/60
    mul     ecx                     ;秒针度数=秒*360/60
    invoke  _DrawLine,hDC,eax,12
           ;调用子程序画秒针,12用来调整秒针长度
    
    ;画分针
    invoke  CreatePen,PS_SOLID,2,000ff00h
       ;2代表画笔粗度,000ff00h代表画笔颜色为绿色
    invoke  SelectObject,hDC,eax
    invoke  DeleteObject,eax
    movzx   eax,stTime.wMinute      ;eax中放系统时间的分值
    mov     ecx,6                   ;6=360/60
    mul     ecx                     ;分针度数 = 分*360/60
    invoke  _DrawLine,hDC,eax,20    
            ;调用子程序画分针,20用来调整分针长度
    
    ;画时针
    invoke  CreatePen,PS_SOLID,3,0ff0080h
       ;3代表画笔粗度,0ff0080h代表画笔颜色为紫色
    invoke  SelectObject,hDC,eax
    invoke  DeleteObject,eax
    movzx   eax,stTime.wHour        ;eax中放系统时间的小时值
    .if     eax>=12
            sub  eax,12  
            ;系统时间为24小时制,若超过12小时就减去12
            ;使小时保持在0到12之间能被时钟显示
    .endif
    mov     ecx,30                  ;30=360/12
    mul     ecx
    movzx   ecx,stTime.wMinute
    shr     ecx,1
    add     eax,ecx
    invoke  _DrawLine,hDC,eax,32
            ;调用子程序画时针,32用来调整时针长度

    popad
    ret
_ShowTime  endp

;处理消息的子程序,
;窗口过程,用来给Windows回调
;这一部分直接套用了一般的模板;
;然后在里面加入了自己的注释,
;因为对这些API函数还没有时间熟悉
;以后要继续熟悉
_ProcWinMain  proc  uses ebx edi esi hWnd,uMsg,wParam,lParam
    local   stPS:PAINTSTRUCT   ;局部结构变量
    mov     eax,uMsg
    .if     eax==WM_TIMER
            ;WM_TIMER消息一般在计时器超时时发送
            ;用来执行计时回调函数
            ;(在一些资料上看到说这个消息存在
            ;安全问题,攻击者可以利用这个漏洞
            ;造成权限提升,具体的我还没有搞明白
            ;这里又留下一个问题)
            invoke  InvalidateRect,hWnd,NULL,TRUE
                    ;此函数屏蔽窗口客户区的区域
                    ;导致窗口客户区被重画
    .elseif eax==WM_PAINT
            ;绘制自己的客户区的代码放在这里
            invoke  BeginPaint,hWnd,addr stPS
                    ;WM_PAINT消息呼叫此函数,
                    ;使区域变成有效
                    ;它和EndPaint成对被呼叫
            invoke  _ShowTime,hWnd,eax     
                    ;区域有效后调用子程序显示时钟
            invoke  EndPaint,hWnd,addr stPS
    .elseif eax==WM_CREATE                   
            ;WM_CREATE是窗口建立收到的消息,
            ;放置窗口初始化代码
            invoke  SetTimer,hWnd,1,1000,NULL

    .elseif eax==WM_CLOSE
            ;WM_CLOSE是退出窗口时发送的消息
            invoke  KillTimer,hWnd,1
                    ;此函数用来取消定时器
            invoke  DestroyWindow,hWinMain   
                    ;此函数摧毁窗口
            invoke  PostQuitMessage,NULL
                    ;此函数结束消息循环
    .else
            invoke  DefWindowProc,hWnd,uMsg,wParam,lParam
                    ;此函数是默认的窗口回调函数
                    ;默认处理窗口的最大化最小化关闭等
     ret
    .endif
    xor     eax,eax
    ret
_ProcWinMain  endp

_WinMain  proc
    local   stWndClass:WNDCLASSEX 
         ;结构变量,WNDCLASSEX是一个有12个成员变量的结构体
         ;定义了窗口的属性等信息如图标光标
    local   stMsg:MSG
         ;结构变量,为了从消息队列中获取消息信息而使用MSG结构
    invoke  GetModuleHandle,NULL       ;得到应用程序的句柄
    mov     hInstance,eax

;注册窗口类
;这里查了一些资料,了解了这里用到的API函数,
;直接套用了一般窗口程序(包括上面处理消息的子程序)
;的模板,在里面添加了自己的一些数据,注释是自己写的。
    invoke  RtlZeroMemory,addr stWndClass,sizeof stWndClass
            ;此函数用来清除缓冲区,是为了下一次能正确显示
    invoke  LoadCursor,0,IDC_ARROW
            ;此函数用来装入光标,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
            ;回调函数指针,指向前面那个回调函数
    invoke  CreateSolidBrush,0002540h 
        ;此函数得到画刷颜色,这里用棕色画刷
        ;对象句柄,返回值放在eax中
    mov     stWndClass.hbrBackground,eax
            ;刷窗口颜色的画刷句柄,背景色为棕色
    mov     stWndClass.lpszClassName,offset szClassName
            ;指向窗口类名字的字符串指针
    invoke  RegisterClassEx,addr stWndClass
            ;注册窗口类的函数

    invoke  CreateWindowEx,WS_EX_CLIENTEDGE,\   ;建立窗口的函数
            offset szClassName,offset szClassName,\
            WS_OVERLAPPEDWINDOW,\
            800,1,200,210,\           ;设置窗口位置(800和1为窗口左上角顶点的坐标位置)
            NULL,NULL,hInstance,NULL  ;和大小(200和210分别为窗口的宽和高)
    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
                    ;把基于键盘扫描码的按键消息转换成基于ASCII码的键盘消息
            invoke  DispatchMessage,addr stMsg 
                    ;回调函数,使系统将消息发送到窗口过程来处理
    .endw
ret
_WinMain  endp

;程序入口
start:
    call    _WinMain
    invoke  ExitProcess,NULL                        
    end     start

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -