News:

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

Blinking icon

Started by Magnum, December 12, 2011, 03:43:11 PM

Previous topic - Next topic

Magnum

I am trying to get this to blink between 2 icons that I made.
I only want it to blink only when it is dialing out.

Is the PdhAddCounter and related code used for disk activity and thus not needed ?

I am stuck.


; Contains code by MichaelW
;
  .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
    IDM_Dial    equ 200
    IDM_Hangup  equ 250
    IDH_HOTKEY1 equ 101
   
    WinMain      PROTO :DWORD,:DWORD,:DWORD,:DWORD
    WndProc      PROTO :DWORD,:DWORD,:DWORD,:DWORD

ID_TIMER                equ 1

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
    szDial_Out    db  "Dial in to Internet.",0
    szHangup      db  "Disconnect from the internet.",0
    szApp         db  "AutoDial",0
    Sound         db  "C:\WINDOWS\Media\tada.wav",0

    pt            POINT <>
    note          NOTIFYICONDATA <>

.data?

l_RASCONN RASCONN 0FFh dup ({})
l_Buffer_Size dd   ?
l_Conn_Count  dd   ?
Green_Blink   dd   ?
Red_Blink     dd   ?


.code

WaterMark   db "SiegeWorks"
%Date       db " &@Date " ; Compile date

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

invoke SetTimer, hWnd, ID_TIMER, 100, NULL

    StartLoop:
      invoke GetMessage,ADDR msg,0,0,0
      cmp eax,0
      je ExitLoop
      invoke TranslateMessage,ADDR msg
      invoke DispatchMessage,ADDR msg
      jmp StartLoop
    ExitLoop:
     
invoke PdhCloseQuery, hQuery
invoke KillTimer, hWnd, ID_TIMER
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
           
invoke LoadImage,hInstance,1000,IMAGE_ICON,0,0,NULL
mov Green_Blink,eax

invoke LoadImage,hInstance,1000,IMAGE_ICON,0,0,NULL
mov Red_Blink,eax


invoke CreatePopupMenu

mov    hPopupMenu,eax

invoke AppendMenu,hPopupMenu,MF_STRING,IDM_Dial,ADDR szDial_Out
invoke AppendMenu,hPopupMenu,MF_STRING,IDM_Hangup,ADDR szHangup
invoke AppendMenu,hPopupMenu,MF_STRING,IDM_EXIT,ADDR szExitString
                                   
            ; Send WM_SIZE which will place our app icon in system tray.
           
invoke SendMessage,hWin,WM_SIZE,SIZE_MINIMIZED,0

    .elseif uMsg == WM_COMMAND
           
            ; Handle the pop up menu options to Dial In or 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

                .elseif eax == IDM_Dial

; Let's dial in for dollars :-)
               
mov dwCb, sizeof RASENTRYNAME5
mov lpRasEntryName, 0

AllocateRasEntryNameLoop1:

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

AllocateRasEntryName1:
      invoke GetProcessHeap
      invoke HeapAlloc, eax, 0, dwCb
      cmp    eax, 0
      je     RetFail1
     
      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 AllocateRasEntryNameLoop1

      cmp eax, 0
      jne RetFail1

      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 RetFail1
      mov hConn, 0

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

RetFail1:

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

.elseif eax == IDM_Hangup

mov l_RASCONN.dwSize, sizeof RASCONN + 1
mov l_Buffer_Size, sizeof l_RASCONN

; list all active RAS connections
invoke RasEnumConnections, addr l_RASCONN, addr l_Buffer_Size, addr l_Conn_Count

; terminate the Remote Access Connection

invoke RasHangUp, l_RASCONN.hrasconn

invoke Sleep,1500 ; give the system enuf time to end the connection
                  ; don't want to leave the port in an inconsistent state.

               .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
           
            ; Destroy popup menu and shut down our app.
                     
            invoke DestroyMenu,hPopupMenu
            invoke PostQuitMessage,0

.ELSEIF uMsg == WM_TIMER

      call TimerProc

    .endif

    invoke DefWindowProc,hWin,uMsg,wParam,lParam
    ret

WndProc endp

TimerProc proc

    invoke PdhCollectQueryData, hQuery
    invoke PdhGetFormattedCounterValue,hCounter,PDH_FMT_LONG,0,ADDR pfc

    .IF pfc.CStatus == PDH_CSTATUS_VALID_DATA

        mov   eax, pfc.longValue

        .IF eax != prevValue

            mov prevValue, eax
            .IF eax
                m2m   nid.hIcon, hIconAct
            .ELSE
                m2m   nid.hIcon, hIconNoAct
            .ENDIF

            invoke Shell_NotifyIcon, NIM_MODIFY, ADDR nid

        .ENDIF

    .ENDIF

    ret

TimerProc endp

end start
Have a great day,
                         Andy

Tedd

You're stuck because you keep on ripping code and trying to mash it together into what you want without understanding what most of it even is. There's nothing wrong with looking at others' code to see how things are done, but don't confuse that with copying it verbatim.

I would recommend starting from scratch, adding one feature at a time, then make sure it works and you understand it. Then you can add the next thing. You may actually learn something along the way and not have so many problems.

Steps:
- Usual window template
- Add notification ('system tray') icon on start, remove on exit
- Create menu for right-click, and actions for items
- RAS Dialing functionality
- Create timer for switching icons on start of dial-up, swap icons in handler; kill timer on success/error, and update the icon
No snowflake in an avalanche feels responsible.

ragdog

Hi Magnum

Look at this source Another HDD Activity Monitor
http://www.masm32.com/board/index.php?topic=4316.0

Magnum

Hey Ragdog,

I looked at that code earlier.

It didn't blink during any disk activity, so I figured that it did not work properly.

Hdactmon.asm does work and that is what I am studying.

This is the area that I am having trouble with. uMsg == WM_COMMAND
Have a great day,
                         Andy

Magnum

I need help in understanding these 2 sections of code so
I can create a timer for switching icons.

I understand that the first is setting up a 1/10 second timer.


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

invoke SetTimer, hWnd, ID_TIMER, 100, NULL

  msgLoop:

    invoke GetMessage, ADDR msg, NULL, 0, 0
    .IF eax != 0
      invoke TranslateMessage, ADDR msg
      invoke DispatchMessage, ADDR msg
      jmp   msgLoop
    .ENDIF

    invoke PdhCloseQuery, hQuery
    invoke KillTimer, hWnd, ID_TIMER

    return msg.wParam

  fail:

    return 0

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

TimerProc proc

    invoke PdhCollectQueryData, hQuery
    invoke PdhGetFormattedCounterValue,hCounter,PDH_FMT_LONG,0,ADDR pfc

    .IF pfc.CStatus == PDH_CSTATUS_VALID_DATA

        mov   eax, pfc.longValue

        .IF eax != prevValue

            mov prevValue, eax
            .IF eax
                m2m   nid.hIcon, hIconAct
            .ELSE
                m2m   nid.hIcon, hIconNoAct
            .ENDIF

            invoke Shell_NotifyIcon, NIM_MODIFY, ADDR nid

        .ENDIF

    .ENDIF

    ret

TimerProc endp


Have a great day,
                         Andy

ragdog

Magnum,Magnum,Magnum ::)

Have you read by Msdn for what this is?


  invoke PdhCollectQueryData, hQuery
    invoke PdhGetFormattedCounterValue,hCounter,PDH_FMT_LONG,0,ADDR pfc

    .IF pfc.CStatus == PDH_CSTATUS_VALID_DATA


A blinking icon is very simply

Add to the resource (.rc) the icons

1.For standart icon
2.Green for if Connected
3.for blinking effect for if disconnected

Ok i have only copy paste  :bg


Magnum.rc

1000 ICON      DISCARDABLE "Res/RW.ico"
2000 ICON      DISCARDABLE "Res/read.ico"
3000 ICON      DISCARDABLE "Res/write.ico"
4000 ICON      DISCARDABLE "Res/NA.ico"



.data
note          NOTIFYICONDATA <>
hSwitchIcon db 0
.data?

l_RASCONN RASCONN 0FFh dup ({})
l_Buffer_Size dd   ?
l_Conn_Count  dd   ?
hIconNA           DWORD ?
hIconRead         DWORD ?
hIconWrite        DWORD ?
hIconRW           DWORD ?



   .if uMsg == WM_CREATE
           
            ; We will need a pop up menu
           invoke LoadImage,hInstance,1000,IMAGE_ICON,0,0,NULL
mov    hIconRW, eax
invoke LoadImage,hInstance,2000,IMAGE_ICON,0,0,NULL
      mov    hIconRead, eax
   invoke   LoadImage,hInstance,3000,IMAGE_ICON,0,0,NULL
      mov    hIconWrite,eax
invoke     LoadImage,hInstance,4000,IMAGE_ICON,0,0,NULL
      mov    hIconNA, eax

      mov note.cbSize,sizeof NOTIFYICONDATA
            push hWin
            pop note.hwnd
            mov note.uID,IDI_TASKBARICON
            mov note.uFlags,NIF_ICON+NIF_MESSAGE+NIF_TIP
            mov note.uCallbackMessage,WM_SHELLNOTIFY
            m2m    note.hIcon, hIconRead
 
            invoke lstrcpy,addr note.szTip,addr szApp
            invoke Shell_NotifyIcon,NIM_ADD,addr note




.elseif eax == IDM_Hangup

mov l_RASCONN.dwSize, sizeof RASCONN + 1
mov l_Buffer_Size, sizeof l_RASCONN

; list all active RAS connections
invoke RasEnumConnections, addr l_RASCONN, addr l_Buffer_Size, addr l_Conn_Count

; terminate the Remote Access Connection

invoke RasHangUp, l_RASCONN.hrasconn

invoke Sleep,1500 ; give the system enuf time to end the connection
                  ; don't want to leave the port in an inconsistent state.
invoke SetTimer, hWnd, ID_TIMER, 1000, NULL ;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< Set you timer for blinking



.ELSEIF uMsg == WM_TIMER

   .if hSwitchIcon==0
        m2m    note.hIcon, hIconRead
        mov hSwitchIcon,1
   .else
      m2m    note.hIcon,  hIconWrite
        mov hSwitchIcon,0
    .endif
    invoke Shell_NotifyIcon, NIM_MODIFY, ADDR note

    .endif

    invoke DefWindowProc,hWin,uMsg,wParam,lParam
    ret


Viola

A complete source is in Attach


Magnum

Thanks Ragdog,

I am trying to understand the logic of the blinking icons.

This code switches between 2 of the loaded icons, where do the other 2 icons come into play ?


.ELSEIF uMsg == WM_TIMER

   .if hSwitchIcon==0
        m2m    note.hIcon, hIconRead
        mov hSwitchIcon,1
   .else
      m2m    note.hIcon,  hIconWrite
        mov hSwitchIcon,0
    .endif
    invoke Shell_NotifyIcon, NIM_MODIFY, ADDR note

    .endif

    invoke DefWindowProc,hWin,uMsg,wParam,lParam
    ret


I have 4 icons I made.

Can I just use the red and green icons ?
And use the green one for the program icon.

Do my icons not work because of their size?

I have attached the icons I made.

I tried all these combinations using 4 icons, but none worked.

;1000 ICON "white_fone.ico"
;2000 ICON "red_fone.ico"
;3000 ICON "green_fone.ico"
;4000 ICON "blank.ico"

;1000 ICON "white_fone.ico"
;2000 ICON "green_fone.ico"
;3000 ICON "red_fone.ico"
;4000 ICON "blank.ico"

; 1000 is the starting icon
;1000 ICON "green_fone.ico"
;2000 ICON "red_fone.ico"
;3000 ICON "white_fone.ico"
;4000 ICON "blank.ico"

;1000 ICON "red_fone.ico"
;2000 ICON "green_fone.ico"
;3000 ICON "white_fone.ico"
;4000 ICON "blank.ico"

;1000 ICON "blank.ico"
;2000 ICON "green_fone.ico"
;3000 ICON "red_fone.ico"
;4000 ICON "white_fone.ico"

;1000 ICON "green_fone.ico"
;2000 ICON "white_fone.ico"
;3000 ICON "blank.ico"
;4000 ICON "red_fone.ico"

1000 ICON "white_fone.ico"
2000 ICON "blank.ico"
3000 ICON "red_fone.ico"
4000 ICON "green.ico"


Have a great day,
                         Andy

Magnum

Not trying to be picky.

I noticed there is no SetTimer in the code you posted.


Identifies the window associated with the specified timer. This value must be the same as the hWnd value passed to the SetTimer function that created the timer.



Can you use the KillTimer without it ?

It doesn't blink while it is trying to connect.


Have a great day,
                         Andy

Magnum

My mistake, I did find the SetTimer.
Have a great day,
                         Andy

ragdog

Hi Magnum


QuoteThis code switches between 2 of the loaded icons, where do the other 2 icons come into play ?


I have only send an example and have modify you code for blinking 2 icons

QuoteI noticed there is no SetTimer in the code you posted.

I have use SetTimer look in your code


                  ; don't want to leave the port in an inconsistent state.
invoke SetTimer, hWnd, ID_TIMER, 1000, NULL
               .endif
            .endif

    .elseif uMsg == WM_SHELLNOTIFY



QuoteCan you use the KillTimer without it ?

It doesn't blink while it is trying to connect.

You must use KillTimer

Remove in the code "invoke KIllTimer ....."
and write it here in this line

      invoke RasDial, NULL, NULL, ADDR rp, 0, NULL, ADDR hConn
      cmp eax, 0
      jne RetFail1
      invoke PlaySound,ADDR Sound,NULL,SND_SYNC
       invoke KillTimer, hWnd, ID_TIMER ;<<<<<<<<<<<<<<<<<<<<<<<<<<<


Magnum

I tried that already.

Blinks when connected, but continues to blink when disconnected ?

Have a great day,
                         Andy

ragdog

No Magnum i think your have what wrong

I have test it it blinks if disconnected and by conected blinks not
I have for test remove the dial code

   .elseif eax == IDM_Dial

                        ;Your code for Dial
                        ;
                        ;
                        invoke PlaySound,ADDR Sound,NULL,SND_SYNC
                        invoke KillTimer, hWnd, ID_TIMER ;<<<<<<<<<<<<<<<<<< Kill the Blink icon timer

                .elseif eax == IDM_Hangup

                        ;Your code for disconnect
                        ;
                        ;
                        invoke SetTimer, hWnd, ID_TIMER, 1000, NULL  ;<<<<<<<<<<<<<<<<<<set the Blink icon timer
             .endif

Magnum

I made your changes.

You can see what happens.

Have a great day,
                         Andy

ragdog

QuoteYou can see what happens.

It blinks if disconnect and blinks not if connected

That happens

But you must change this


      invoke PlaySound,ADDR Sound,NULL,SND_SYNC
      invoke KillTimer, hWnd, ID_TIMER ;<<<<<<<<<<<<<<<<<< Kill the Blink icon timer
   .if hSwitchIcon==0
         m2m    note.hIcon, hIconGreen   ; Green icon
       invoke Shell_NotifyIcon, NIM_MODIFY, ADDR note

   .endif


Why? if current selected icon red by KillTimer make this green by Connecting

But it works