System Tray (win32)

This is an example how to add an icon to the Windows System Tray. Works on Windows 4.x, 5.x and 6.x.


  1. ; tray.asm - simple example of windows tray application
  2. ; written by Mateusz Tymek
  3. ; http://www.decard.net
  4. ;
  5. ; based on Iczelion's tutorial (http://www.win32asm.cjb.net/)
  6. ; you can modify and redistribute this code just as you wish :)
  7.  
  8.  
  9. format PE GUI 4.0
  10. entry start
  11. include "win32a.inc"
  12.  
  13. ; constants
  14. WM_SHELLNOTIFY = WM_USER+5
  15. IDI_TRAY       = 0
  16. IDM_SHOWHIDE   = 100
  17. IDM_EXIT       = 101
  18.  
  19.  
  20. ; data section
  21. section '.data' data readable writeable
  22.  
  23.   szClass db "WNDCLASS", 0
  24.   szTitle db "SysTray Example", 0
  25.   szShowHide db "&Show/Hide", 0
  26.   szExit     db "&Exit", 0
  27.  
  28.   hInstance dd ?
  29.   hTrayMenu dd ?
  30.   hMainWnd  dd ?
  31.   msg       MSG
  32.   wc        WNDCLASSEX
  33.   node      NOTIFYICONDATA
  34.   showflag  dd ?   ; 1 if main window is visible
  35.  
  36.  
  37. ; code section
  38. section '.code' code readable executable
  39.   start:
  40.         invoke  GetModuleHandle,0
  41.         mov     [hInstance],eax
  42.  
  43.      ; initialise main window
  44.         mov     [wc.hInstance],eax
  45.         xor     eax,eax
  46.         mov     [wc.cbSize],sizeof.WNDCLASSEX
  47.         mov     [wc.style],eax
  48.         mov     [wc.cbClsExtra],eax
  49.         mov     [wc.cbWndExtra],eax
  50.         mov     [wc.lpszMenuName],eax
  51.         mov     [wc.hIconSm],eax
  52.         mov     [wc.hbrBackground],COLOR_BTNFACE+1
  53.         mov     [wc.lpszClassName],szClass
  54.         mov     [wc.lpfnWndProc],MainWindowProc
  55.         invoke  LoadIcon, NULL,IDI_APPLICATION
  56.         mov     [wc.hIcon],eax
  57.         invoke  LoadCursor, NULL,IDC_ARROW
  58.         mov     [wc.hCursor],eax
  59.         invoke  RegisterClassEx, wc
  60.         or      eax,eax
  61.         jz      finish
  62.         invoke  CreateWindowEx, 0,szClass,szTitle,WS_VISIBLE+WS_OVERLAPPEDWINDOW,\
  63.                                 220,220,200,200,HWND_DESKTOP,0,[hInstance],0
  64.         or      eax,eax
  65.         jz      finish
  66.         mov     [hMainWnd],eax
  67.         mov     [showflag],1
  68.  
  69.   message_loop:
  70.         invoke  GetMessage, msg,NULL,0,0
  71.         or      eax,eax
  72.         jz      finish
  73.         invoke  TranslateMessage, msg
  74.         invoke  DispatchMessage, msg
  75.         jmp     message_loop
  76.   finish:
  77.         invoke  ExitProcess, [msg.wParam]
  78.  
  79.  
  80. proc MainWindowProc hWnd,uMsg,wparam,lparam
  81. local pt:POINT
  82.         push    ebx esi edi
  83.         mov     eax,[uMsg]
  84.         cmp     eax,WM_SHELLNOTIFY
  85.         je      .wmshellnotify
  86.         cmp     eax,WM_COMMAND
  87.         je      .wmcommand
  88.         cmp     eax,WM_SYSCOMMAND
  89.         je      .wmsyscommand
  90.         cmp     eax,WM_CREATE
  91.         je      .wmcreate
  92.         cmp     eax,WM_DESTROY
  93.         je      .wmdestroy
  94.   .defwndproc:
  95.         invoke  DefWindowProc, [hWnd],[uMsg],[wparam],[lparam]
  96.         jmp     .finish
  97.   .wmcreate:
  98.      ; create tray icon
  99.         ; fill NOTIFYICONDATA structure
  100.         mov     [node.cbSize],sizeof.NOTIFYICONDATA
  101.         mov     eax,[hWnd]
  102.         mov     [node.hWnd],eax
  103.         mov     [node.uID],IDI_TRAY
  104.         mov     [node.uFlags],NIF_ICON+NIF_MESSAGE+NIF_TIP
  105.         mov     [node.uCallbackMessage],WM_SHELLNOTIFY
  106.         invoke  LoadIcon, NULL,IDI_WINLOGO
  107.         mov     [node.hIcon],eax
  108.         mov     dword[node.szTip],"Tray"
  109.         mov     dword[node.szTip+4], " Dem"
  110.         mov     word[node.szTip+8], 'o'
  111.         invoke  Shell_NotifyIcon, NIM_ADD,node          ; show icon ton system tray
  112.         invoke  CreatePopupMenu                                         ;
  113.         mov     [hTrayMenu],eax                                         ; create popup menu
  114.         invoke  AppendMenu, eax,MF_STRING,IDM_SHOWHIDE,szShowHide       ;
  115.         invoke  AppendMenu, [hTrayMenu],MF_STRING,IDM_EXIT,szExit       ;
  116.         xor     eax,eax
  117.         jmp     .finish
  118.   .wmcommand:                           ; WM_COMMAND handler - here we handle clicks on tray icon
  119.         cmp     [lparam],0
  120.         jne     .finish
  121.         mov     eax,[wparam]
  122.         cmp     eax,IDM_SHOWHIDE
  123.         je      .showhide
  124.         cmp     eax,IDM_EXIT
  125.         je      .idm_exit
  126.         jmp     .finish
  127.   .idm_exit:
  128.         invoke  DestroyWindow, [hWnd]
  129.         jmp     .finish
  130.  
  131.   .wmsyscommand:                                ; when user presses "minimize" button, main window
  132.         cmp     [wparam],SC_MINIMIZE            ; should be hidden
  133.         jne     .defwndproc
  134.      .sc_minimize:
  135.         jmp     .showhide
  136.  
  137.   .wmshellnotify:                               ; WM_SHELLNOTIFY handler - here we handle actions
  138.         cmp     [wparam],IDI_TRAY               ; like clicking on our icon
  139.         jne     .finish
  140.         cmp     [lparam],WM_LBUTTONDOWN
  141.         je      .showhide
  142.         cmp     [lparam],WM_RBUTTONDOWN
  143.         je      .show_tray_popup
  144.         jmp     .finish
  145.   .showhide:
  146.         cmp     [showflag],0
  147.         je      .show
  148.       .hide:
  149.         invoke  ShowWindow, [hWnd],SW_HIDE
  150.         mov     [showflag], 0
  151.         jmp     .finish
  152.       .show:
  153.         invoke  ShowWindow, [hWnd],SW_SHOW
  154.         mov     [showflag], 1
  155.         jmp     .finish
  156.   .show_tray_popup:
  157.         lea     eax,[pt]
  158.         invoke  GetCursorPos, eax
  159.         invoke  SetForegroundWindow, [hWnd]
  160.         invoke  TrackPopupMenu, [hTrayMenu],TPM_RIGHTALIGN,[pt.x],[pt.y],\
  161.                                 NULL,[hWnd],NULL
  162.         invoke  PostMessage, [hWnd],WM_NULL,0,0
  163.         jmp     .finish
  164.  
  165.   .wmdestroy:
  166.         invoke  Shell_NotifyIcon, NIM_DELETE,node
  167.         invoke  DestroyMenu, [hTrayMenu]
  168.         invoke  PostQuitMessage, 0
  169.         xor     eax,eax
  170.   .finish:
  171.         pop     edi esi ebx
  172.         ret
  173. endp
  174.  
  175. ; imports
  176. section '.idata' import data readable
  177. library kernel32,"KERNEL32.DLL",\
  178.         user32,"USER32.DLL",\
  179.         shell32,"SHELL32.DLL"
  180.  
  181. include "api/kernel32.inc"
  182. include "api/user32.inc"
  183. include "api/shell32.inc"