Having problems getting a clock to run. The clock starts and stops. If I sit and click on the window, it will continue to run as if the message loop is shutting down and needs a trigger. Here is the excerpts from the code and thanks...

In the message loop:
.while TRUE

invoke WaitForSingleObject,hTimer,500
invoke DisplayTimeProc

invoke GetMessage,addr msg,NULL,0,0
  .BREAK .if !eax
invoke TranslateMessage,addr msg
invoke DispatchMessage,addr msg
.endw

In WndProc:
.if uMsg==WM_INITDIALOG
mov hSTC_TIMER,rv(GetDlgItem,hWin,STC_TIMER)
mov hTimer,rv(CreateWaitableTimer,NULL,FALSE,NULL)
invoke SetWaitableTimer,hTimer,0,500,NULL,NULL,0

The clock:

DisplayTimeProc proc
LOCAL systime:SYSTEMTIME
LOCAL pBuf :DWORD
invoke GetSystemTime,addr systime
mov pBuf,ptr$(buffer)
movzx eax, systime.wDayOfWeek
mov ebx,4
mul ebx
mov wDayOfWeek,cat$(pBuf,arrayDayOfWeek,SADD(13,10))
movzx eax, systime.wMonth
mov ebx,4
mul ebx
mov wMonth,cat$(wDayOfWeek,arrayMonth," ")
movzx eax, systime.wDay
mov wDay,cat$(wMonth,sstr$(eax),",")
movzx eax, systime.wYear
mov wYear,cat$(wDay,sstr$(eax),SADD(13,10))
movzx eax, systime.wHour
mov wHour,cat$(wYear,sstr$(eax),":")
movzx eax, systime.wMinute
mov wMin,cat$(wHour,sstr$(eax),":")
movzx eax, systime.wSecond
mov wSec,cat$(wMin,sstr$(eax),":")
movzx eax, systime.wMilliseconds
mov wMSec,cat$(wSec,sstr$(eax))
invoke SetWindowText,hSTC_TIMER,pBuf
; invoke MessageBox,0,pBuf,0,MB_OK
xor eax,eax
ret
DisplayTimeProc endp
Posted on 2009-03-21 17:52:21 by green
OffTopic sorry...

What's cat$ and sstr$() ? Looks useful but totally escapes me.
Posted on 2009-03-21 19:02:22 by JimmyClif
cat$ is a part of MASM32 Macro High Level Reference. Here is the prototype:

cat$: mov lpbuffer, cat$(lpBuffer,)

sstr$ is Preprocessor code for high level language simulation in MASM32. macros.asm that comes with MASM32. Here is the macro:
      sstr$ MACRO DDvalue   ;; signed integer from string
        LOCAL rvstring
        .data
          rvstring db 20 dup (0)
        align 4
        .code
        invoke dwtoa,DDvalue,ADDR rvstring
        ;; invoke ltoa,DDvalue,ADDR rvstring
        EXITM <OFFSET rvstring>
      ENDM

Another thing that I have found out is the GetSystemTime is a 24 hour clock and at 20 (8:00 PM) hours, it dumps the first digit. I changed the PC clock to 9:00 PM and the first digit was still missing. Changed to GetLocalTime to get the hours to work.
Posted on 2009-03-21 19:36:00 by green
Putting a delay in your messageloop isn't such a good idea, since it will slow down processing of your messages. Also, because you're setting up the timer object in your WM_INITDIALOG handler, but you're using it before it's initialized which is bad.

For a simple clock, I'd suggest you use SetTimer() and process WM_TIMER messages (or use a callback - just keep in mind that even with callbacks, SetTimer() still requires a message loop).

If you insist on using waitable timers, create a background thread that does the waiting, and calls RedrawWindow() on your main HWND - it's then up to the WM_PAINT to, well, paint your clock :)
Posted on 2009-03-22 05:21:12 by f0dder
Thanks f0dder. Not totally familiar with this threading stuff, but I did use SetTimer for the clock and it worked well.
Posted on 2009-03-22 05:30:14 by green

Thanks f0dder. Not totally familiar with this threading stuff, but I did use SetTimer for the clock and it worked well.
Threading would be overkill for this, I only mentioned it for completeness' sake :)

SetTimer() is indeed the sensible thing to use when you don't need super-tight timing - it's simple and efficient, and accuracy should be OK as long as you don't need millisecond accuracy.
Posted on 2009-03-22 05:36:39 by f0dder