From: Karl E. Peterson on
on 6/30/2010, Bob Butler supposed :
> "Karl E. Peterson" <karl(a)exmvps.org> wrote...
>> Brain freeze here, I guess.
>>
>> I need a simple one-shot timer (non form-based). I was thinking, just use
>> SetTimer, then call KillTimer in the callback. But, KillTimer fails in the
>> callback. LastDllError=0.
>
> works for me;

You made me re-examine a few things, including where I was calling
KillTimer. I had been syncing the callback in a BAS module, then
redirecting to a class, and doing a few other things as well. Anyway,
it turned out I was using the wrong handle in the first parameter.
<groan> It's working now! :-)

Thanks... Karl

--
..NET: It's About Trust!
http://vfred.mvps.org


From: Karl E. Peterson on
Nobody wrote :
> You probably didn't use the return value of SetTimer, but I could be
> mistaken. Here is an example to try. Post the code in Module1, and remove
> Form1 from a new project.

Appreciated! I did get it working, and you're *almost* right. I was
using the wrong window handle. (I had to use an hWnd, even though I
was using TimerProc, because of the complicated plumbing going on. I
need to pass an ObjPtr to the callback using that second parameter.)

Thanks... Karl

--
..NET: It's About Trust!
http://vfred.mvps.org


From: Nobody on
"Karl E. Peterson" <karl(a)exmvps.org> wrote in message
news:i0gc5o$61i$1(a)news.eternal-september.org...
> Yeah, but what I got going is already complex enough, that more flags
> would just really make it all quite bizarre. And, I will want to reuse
> the timer for a later one-shot. I could just leave it running, but
> ideally it oughta be a very short interval on (at least) the first
> callback.

Another idea is to use PostMessage to post a custom message(like WM_APP+1)
to Form1 to process the delayed task, but this requires a form or control
and subclassing, but the delay is as small as it gets. I have done both
methods in the past.

Also, to keep the code neat, you may want to use Enum to tell the TimerProc
what to do. Example:

Public Enum enumTimerWhatToDo
enumTimerDoTask1
enumTimerDoTask2
enumTimerDoTask3
End Enum
Public TimerWhatToDo As enumTimerWhatToDo

' Returns True when successful, False when busy
Public Function StartDelayedTask(ByVal WhatToDo As enumTimerWhatToDo) As
Boolean
If TimerID = 0 Then
TimerWhatToDo = WhatToDo
TimerID = SetTimer(0, 0, 10, AddressOf TimerProc)
StartDelayedTask = True ' Success
End If
End Function

Public Sub TimerProc(ByVal hwnd As Long, ByVal uMsg As Long, _
ByVal idEvent As Long, ByVal dwTime As Long)

KillTimer 0, TimerID
TimerID = 0 ' Done.
End Sub


From: Karl E. Peterson on
Nobody submitted this idea :
> "Karl E. Peterson" <karl(a)exmvps.org> wrote...
>> Yeah, but what I got going is already complex enough, that more flags would
>> just really make it all quite bizarre. And, I will want to reuse the timer
>> for a later one-shot. I could just leave it running, but ideally it oughta
>> be a very short interval on (at least) the first callback.
>
> Another idea is to use PostMessage to post a custom message(like WM_APP+1) to
> Form1 to process the delayed task, but this requires a form or control and
> subclassing, but the delay is as small as it gets.

Not a bad thought, actually. I'd had it myself. The hook is there,
but not yet set at the time I need to go async. Rather, the hook is
set in reaction to the callback. Hence the dilemma.

> Also, to keep the code neat, you may want to use Enum to tell the TimerProc
> what to do. Example:
>
> Public Enum enumTimerWhatToDo
> enumTimerDoTask1
> enumTimerDoTask2
> enumTimerDoTask3
> End Enum
> Public TimerWhatToDo As enumTimerWhatToDo
>
> ' Returns True when successful, False when busy
> Public Function StartDelayedTask(ByVal WhatToDo As enumTimerWhatToDo) As
> Boolean
> If TimerID = 0 Then
> TimerWhatToDo = WhatToDo
> TimerID = SetTimer(0, 0, 10, AddressOf TimerProc)
> StartDelayedTask = True ' Success
> End If
> End Function
>
> Public Sub TimerProc(ByVal hwnd As Long, ByVal uMsg As Long, _
> ByVal idEvent As Long, ByVal dwTime As Long)
>
> KillTimer 0, TimerID
> TimerID = 0 ' Done.
> End Sub

Just to throw all that into a twist, the callback needs to be routed
into a class. So I'm using the idEvent parameter to pass ObjPtr(Me) to
the TimerProc, where it can be automagically reconstituted as the
appropriate object and it's callback method can then be called.

At any rate, I got it going now! :-)

--
..NET: It's About Trust!
http://vfred.mvps.org


From: Bob Butler on

"Karl E. Peterson" <karl(a)exmvps.org> wrote in message
news:i0gcnp$a4v$1(a)news.eternal-september.org...
> on 6/30/2010, Bob Butler supposed :
>> "Karl E. Peterson" <karl(a)exmvps.org> wrote...
>>> Brain freeze here, I guess.
>>>
>>> I need a simple one-shot timer (non form-based). I was thinking, just
>>> use SetTimer, then call KillTimer in the callback. But, KillTimer fails
>>> in the callback. LastDllError=0.
>>
>> works for me;
>
> You made me re-examine a few things, including where I was calling
> KillTimer. I had been syncing the callback in a BAS module, then
> redirecting to a class, and doing a few other things as well. Anyway, it
> turned out I was using the wrong handle in the first parameter. <groan>
> It's working now! :-)
>
> Thanks... Karl

Me 1
Karl 49531