The MASM Forum

General => The Workshop => Topic started by: caseys on February 27, 2013, 05:45:23 PM

Title: SetTimer question
Post by: caseys on February 27, 2013, 05:45:23 PM
hello. how can i call settimer function on non dialog based application? normally i was doing like this:


...

    .if uMsg == WM_INITDIALOG
        invoke  SetTimer, hWin, ID_TIMER1, 500, NULL

...

      .elseif uMsg==WM_TIMER
        mov     eax, wParam
        .if     eax==ID_TIMER1
invoke MessageBox, NULL,addr MsgBoxText, addr MsgCaption, MB_OK
invoke ExitProcess,NULL
        .endif
    .endif
...


thanks
Title: Re: SetTimer question
Post by: jj2007 on February 27, 2013, 06:56:54 PM
WM_CREATE instead if WM_INITDIALOG, that's all. Besides, a callback function is often a better choice:

.if uMsg==WM_CREATE
  invoke SetTimer, hWnd, id, ms, CbTimer
...

CbTimer proc hwnd:DWORD, uMsg:DWORD, PMidEvent:DWORD, dwTime:DWORD
... react...

P.S.: Welcome to the forum :icon14:
Title: Re: SetTimer question
Post by: caseys on February 27, 2013, 07:08:23 PM
nice. thanks! i thought it's the same forum as masmforum.com/board couse i was there all the time but i can't post anymore. seems closed or something
Title: Re: SetTimer question
Post by: caseys on February 27, 2013, 08:02:13 PM
but still, i can't get it to work on non dialog/form based application. can someone post an example here? thanks
Title: Re: SetTimer question
Post by: MichaelW on February 27, 2013, 10:59:32 PM
For the timer created by SetTimer to work, the calling thread must dispatch messages. This is a quick and dirty demo of one possible method that will work for a console app.

;==============================================================================
    include \masm32\include\masm32rt.inc
    include \masm32\include\winmm.inc
    includelib \masm32\lib\winmm.lib
;==============================================================================
    .data
        hTimerQueue HANDLE  0
        phNewTimer  PHANDLE 0
        param       dd      123
    .code
;==============================================================================

TimerProc proc lpParam:PVOID, TimerOrWaitFired:DWORD
    ;mov eax, lpParam
    ;mov eax, [eax]
    ;printf("%d\n", eax)
    invoke GetTickCount
    printf("%d\n", eax)
    ret
TimerProc endp

;==============================================================================
start:
;==============================================================================

    invoke Sleep, 3000

    invoke CreateTimerQueue
    mov hTimerQueue, eax
    .IF eax == 0
        printf("CreateTimerQueue error %s\n",LastError$())
        inkey
    .ENDIF

    ;-----------------------------------------------------------------------
    ; For a timer period less than 10 or 15.625ms, depending on the system,
    ; use timeBeginPeriod to set an appropriate minimum timer resolution.
    ;-----------------------------------------------------------------------

    ;invoke timeBeginPeriod, 1

    ;------------------------------------
    ; Create a timer with a 50ms period.
    ;------------------------------------

    invoke CreateTimerQueueTimer, ADDR phNewTimer, hTimerQueue,
                                  TimerProc, ADDR param,
                                  1, 50, WT_EXECUTEINTIMERTHREAD
    .IF eax == 0
        printf("CreateTimerQueueTimer error %s\n",LastError$())
        inkey
    .ENDIF

    ;----------------------------------------------------
    ; The prompt here will be scrolled off the screen as
    ; the timer procedure displays the tick count.
    ;----------------------------------------------------

    inkey ".",13,10

    ;-------------------------------------------------------------------
    ; The period for this call needs to match that for timeBeginPeriod.
    ;-------------------------------------------------------------------

    ;invoke timeEndPeriod, 1

    invoke DeleteTimerQueueTimer, hTimerQueue, phNewTimer, NULL
    .IF eax == 0
        printf("DeleteTimerQueueTimer error %s\n",LastError$())
    .ENDIF

    invoke DeleteTimerQueueEx, hTimerQueue, INVALID_HANDLE_VALUE
    .IF eax == 0
        printf("DeleteTimerQueueEx error %s\n",LastError$())
    .ENDIF

    inkey

    exit

;==============================================================================
end start

Title: Re: SetTimer question
Post by: jj2007 on February 27, 2013, 11:47:07 PM
Console assembly and link:

include \masm32\include\masm32rt.inc
.code
CbTimer proc hwnd:DWORD, uMsg:DWORD, PMidEvent:DWORD, dwTime:DWORD
  print "*"
  ret
CbTimer endp
start:
   invoke SetTimer, 0, 123, 50, CbTimer
   MsgBox 0, "Ciao", "Hi", MB_OK
   exit
end start
Title: Re: SetTimer question
Post by: dedndave on February 28, 2013, 12:06:27 AM
it is the same forum - just a new version of it
the old one is still partially available for reference
Title: Re: SetTimer question
Post by: caseys on February 28, 2013, 12:16:29 AM
nice. thanks for all the answers. i'm glad this community is still up and running! here's final working win32 sample:


.386
.model flat, stdcall
option casemap:none

include C:\masm32\include\windows.inc
include C:\masm32\include\kernel32.inc
includelib C:\masm32\lib\kernel32.lib
include C:\masm32\include\user32.inc
includelib C:\masm32\lib\user32.lib

.data
MsgCaption      db "TITLE", 0
MsgBoxText      db "MESSAGE", 0
.code

start:
CbTimer proc hwnd:DWORD, uMsg:DWORD, PMidEvent:DWORD, dwTime:DWORD
invoke SetTimer, 0, 220, 3000, CbTimer
invoke MessageBox, 0, addr MsgBoxText, addr MsgCaption, MB_OK
invoke KillTimer, 0, 220
invoke ExitProcess, 0
CbTimer endp
end start



Title: Re: SetTimer question
Post by: MichaelW on February 28, 2013, 06:51:53 AM
I was assuming that the goal was to use a timer in some sort of working console app where the app has complete control of the timer and can do things like accept user input, without disturbing the timer.
Title: Re: SetTimer question
Post by: caseys on February 28, 2013, 09:07:44 PM
it was, it's just an another example for new masm members.