如何使用SendMessage函数来发送具有定时器PROC在Win32 WM_TIMER(How d

2019-09-26 04:45发布

我有一个计时器,ID 1,其具有的TimerProc作为回调函数。

我在做其他的定时器(ID 2,3,...)中的TimerProc和他们使用WM_TIMER事件,而不是其他的TimerProc。

当创建窗口,我想立刻产生计时器事件,ID 1。

所以我用SendMessage函数一样,

SendMessage(hWnd, WM_TIMER, 1, (LPARAM)&timerproc);

但没有奏效。

如何激活的TimerProc在右侧窗口中的第一次?

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);
    }

Answer 1:

当创建窗口,我想立刻产生计时器事件,ID 1.所以我用SendMessage函数一样,

 SendMessage(hWnd, WM_TIMER, 1, (LPARAM)&timerproc); 

但没有奏效。

回调得到由仅在定时器信号拥有线程的消息队列,以产生一个定时器称为WM_TIMER消息,然后由检索的(Peek|Get)Message()并传递到DispatchMessage()由线程的消息循环。 这是DispatchMessage()调用如果指派计时器回调,否则它提供了WM_TIMER消息给窗口的WndProc:

如果lpmsg参数指向一个WM_TIMER消息和lParam所述的参数WM_TIMER消息不是NULLlParam指向一个函数被调用,而不是窗口过程。

使用SendMessage()绕过窗口的消息队列和直接到窗口的WndProc。 这就是为什么你没有看到计时器回调得到调用。

所以,在最起码,你将不得不使用PostMessage()而不是SendMessage()使您的手工WM_TIMER消息可以去通过这个窗口的消息队列,并达到DispatchMessage()

PostMessage(hWnd, WM_TIMER, 1, (LPARAM)&timerproc);

否则,你就必须调用DispatchMessage()直接用假MSG你自己:

MSG msg = {};
msg.hwnd = hWnd;
msg.message = WM_TIMER;
msg.wParam = 1;
msg.lParam = (LPARAM) &timerproc;
msg.time = GetTickCount();
GetCursorPos(&msg.pt);
DispatchMessage(&msg);

然而,这实际上不是必要的,因为......

如何激活的TimerProc在右侧窗口中的第一次?

回调是一个函数,所以只是把它直接,就像任何其他的功能:

//SendMessage(hWnd, WM_TIMER, 1, (LPARAM)&MakeRain);
MakeRain(hWnd, WM_TIMER, 1, GetTickCount());


文章来源: How do I use sendmessage for sending wm_timer that has timer proc in win32