The MASM Forum Archive 2004 to 2012

General Forums => The Workshop => Topic started by: jj2007 on September 12, 2011, 02:41:51 PM

Title: SetTimer callback problem
Post by: jj2007 on September 12, 2011, 02:41:51 PM
I use invoke SetTimer, hWnd, MyID, 1000, CbTimer in a Win GUI app, mostly successfully.

The problem is that I discovered events in CbTimer that shouldn't be there. My IDs are all in the -100 ... -127 range, but I get events like e.g. +31546 ... and different, decreasing, numbers for each app run, as if a global system-wide counter was involved.

Any ideas who could play foul here? The app is too large to post here, and I can't reproduce it with a simpler window. All SetTimer invokes look fine.

CbTimer proc hwnd:DWORD, uMsg:DWORD, PMidEvent:DWORD, dwTime:DWORD
LOCAL gpCbT, hEdit, hOK, hCancel, rc:RECT, rcp:RECT, wpf:WINDOWPLACEMENT
LOCAL txrg:TEXTRANGE
LOCAL chrg:CHARRANGE
LOCAL LocBuf[MAX_PATH*2]:BYTE
  pushad ; save all - we are inside a timer...
  mov ebx, PMidEvent
  .if sdword ptr ebx>0
MsgBox 0, str$(ebx), 0, MB_OK
  .endif
...
  popad
ret
CbTimer endp


Among the 14 SetTimer calls, the marked one seems responsible, with TimerActivate = -120 (but same result for other values):

CASE WM_ACTIVATE
.if ActFlag==0
invoke SetTimer, hWnd, TimerActivate, 200, CbTimer  ; <<<< the culprit
invoke SetTimer, hWnd, TimerPipeClose, 20, CbTimer
.endif


SetTimer happens once, and the problem starts directly after.
Title: Re: SetTimer callback problem
Post by: dedndave on September 12, 2011, 03:27:14 PM
the Community Content section for TimerProc Callback may be of interest

http://msdn.microsoft.com/en-us/library/ms644907%28v=VS.85%29.aspx

is there some reason for not filtering them out ?
Title: Re: SetTimer callback problem
Post by: jj2007 on September 12, 2011, 03:56:19 PM
Quote from: dedndave on September 12, 2011, 03:27:14 PM
the Community Content section for TimerProc Callback may be of interest

http://msdn.microsoft.com/en-us/library/ms644907%28v=VS.85%29.aspx

is there some reason for not filtering them out ?

The error handling issue is interesting, but it seems not to be the problem, as I get the wrong ID right on top of the CB. And yes I could filter them out, but it appears that the right ID is not working either. Very strange...
Title: Re: SetTimer callback problem
Post by: MichaelW on September 12, 2011, 03:57:03 PM
The third parameter is the timer ID as a 32 or 64-bit unsigned integer, not a pointer. The UINT_PTR is specified to ensure that the size will match the size of a pointer.

http://msdn.microsoft.com/en-us/library/aa383751(v=VS.85).aspx#UINT_PTR

From BaseTsd.h:

// The INT_PTR is guaranteed to be the same size as a pointer.  Its
// size with change with pointer size (32/64).  It should be used
// anywhere that a pointer is cast to an integer type. UINT_PTR is
// the unsigned variation.

Title: Re: SetTimer callback problem
Post by: dedndave on September 12, 2011, 04:11:12 PM
maybe use smaller (positive) ID's   :P
Title: Re: SetTimer callback problem
Post by: jj2007 on September 12, 2011, 06:00:47 PM
The IDs are defined as DWORD, so that could not be the problem...

But I found it: The bloody WM_ACTIVATE message is triggered the first time with a zero handle!!
So invoke SetTimer, hWnd, MyID, 200, CbTimer was in reality invoke SetTimer, 0, MyID, 200, CbTimer... and that explains the "global" countdown.

Thanks, Michael and Dave :thumbu

Anyway, I learnt something important:
Quote; Create the main application window
   invoke CreateWindowEx, ....
   mov hWnd, eax  ; set global handle

QuoteWndProc proc hWin:DWORD, uMsg:DWORD, wParam:DWORD, lParam:DWORD
...
   SWITCH uMsg
   CASE WM_CREATE
      m2m hWnd, hWin      ; global window handle must be set here, not in WinMain

:bg
Title: Re: SetTimer callback problem
Post by: dedndave on September 12, 2011, 09:55:16 PM
i have been doing that for most windows
it seems to be the earliest time that the window handle is known
but, i was doing it so i knew WM_CREATE had executed - lol
Title: Re: SetTimer callback problem
Post by: qWord on September 12, 2011, 10:02:31 PM
Quote from: jj2007 on September 12, 2011, 06:00:47 PMAnyway, I learnt something important:
QuoteWndProc proc hWin:DWORD, uMsg:DWORD, wParam:DWORD, lParam:DWORD
...
      m2m hWnd, hWin      ; global window handle must be set here, not in WinMain
or better:
Quoteinvoke SetTimer, hWin, MyID, 200, CbTimer
:bg
Title: Re: SetTimer callback problem
Post by: jj2007 on September 12, 2011, 10:10:30 PM
Quote from: qWord on September 12, 2011, 10:02:31 PM
or better:
Quoteinvoke SetTimer, hWin, MyID, 200, CbTimer
:bg

Or even shorter:
SetMyTimerP proc TheID, TheDelay
  invoke SetTimer, hWnd, TheID, TheDelay, CbTimer
  ret
SetMyTimerP endp

With a WndProc of already 1,000 lines and 14 timers, it is convenient to have an extra proc that handles both WndProc and non-WndProc calls. But for a smaller app, your idea is absolutely right, of course :U