News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

Tray icon end automatically

Started by Magnum, December 06, 2011, 03:25:53 PM

Previous topic - Next topic

Magnum

I would like to add a tray icon for an app that dials in to my I.S.P.

Is it possible to have the icon automatically exit when my program has finished?

I was also interested in how to make an animated icon for that tray icon.



Have a great day,
                         Andy

Tedd

Add the icon (NIM_ADD) to the tray when your program starts, and remove it (NIM_DELETE) just before you finish.
To animate, you'd use NIM_MODIFY to update the icon on a timer; or change it on the result of some event (e.g. successful connection.)
No snowflake in an avalanche feels responsible.

Magnum

Sorry for the butchering.

Would I add my code at the end of WinMain ?


.data

    hInstance     dd 0
    hWnd          dd 0
    hIcon         dd 0
    hPopupMenu    dd 0

    szClassName   db "Dialing",0
    szDisplayName db "Dialing_In",0
                     
    szExitString  db "Exit program",0
   
    pt            POINT <>
    note          NOTIFYICONDATA <>

.code

start:
    invoke GetModuleHandle,0
    mov hInstance,eax
    invoke WinMain,hInstance,0,0,0
    invoke ExitProcess,eax

WinMain proc hInst:DWORD,hPrevInst:DWORD,CmdLine:DWORD,CmdShow:DWORD

; Standard window creation stuff

    LOCAL wc:WNDCLASSEX
    LOCAL msg:MSG

    mov wc.cbSize,SIZEOF WNDCLASSEX
    mov wc.style,CS_HREDRAW or CS_VREDRAW or CS_BYTEALIGNWINDOW
    mov wc.lpfnWndProc,OFFSET WndProc
    mov wc.cbClsExtra,0
    mov wc.cbWndExtra,0
    mov eax,hInst
    mov wc.hInstance,eax
    mov wc.hbrBackground,COLOR_WINDOW+1
    mov wc.lpszMenuName,0
    mov wc.lpszClassName,OFFSET szClassName
    invoke LoadImage,hInstance,500,IMAGE_ICON,0,0,LR_DEFAULTSIZE
    mov hIcon,eax
    mov wc.hIcon,eax
    invoke LoadCursor,0,IDC_ARROW
    mov wc.hCursor,eax
    mov wc.hIconSm,0

    invoke RegisterClassEx,ADDR wc

    invoke CreateWindowEx,WS_EX_LEFT,
                          ADDR szClassName,
                          ADDR szDisplayName,
                          WS_OVERLAPPEDWINDOW,
                          0,0,0,0,
                          0,0,
                          hInstance,0
    mov hWnd,eax

    StartLoop:
      invoke GetMessage,ADDR msg,0,0,0
      cmp eax,0
      je ExitLoop
      invoke TranslateMessage,ADDR msg
      invoke DispatchMessage,ADDR msg
      jmp StartLoop
    ExitLoop:
     
    mov eax,msg.wParam
    ret

WinMain endp

WndProc proc hWin:DWORD,uMsg:DWORD,wParam:DWORD,lParam:DWORD

          .if uMsg == WM_CREATE
              ; ------------------------------------------------------------
              ; We will need a pop up menu with one option to exit the app.
              ; ------------------------------------------------------------
              invoke CreatePopupMenu
              mov hPopupMenu,eax
              invoke AppendMenu,hPopupMenu,MF_STRING,IDM_EXIT,ADDR szExitString
             
              ; Send WM_SIZE which will place our apps icon in system tray.
              ; ------------------------------------------------------------
              invoke SendMessage,hWin,WM_SIZE,SIZE_MINIMIZED,0

     
    .elseif uMsg == WM_COMMAND
            ; -----------------------------------------------------------
            ; Handles our single pop up menu option to exit the program.
            ; -----------------------------------------------------------
            .if lParam == 0
                mov eax,wParam
                .if eax == IDM_EXIT
                    invoke Shell_NotifyIcon,NIM_DELETE,ADDR note
                    invoke SendMessage,hWin,WM_DESTROY,0,0
                .endif
            .endif

    .elseif uMsg == WM_SIZE
            ; ------------------------------------------------------
            ; Place the app icon in the system tray.
            ; ------------------------------------------------------
            .if wParam == SIZE_MINIMIZED
                mov note.cbSize,SIZEOF NOTIFYICONDATA
                push hWin
                pop note.hwnd
                mov note.uID,IDI_TRAY
                mov note.uFlags,NIF_ICON+NIF_MESSAGE+NIF_TIP
                mov note.uCallbackMessage,WM_SHELLNOTIFY
                mov eax,hIcon
                mov note.hIcon,eax
                invoke lstrcpy,ADDR note.szTip,ADDR szDisplayName
                invoke ShowWindow,hWin,SW_HIDE
                invoke Shell_NotifyIcon,NIM_ADD,ADDR note
            .endif

    .elseif uMsg == WM_DESTROY
           
            invoke DestroyMenu,hPopupMenu
            invoke PostQuitMessage,0

    .endif

    invoke DefWindowProc,hWin,uMsg,wParam,lParam
    ret

WndProc endp
end start

Have a great day,
                         Andy

Magnum

This puts the icon in the tray but doesn't dial out.


    .586                      ; create 32 bit code
    .model flat,stdcall       ; 32 bit memory model
    option casemap :none      ; case sensitive

include \masm32\include\windows.inc
include \masm32\include\user32.inc
    include \masm32\include\kernel32.inc
    include \masm32\include\shell32.inc
    include \masm32\include\rasapi32.inc
    include \masm32\include\winmm.inc


    includelib \masm32\lib\user32.lib
    includelib \masm32\lib\kernel32.lib
    includelib \masm32\lib\shell32.lib
    includelib \masm32\lib\rasapi32.lib
    includelib \masm32\lib\winmm.lib

RASENTRYNAME5A STRUCT
        dwSize          dd ?
        szEntryName     db 260 dup(?)
        dwFlags         dd ?
        szPhonebookPath db 264 dup(?)
    RASENTRYNAME5A ENDS

    RASENTRYNAME5 EQU <RASENTRYNAME5A>

    RASDIALPARAMS4A STRUCT
        dwSize           dd ?
        szEntryName      db 101h dup(?)
        szPhoneNumber    db 81h dup(?)
        szCallbackNumber db 81h dup(?)
        szUserName       db 101h dup(?)
        szPassword       db 101h dup(?)
        szDomain         db 13h dup(?)
        dwSubEntry       dd ?
        dwCallbackId     dd ?
    RASDIALPARAMS4A ENDS

    RASDIALPARAMS4 EQU <RASDIALPARAMS4A>

WM_SHELLNOTIFY equ WM_APP+5

    IDI_TRAY    equ 0
    IDM_EXIT    equ 100
   
    WinMain      PROTO :DWORD,:DWORD,:DWORD,:DWORD
    WndProc      PROTO :DWORD,:DWORD,:DWORD,:DWORD

.data

    hInstance     dd 0
    hWnd          dd 0
    hIcon         dd 0
    hPopupMenu    dd 0

    szClassName   db "Dialing",0
    szDisplayName db "Dialing_In",0
                     
    szExitString  db "Exit program",0
   
    ;pt            POINT <>
    note          NOTIFYICONDATA <>
    szApp db  "AutoDial",0
    Sound db  "C:\WINDOWS\Media\tada.wav",0


.code

start:
    invoke GetModuleHandle,0
    mov hInstance,eax
    invoke WinMain,hInstance,0,0,0
    invoke ExitProcess,eax

WinMain proc hInst:DWORD,hPrevInst:DWORD,CmdLine:DWORD,CmdShow:DWORD

; Standard window creation stuff

LOCAL wc:WNDCLASSEX
LOCAL msg:MSG

LOCAL lpRasEntryName    :DWORD
LOCAL dwCb              :DWORD
LOCAL dwEntries         :DWORD
LOCAL rp                :RASDIALPARAMS4
LOCAL fPass             :BOOL
LOCAL hConn             :DWORD


    mov wc.cbSize,SIZEOF WNDCLASSEX
    mov wc.style,CS_HREDRAW or CS_VREDRAW or CS_BYTEALIGNWINDOW
    mov wc.lpfnWndProc,OFFSET WndProc
    mov wc.cbClsExtra,0
    mov wc.cbWndExtra,0
    mov eax,hInst
    mov wc.hInstance,eax
    mov wc.hbrBackground,COLOR_WINDOW+1
    mov wc.lpszMenuName,0
    mov wc.lpszClassName,OFFSET szClassName
    invoke LoadImage,hInstance,500,IMAGE_ICON,0,0,LR_DEFAULTSIZE
    mov hIcon,eax
    mov wc.hIcon,eax
    invoke LoadCursor,0,IDC_ARROW
    mov wc.hCursor,eax
    mov wc.hIconSm,0

    invoke RegisterClassEx,ADDR wc

    invoke CreateWindowEx,WS_EX_LEFT,
                          ADDR szClassName,
                          ADDR szDisplayName,
                          WS_OVERLAPPEDWINDOW,
                          0,0,0,0,
                          0,0,
                          hInstance,0
    mov hWnd,eax

    StartLoop:

      invoke GetMessage,ADDR msg,0,0,0
      cmp eax,0
      je ExitLoop
      invoke TranslateMessage,ADDR msg
      invoke DispatchMessage,ADDR msg
      jmp StartLoop

   ExitLoop:
   ret

WinMain endp

WndProc proc hWin:DWORD,uMsg:DWORD,wParam:DWORD,lParam:DWORD

          .if uMsg == WM_CREATE
              ; ------------------------------------------------------------
              ; We will need a pop up menu with one option to exit the app.
              ; ------------------------------------------------------------
              ;invoke CreatePopupMenu
              ;mov hPopupMenu,eax
              ;invoke AppendMenu,hPopupMenu,MF_STRING,IDM_EXIT,ADDR szExitString
             
              ; Send WM_SIZE which will place our apps icon in system tray.
              ; ------------------------------------------------------------
              invoke SendMessage,hWin,WM_SIZE,SIZE_MINIMIZED,0

     
    .elseif uMsg == WM_COMMAND
            ; -----------------------------------------------------------
            ; Handles our single pop up menu option to exit the program.
            ; -----------------------------------------------------------
            ;.if lParam == 0
             ;   mov eax,wParam
              ;  .if eax == IDM_EXIT
               ;     invoke Shell_NotifyIcon,NIM_DELETE,ADDR note
                ;    invoke SendMessage,hWin,WM_DESTROY,0,0
                ;.endif
            ;.endif

    .elseif uMsg == WM_SIZE
            ; ------------------------------------------------------
            ; Place the app icon in the system tray.
            ; ------------------------------------------------------
            .if wParam == SIZE_MINIMIZED
                mov note.cbSize,SIZEOF NOTIFYICONDATA
                push hWin
                pop note.hwnd
                mov note.uID,IDI_TRAY
                mov note.uFlags,NIF_ICON+NIF_MESSAGE+NIF_TIP
                mov note.uCallbackMessage,WM_SHELLNOTIFY
                mov eax,hIcon
                mov note.hIcon,eax
                invoke lstrcpy,ADDR note.szTip,ADDR szDisplayName
                invoke ShowWindow,hWin,SW_HIDE
                invoke Shell_NotifyIcon,NIM_ADD,ADDR note
            .endif

    .elseif uMsg == WM_DESTROY
           
            invoke DestroyMenu,hPopupMenu
            invoke PostQuitMessage,0

    .endif

    invoke DefWindowProc,hWin,uMsg,wParam,lParam
    ret

WndProc endp

end start

Have a great day,
                         Andy

Magnum

I am learning even if it's at a turtle's pace.

This works, creates a tray icon and dials out if Ctrl F-12 is pressed.

What I would like is to have it automatically dial out when I start the program without using a HotKey.

I will wait till later to work on getting the tray icon to automatically end when a connection has been make.


  .586                      ; create 32 bit code
    .model flat,stdcall       ; 32 bit memory model
    option casemap :none      ; case sensitive

    include \masm32\include\windows.inc
    include \masm32\include\user32.inc
    include \masm32\include\kernel32.inc
    include \masm32\include\shell32.inc
    include \masm32\include\winmm.inc
    include \masm32\include\rasapi32.inc
   
    includelib \masm32\lib\user32.lib
    includelib \masm32\lib\kernel32.lib
    includelib \masm32\lib\shell32.lib
    includelib \masm32\lib\winmm.lib
    includelib \masm32\lib\rasapi32.lib

    WM_SHELLNOTIFY equ WM_APP+5

    IDI_TRAY    equ 0
    IDM_EXIT    equ 100
    IDH_HOTKEY1 equ 101
   
    WinMain      PROTO :DWORD,:DWORD,:DWORD,:DWORD
    WndProc      PROTO :DWORD,:DWORD,:DWORD,:DWORD

RASENTRYNAME5A STRUCT
        dwSize          dd ?
        szEntryName     db 260 dup(?)
        dwFlags         dd ?
        szPhonebookPath db 264 dup(?)
    RASENTRYNAME5A ENDS

    RASENTRYNAME5 EQU <RASENTRYNAME5A>

    RASDIALPARAMS4A STRUCT
        dwSize           dd ?
        szEntryName      db 101h dup(?)
        szPhoneNumber    db 81h dup(?)
        szCallbackNumber db 81h dup(?)
        szUserName       db 101h dup(?)
        szPassword       db 101h dup(?)
        szDomain         db 13h dup(?)
        dwSubEntry       dd ?
        dwCallbackId     dd ?
    RASDIALPARAMS4A ENDS

    RASDIALPARAMS4 EQU <RASDIALPARAMS4A>


.data

    hInstance     dd 0
    hWnd          dd 0
    hIcon         dd 0
    hPopupMenu    dd 0

    szClassName   db "AutoDial",0
    szDisplayName db "Dialing Out",0
                     
    szExitString  db "Exit program",0
    szApp db  "AutoDial",0
    Sound db  "C:\WINDOWS\Media\tada.wav",0

    pt            POINT <>
    note          NOTIFYICONDATA <>

.code

start:
    invoke GetModuleHandle,0
    mov hInstance,eax
    invoke WinMain,hInstance,0,0,0
    invoke ExitProcess,eax

WinMain proc hInst:DWORD,hPrevInst:DWORD,CmdLine:DWORD,CmdShow:DWORD

; Standard window creation stuff

    LOCAL wc:WNDCLASSEX
    LOCAL msg:MSG

    mov wc.cbSize,SIZEOF WNDCLASSEX
    mov wc.style,CS_HREDRAW or CS_VREDRAW or CS_BYTEALIGNWINDOW
    mov wc.lpfnWndProc,OFFSET WndProc
    mov wc.cbClsExtra,0
    mov wc.cbWndExtra,0
    mov eax,hInst
    mov wc.hInstance,eax
    mov wc.hbrBackground,COLOR_WINDOW+1
    mov wc.lpszMenuName,0
    mov wc.lpszClassName,OFFSET szClassName
    invoke LoadImage,hInstance,500,IMAGE_ICON,0,0,LR_DEFAULTSIZE
    mov hIcon,eax
    mov wc.hIcon,eax
    invoke LoadCursor,0,IDC_ARROW
    mov wc.hCursor,eax
    mov wc.hIconSm,0

    invoke RegisterClassEx,ADDR wc

    invoke CreateWindowEx,WS_EX_LEFT,
                          ADDR szClassName,
                          ADDR szDisplayName,
                          WS_OVERLAPPEDWINDOW,
                          0,0,0,0,
                          0,0,
                          hInstance,0
    mov hWnd,eax

    StartLoop:
      invoke GetMessage,ADDR msg,0,0,0
      cmp eax,0
      je ExitLoop
      invoke TranslateMessage,ADDR msg
      invoke DispatchMessage,ADDR msg
      jmp StartLoop
    ExitLoop:
     
    mov eax,msg.wParam
    ret

WinMain endp

WndProc proc hWin:DWORD,uMsg:DWORD,wParam:DWORD,lParam:DWORD

LOCAL lpRasEntryName    :DWORD
LOCAL dwCb              :DWORD
LOCAL dwEntries         :DWORD
LOCAL rp                :RASDIALPARAMS4
LOCAL fPass             :BOOL
LOCAL hConn             :DWORD

        .if uMsg == WM_CREATE
           
            ; We will need a pop up menu with one option to exit the app.
           
            invoke CreatePopupMenu
            mov hPopupMenu,eax
            invoke AppendMenu,hPopupMenu,MF_STRING,IDM_EXIT,ADDR szExitString
           
            ; Register hotkey
           
            invoke RegisterHotKey,hWin,IDH_HOTKEY1,MOD_CONTROL,VK_F12 ; Control F12 key
           
            ; Send WM_SIZE which will place our apps icon in system tray.
           
            invoke SendMessage,hWin,WM_SIZE,SIZE_MINIMIZED,0

    .elseif uMsg == WM_HOTKEY
            mov eax,lParam
            and eax,0FFFFh
            .if eax == MOD_CONTROL
               
                ; Ctrl key was pressed so check for additional key press.
               
                mov eax,lParam
                shr eax,16
                .if eax == VK_F12
                   
                    ; F12 function key was pressed
                   
                    ; Do something here ?

mov dwCb, sizeof RASENTRYNAME5
mov lpRasEntryName, 0

AllocateRasEntryNameLoop:

      cmp lpRasEntryName, 0
      je  AllocateRasEntryName
      invoke GetProcessHeap
      invoke HeapFree, eax, 0, lpRasEntryName

AllocateRasEntryName:
      invoke GetProcessHeap
      invoke HeapAlloc, eax, 0, dwCb
      cmp    eax, 0
      je     RetFail
     
      mov lpRasEntryName, eax
      invoke RtlZeroMemory, lpRasEntryName, dwCb
      mov ebx, sizeof RASENTRYNAME5
      mov eax, lpRasEntryName
      mov (RASENTRYNAME5 PTR [eax]).dwSize, ebx

      invoke RasEnumEntries, NULL, NULL, lpRasEntryName, ADDR dwCb, ADDR dwEntries
      cmp eax, 278h
      je AllocateRasEntryNameLoop

      cmp eax, 0
      jne RetFail

      mov dwCb, sizeof RASDIALPARAMS4

      invoke RtlZeroMemory, ADDR rp, dwCb     
      mov eax, dwCb
      mov rp.dwSize, eax

      mov eax, lpRasEntryName

invoke lstrcpy, ADDR rp.szEntryName, ADDR (RASENTRYNAME5 PTR [eax]).szEntryName

invoke RasGetEntryDialParams, NULL, ADDR rp, ADDR fPass
      cmp eax, 0
      jne RetFail
      mov hConn, 0

      invoke RasDial, NULL, NULL, ADDR rp, 0, NULL, ADDR hConn
      cmp eax, 0
      jne RetFail
      invoke PlaySound,ADDR Sound,NULL,SND_SYNC

RetFail:

      cmp lpRasEntryName, 0
      je AllocateRasEntryName
      invoke GetProcessHeap
      invoke HeapFree, eax, 0, lpRasEntryName

                .endif
             .endif

    .elseif uMsg == WM_COMMAND
           
            ; Handles our single pop up menu option to exit the program.
           
            .if lParam == 0
                mov eax,wParam
                .if eax == IDM_EXIT
                    invoke Shell_NotifyIcon,NIM_DELETE,ADDR note
                    invoke SendMessage,hWin,WM_DESTROY,0,0
                .endif
            .endif

    .elseif uMsg == WM_SIZE
           
            ; Places app icon in the system tray.
           
            .if wParam == SIZE_MINIMIZED
                mov note.cbSize,SIZEOF NOTIFYICONDATA
                push hWin
                pop note.hwnd
                mov note.uID,IDI_TRAY
                mov note.uFlags,NIF_ICON+NIF_MESSAGE+NIF_TIP
                mov note.uCallbackMessage,WM_SHELLNOTIFY
                mov eax,hIcon
                mov note.hIcon,eax
                invoke lstrcpy,ADDR note.szTip,ADDR szDisplayName
                invoke ShowWindow,hWin,SW_HIDE
                invoke Shell_NotifyIcon,NIM_ADD,ADDR note
            .endif

    .elseif uMsg == WM_SHELLNOTIFY
           
            ; Pop up apps menu if the user right clicks on sys tray icon.
           
            .if wParam == IDI_TRAY
                .if lParam == WM_RBUTTONDOWN or WM_RBUTTONUP
                    invoke GetCursorPos,ADDR pt
                    invoke SetForegroundWindow,hWin
                    invoke TrackPopupMenuEx,hPopupMenu,
                                            TPM_RIGHTALIGN or TPM_LEFTBUTTON,
                                            pt.x,pt.y,hWin,0
                    invoke PostMessage,hWin,WM_NULL,0,0
                .endif
            .endif

    .elseif uMsg == WM_DESTROY
           
            ; Unregister hotkeys destroy popup menu and shut down our app.
                       
            invoke UnregisterHotKey,hWin,IDH_HOTKEY1
            invoke DestroyMenu,hPopupMenu
            invoke PostQuitMessage,0

    .endif

    invoke DefWindowProc,hWin,uMsg,wParam,lParam
    ret

WndProc endp

end start

Have a great day,
                         Andy

dedndave

just put the Ras code in a PROC
call it when the hotkey is pressed, of course
but also call it after the program has initialized, perhaps at the end of WM_CREATE

another approach would be to generate a simulated hotkey
but, that seems like unnecessary code

Magnum

I don't want it activated by any hotkey.

How about generating a small window with a bmp that would go away after my program connects ?

That should be doable.

Have a great day,
                         Andy

Magnum

The addition of the last two lines closes the tray icon automatically after a connection is made.



RetFail:

      cmp lpRasEntryName, 0
      je AllocateRasEntryName
      invoke GetProcessHeap
      invoke HeapFree, eax, 0, lpRasEntryName

; Close tray icon after connection

invoke Shell_NotifyIcon,NIM_DELETE,ADDR note
invoke SendMessage,hWin,WM_DESTROY,0,0

Have a great day,
                         Andy