zoukankan      html  css  js  c++  java
  • Win32汇编实现桌面时钟(有托盘图标)

    忙了两三天的空余时间,终于把桌面时钟程序完成了,功能也是比较粗糙的。众所周知的,汇编写程序容易造成代码膨胀,本程序光代码就用了465行,对于我来说也算是不少了……

    除了实现一些基本功能外,我还为程序实现了在托盘显示的功能。关于实现该功能,当然是费了不少时间,首先要感谢lczelion,他的理论支持下,让我知道了该如何去调用API,以及注意事项。主要还是windows外壳函数Shell_NotifyIcon和结构体NOTIFYICONDATA <>去配合实现的功能,具体如何调用网上也许有很多,就不去说了。但是还有一点就是如何实现窗口像QQ那样,只有托盘图标而把任务栏窗口隐藏?这是我所碰到的问题:原来CreateWindowEx中有个扩展属性WS_EX_TOOLWINDOW,该属性可以把我的想法实现。

    对于最费事的还是如何去画时钟,去使用位图。如何使用DC以及ROP码去实现时钟图案和背景,如何去画时钟的指针和外围的圆点,如何去使用浮点寄存器去精确计算时钟指针的坐标来为我所用……这些都是我所碰到的问题以及学习到得知识。再此又要感谢老罗了~~

    唯一一点没有按照我想法去走的就是如何只能让该实例程序只运行一个。由于时间关系,这个以后再去实现。据说要调用API,利用互斥法实现,具体思路和函数都知道了,实现也只是迟早的事情了。

    程序中一些基本的语句就没有注释,关键的地方用注释表明了。不明白的地方亦可以把MSDN拿出来查查。下面就把代码贴上去:

    资源文件Clock.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
    #define    ICO_TRAYICON    106
    //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
    ICO_MAIN        ICON    "Main.ico"
    IDC_MAIN        CURSOR  "Main.cur"
    IDC_MOVE        CURSOR  "Move.cur"
    IDB_BACK1       BITMAP  "Back1.bmp"
    IDB_CIRCLE1     BITMAP  "Circle1.bmp"
    IDB_MASK1       BITMAP  "Mask1.bmp"
    IDB_BACK2       BITMAP  "Back2.bmp"
    IDB_CIRCLE2     BITMAP  "Circle2.bmp"
    IDB_MASK2       BITMAP  "Mask2.bmp"
    ICO_TRAYICON    ICON    "TrayIcon.ico"
    //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

    Clock.asm源代:

    ;----------------------------------------------------------------
    include         windows.inc
    include         user32.inc
    includelib      user32.lib
    include         kernel32.inc
    includelib      kernel32.lib
    include         gdi32.inc
    includelib      gdi32.lib
    include         shell32.inc
    includelib      shell32.lib
    ;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
    WM_SHELLNOTIFY  equ     WM_USER + 1
    IDI_TRAYICON    equ     1       ;托盘小图标 ID
    
    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
    ICO_TRAYICON    equ     106
     
    ID_TIMER        equ     1
    IDM_BACK1       equ     100
    IDM_BACK2       equ     101
    IDM_CIRCLE1     equ     102
    IDM_CIRCLE2     equ     103
    IDM_TOPMOST     equ     104
    IDM_HIDE        equ     105
    IDM_SHOW        equ     106
    IDM_EXIT        equ     107
    ;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
                    .data?
                    
    hInstance       dd      ?
    hWinMain        dd      ?
    hCursorMain     dd      ?
    hCursorMove     dd      ?
    hMenu           dd      ?
    
    hBmpBack        dd      ?
    hDcBack         dd      ?
    hBmpClock       dd      ?
    hDcClock        dd      ?
     
    dwNowBack       dd      ?
    dwNowCircle     dd      ?
    
    stNote  NOTIFYICONDATA <>
    ;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
                    .const
                    
    szClassName     db      "Clock",0
    dwParam180      dw      180
    dwRadius        dw      CLOCK_SIZE/2
    szTrayTip       db      "Powered by Win32 Assembly",0
    szMenuBack1     db      "使用格子背景(&A)",0
    szMenuBack2     db      "使用花布背景(&B)",0
    szMenuCircle1   db      "使用淡蓝色边框(&C)",0
    szMenuCircle2   db      "使用粉红色边框(&D)",0
    szMenuTopMost   db      "总在最前(&T)",0
    szMenuHide      db      "隐藏时钟窗口(&H)",0
    szMenuShow      db      "显示时钟窗口(&S)",0
    szMenuExit      db      "退出(&X)...",0
    ;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
                    .code
    ;========================================
    ;计算出圆周上某个角度对应的 X 坐标
    ; X = 圆心X + sin(角度)*半径
    ;========================================
    _CalcX          proc    _dwDegree, _dwRadius
                    local   @dwReturn:DWORD
                    
                    fild    dwRadius
                    fild    _dwDegree
                    fldpi
                    fmul
                    fild    dwParam180
                    fdivp   st(1),st
                    fsin
                    fild    _dwRadius
                    fmul
                    fadd
                    fistp   @dwReturn
                    mov     eax,@dwReturn
                    ret
                    
    _CalcX          endp
    ;========================================
    ;计算出圆周上某个角度对应的 Y 坐标
    ; Y = 圆心Y - cos(角度)*半径
    ;========================================
    _CalcY          proc    _dwDegree, _dwRadius
                    local   @dwReturn:DWORD
                    
                    fild    dwRadius
                    fild    _dwDegree
                    fldpi
                    fmul
                    fild    dwParam180
                    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
                    local   @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
                    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
                    invoke  _DrawLine,hDcClock,eax,56
                    ;-----------------------------------
                    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,53
                    
                    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
                    invoke  CreateCompatibleDC,@hDC
                    mov     hDcBack,eax
                    invoke  CreateCompatibleDC,@hDC
                    mov     hDcClock,eax
                    invoke  CreateCompatibleDC,@hDC
                    mov     @hDcCircle,eax
                    invoke  CreateCompatibleDC,@hDC
                    mov     @hDcMask,eax
                    invoke  CreateCompatibleBitmap,@hDC,CLOCK_SIZE,CLOCK_SIZE
                    mov     hBmpBack,eax
                    invoke  CreateCompatibleBitmap,@hDC,CLOCK_SIZE,CLOCK_SIZE
                    mov     hBmpClock,eax
                    invoke  ReleaseDC,hWinMain,@hDC
                    
                    invoke  LoadBitmap,hInstance,dwNowBack
                    mov     @hBmpBack,eax
                    invoke  LoadBitmap,hInstance,dwNowCircle
                    mov     @hBmpCircle,eax
                    mov     eax,dwNowCircle
                    inc     eax
                    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
                    invoke  PatBlt,hDcBack,0,0,CLOCK_SIZE,CLOCK_SIZE,PATCOPY
                    pop     eax
                    invoke  DeleteObject,eax
                    
                    ;>>>>>>>>>>>关键技术<<<<<<<<<<<
                    ;///////////////////////////
                    ; 块传送函数中对于 ROP 码的操作
                    ;///////////////////////////
                    ;==========================画钟面
                    invoke  BitBlt,hDcBack,0,0,CLOCK_SIZE,CLOCK_SIZE,@hDcMask,0,0,SRCAND
                    invoke  BitBlt,hDcBack,0,0,CLOCK_SIZE,CLOCK_SIZE,@hDcCircle,0,0,SRCPAINT
                    
                    invoke  DeleteDC,@hDcCircle
                    invoke  DeleteDC,@hDcMask
                    invoke  DeleteObject,@hBmpBack
                    invoke  DeleteObject,@hBmpCircle
                    invoke  DeleteObject,@hBmpMask
                    ret
                    
    _CreateBackGround endp
    ;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
    _Initial        proc
                    ;========================初始化托盘图标
                    mov     stNote.cbSize,sizeof NOTIFYICONDATA
                    push    hWinMain
                    pop     stNote.hwnd     
                    mov     stNote.uID,IDI_TRAYICON
                    mov     stNote.uFlags,NIF_ICON+NIF_MESSAGE+NIF_TIP
                    mov     stNote.uCallbackMessage,WM_SHELLNOTIFY
                    invoke  LoadIcon,hInstance,ICO_TRAYICON
                    mov     stNote.hIcon,eax
                    invoke  lstrcpy,addr stNote.szTip,addr szTrayTip
                    invoke  Shell_NotifyIcon,NIM_ADD,offset stNote
                    
                    ;========================创建弹出菜单项
                    invoke  CreatePopupMenu
                    mov     hMenu,eax
                    
                    invoke  AppendMenu,hMenu,MF_BYCOMMAND,IDM_BACK1,offset szMenuBack1
                    invoke  AppendMenu,hMenu,MF_BYCOMMAND,IDM_BACK2,offset szMenuBack2
                    invoke  AppendMenu,hMenu,MF_SEPARATOR,0,0
                    invoke  AppendMenu,hMenu,MF_BYCOMMAND,IDM_CIRCLE1,offset szMenuCircle1
                    invoke  AppendMenu,hMenu,MF_BYCOMMAND,IDM_CIRCLE2,offset szMenuCircle2
                    invoke  AppendMenu,hMenu,MF_SEPARATOR,0,0
                    invoke  AppendMenu,hMenu,MF_BYCOMMAND,IDM_TOPMOST,offset szMenuTopMost
                    invoke  AppendMenu,hMenu,MF_BYCOMMAND,IDM_HIDE,offset szMenuHide
                    invoke  AppendMenu,hMenu,MF_BYCOMMAND,IDM_SHOW,offset szMenuShow
                    invoke  AppendMenu,hMenu,MF_SEPARATOR,0,0
                    invoke  AppendMenu,hMenu,MF_BYCOMMAND,IDM_EXIT,offset szMenuExit
                    
                    invoke  CheckMenuRadioItem,hMenu,IDM_BACK1,IDM_BACK2,IDM_BACK1,MF_BYCOMMAND
                    invoke  CheckMenuRadioItem,hMenu,IDM_CIRCLE1,IDM_CIRCLE2,IDM_CIRCLE1,MF_BYCOMMAND
                    
                    ;========================设置圆形窗口
                    invoke  CreateEllipticRgn,0,0,CLOCK_SIZE+1,CLOCK_SIZE+1
                    push    eax
                    invoke  SetWindowRgn,hWinMain,eax,TRUE
                    pop     eax
                    invoke  DeleteObject,eax
                    ;========================建立背景
                    mov     dwNowBack,IDB_BACK1
                    mov     dwNowCircle,IDB_CIRCLE1
                    invoke  _CreateBackGround
                    invoke  _CreateClockPic
                    ;========================建立周期为 1s 的计时器
                    invoke  SetTimer,hWinMain,ID_TIMER,1000,NULL
                    ret
                    
    _Initial        endp
    
    ;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
    _DelBackGround  proc
                    invoke  DeleteDC,hDcBack
                    invoke  DeleteDC,hDcClock
                    invoke  DeleteObject,hBmpBack
                    invoke  DeleteObject,hBmpClock
                    ret
                    
    _DelBackGround  endp
    ;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
    _Quit           proc
                    invoke  _DelBackGround
                    invoke  KillTimer,hWinMain,ID_TIMER
                    invoke  Shell_NotifyIcon,NIM_DELETE,addr stNote
                    invoke  DestroyWindow,hWinMain
                    invoke  PostQuitMessage,NULL
                    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
                    .elseif eax ==  WM_PAINT
                            invoke  BeginPaint,hWnd,addr @stPS
                            mov     @hDC,eax
                            mov     eax,@stPS.rcPaint.right
                            sub     eax,@stPS.rcPaint.left
                            mov     ecx,@stPS.rcPaint.bottom
                            sub     ecx,@stPS.rcPaint.top
                            invoke  BitBlt,@hDC,@stPS.rcPaint.left,@stPS.rcPaint.top,eax,ecx,/
                                    hDcClock,@stPS.rcPaint.left,@stPS.rcPaint.top,SRCCOPY
                            invoke  EndPaint,hWnd,addr @stPS
                    .elseif eax ==  WM_RBUTTONDOWN
                            invoke  GetCursorPos,addr @stPos
                            invoke  EnableMenuItem,hMenu,IDM_SHOW,MF_GRAYED
                            invoke  TrackPopupMenu,hMenu,TPM_LEFTALIGN,@stPos.x,@stPos.y,NULL,hWnd,NULL
                    .elseif eax ==  WM_LBUTTONDOWN
                            invoke  SetCursor,hCursorMove
                            invoke  UpdateWindow,hWnd
                            invoke  ReleaseCapture
                            invoke  SendMessage,hWnd,WM_NCLBUTTONDOWN,HTCAPTION,0
                            invoke  SetCursor,hCursorMain
                    .elseif eax ==  WM_COMMAND
                            mov     eax,wParam
                            .if     ax == IDM_BACK1
                                    mov     dwNowBack,IDB_BACK1
                                    invoke  CheckMenuRadioItem,hMenu,IDM_BACK1,IDM_BACK2,IDM_BACK1,MF_BYCOMMAND
                            .elseif ax == IDM_BACK2
                                    mov     dwNowBack,IDB_BACK2
                                    invoke  CheckMenuRadioItem,hMenu,IDM_BACK1,IDM_BACK2,IDM_BACK2,MF_BYCOMMAND
                            .elseif ax == IDM_CIRCLE1
                                    mov     dwNowCircle,IDB_CIRCLE1
                                    invoke  CheckMenuRadioItem,hMenu,IDM_CIRCLE1,IDM_CIRCLE2,IDM_CIRCLE1,MF_BYCOMMAND
                            .elseif ax == IDM_CIRCLE2
                                    mov     dwNowCircle,IDB_CIRCLE2
                                    invoke  CheckMenuRadioItem,hMenu,IDM_CIRCLE1,IDM_CIRCLE2,IDM_CIRCLE2,MF_BYCOMMAND
                            .elseif ax == IDM_TOPMOST
                                    movzx   eax,ax
                                    mov     ebx,eax
                                    invoke  GetMenuState,hMenu,ebx,MF_BYCOMMAND
                                    .if     eax ==  MF_CHECKED
                                            invoke  CheckMenuItem,hMenu,ebx,MF_UNCHECKED
                                            invoke  SetWindowPos,hWnd,HWND_NOTOPMOST,0,0,0,0,SWP_NOMOVE or SWP_NOSIZE
                                    .else
                                            invoke  CheckMenuItem,hMenu,ebx,MF_CHECKED
                                            invoke  SetWindowPos,hWnd,HWND_TOPMOST,0,0,0,0,SWP_NOMOVE or SWP_NOSIZE
                                    .endif
                            .elseif ax == IDM_SHOW
                                invoke    ShowWindow,hWnd,SW_RESTORE
                                    ;invoke  SetWindowPos,hWnd,HWND_TOPMOST,0,0,0,0,SWP_NOMOVE or SWP_NOSIZE
                                    ;invoke  SetWindowPos,hWnd,HWND_NOTOPMOST,0,0,0,0,SWP_NOMOVE or SWP_NOSIZE
                                    invoke    SetForegroundWindow,hWnd
                            .elseif ax == IDM_HIDE
                                    invoke  ShowWindow,hWnd,SW_HIDE
                            .elseif ax == IDM_EXIT
                                    call    _Quit
                                    xor     eax,eax
                                    ret
                            .endif
                            invoke  _DelBackGround
                            invoke  _CreateBackGround
                            invoke  _CreateClockPic
                            invoke  InvalidateRect,hWnd,NULL,FALSE
                    .elseif eax ==  WM_SHELLNOTIFY
                            .if     wParam == IDI_TRAYICON
                                    .if     lParam == WM_RBUTTONDOWN
                                            invoke  GetCursorPos,addr @stPos
                                            invoke  SetForegroundWindow,hWnd 
                                            invoke  EnableMenuItem,hMenu,IDM_SHOW,MF_ENABLED
                                            invoke  TrackPopupMenu,hMenu,TPM_RIGHTALIGN,@stPos.x,@stPos.y,NULL,hWnd,NULL 
                                            invoke  PostMessage,hWnd,WM_NULL,0,0
                                    .elseif lParam == WM_LBUTTONDBLCLK
                                            invoke  SendMessage,hWnd,WM_COMMAND,IDM_SHOW,0
                                            
                                    .endif
                            .endif
                    .elseif eax ==  WM_CREATE
                            mov     eax,hWnd
                            mov     hWinMain,eax
                            invoke  _Initial
                    .elseif eax ==  WM_CLOSE
                            call    _Quit
                    .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_MAIN
                    mov     hCursorMain,eax
                    invoke  LoadCursor,hInstance,IDC_MOVE
                    mov     hCursorMove,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 or CS_DBLCLKS
                    mov     @stWndClass.lpfnWndProc,offset _ProcWinMain
                    mov     @stWndClass.hbrBackground,COLOR_WINDOW + 1
                    mov     @stWndClass.lpszClassName,offset szClassName
                    
                    invoke  RegisterClassEx,addr @stWndClass
                    invoke  CreateWindowEx,WS_EX_TOOLWINDOW,/
                            offset szClassName,offset szClassName,/
                            WS_SYSMENU or WS_POPUP,/
                            900,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

    实验图片如下:

    时钟的图片:

    时钟图标

    鼠标放在托盘上:

    鼠标放在托盘上

    在时钟上点击右键:

    在时钟上点击右键

    在托盘图标上点击右键:


    在托盘图标上点击右键


    -------------------------------------------------------

    kedebug

    Department of Computer Science and Engineering,

    Shanghai Jiao Tong University

    E-mail: kedebug0@gmail.com

    GitHub: http://github.com/kedebug

    -------------------------------------------------------

  • 相关阅读:
    js使用html2canvas实现页面截图并保存图片
    微信小程序之图片base64解码
    微信小程序之回调函数
    小程序横向滚动
    搭建vue开发环境的步骤
    检测算法简介及其原理——fast R-CNN,faster R-CNN,YOLO,SSD,YOLOv2,YOLOv3
    hadoop常用命令
    工作流调度系统Azkaban的简介和使用
    java微服务简介与实战
    mxnet快速入门教程
  • 原文地址:https://www.cnblogs.com/kedebug/p/2791759.html
Copyright © 2011-2022 走看看