I have a timer, ID 1, which has a timerproc as a callback function.
I am making the other timers (ID 2, 3, ...) in the timerproc and they use WM_TIMER
event, not another timerproc.
When creating window, I want to immediately generate Timer Event, ID 1.
So I used SendMessage function like that
SendMessage(hWnd, WM_TIMER, 1, (LPARAM)&timerproc);
but it didn't work.
How do I activate timerproc at right that the first time of window?
void CALLBACK MakeRain(HWND hWnd, UINT iMessage, UINT_PTR wParam, DWORD lParam)
{ /* this is timerproc for ID 1 */
if (gRdx >= MAX_WORDS_COUNT) return;
gRain[gRdx].f = 1;
gRain[gRdx].x = rand() % (gRect.right - 30);
gRain[gRdx].y = 10;
int id = RdxToTID(gRdx);
int vel = rand() % 2000 + 1000;
SetTimer(hWnd, id, vel, NULL); /* In here I am making other timers */
gRdx++;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam)
{
HDC hdc;
PAINTSTRUCT ps;
int tid = wParam;
int rdx = TIDToRdx(tid);
switch (iMessage)
{
case WM_CREATE:
GetClientRect(hWnd, &gRect);
srand((unsigned int)time(NULL));
SetTimer(hWnd, 1, MAKE_RAIN_TERM, MakeRain);
/* my trying, It is not working */
//SendMessage(hWnd, WM_TIMER, 1, (LPARAM)&MakeRain);
return 0;
case WM_TIMER:
gRain[rdx].y += 10;
if (gRain[rdx].y >= gRect.bottom) {
gRain[rdx].f = 0;
KillTimer(hWnd, tid);
}
InvalidateRect(hWnd, NULL, TRUE);
return 0;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
for (int i = 0; i < MAX_WORDS_COUNT; i++) {
if (gRain[i].f == 0) continue;
TextOut(hdc, gRain[i].x, gRain[i].y, words[i], lstrlen(words[i]));
}
EndPaint(hWnd, &ps);
return 0;
case WM_DESTROY:
KillTimer(hWnd, 1);
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hWnd, iMessage, wParam, lParam);
}
The callback gets called by the timer only when the timer signals the owning thread's message queue to generate a
WM_TIMER
message, which is then retrieved by(Peek|Get)Message()
and passed toDispatchMessage()
by the thread's message loop. It isDispatchMessage()
that calls the timer callback if one is assigned, otherwise it delivers theWM_TIMER
message to the window's WndProc:Using
SendMessage()
bypasses the window's message queue and goes directly to the window's WndProc. That is why you are not seeing the timer callback getting called.So, at the very least, you would have to use
PostMessage()
instead ofSendMessage()
so that your manualWM_TIMER
message can go through the window's message queue and reachDispatchMessage()
:Otherwise, you would have to call
DispatchMessage()
directly with a fakeMSG
of your own:However, that is not actually necessary, because...
The callback is a function, so just call it directly, like any other function: