KillTimer 不删除给定的计时器

问题描述 投票:0回答:1

我写了一段代码来了解SetTimer和KillTimer。 我首先在WM_CREATE中设置一个定时器,然后在定时器中写入KillTimer 回调函数,这样计时器只会被调用一次。

我在定时器回调函数中放了一个MessageBox,这样 将弹出一个消息框以指示计时器已被调用。 由于计时器,消息框预计只会弹出一次 MessageBox 调用后将立即被 KillTimer 关闭。

但是,程序没有按预期运行。看来 KillTimer 没有按照指示停止计时器。相反,该程序 不断弹出消息框。

以下是代码:

#include <stdio.h>
#include <windows.h>

VOID CALLBACK timer_proc(HWND hwnd, UINT msg, UINT timer_id, DWORD time)
{
        char buf[1024];
        sprintf(buf, "TIMER PROC CALLED AT %d, ID %d", time, timer_id);
        MessageBoxA(hwnd, buf, "MSGBOX", MB_ICONINFORMATION);
        KillTimer(hwnd, timer_id);
}

void wm_paint(HWND hwnd)
{
        PAINTSTRUCT ps;
        HDC hdc = BeginPaint(hwnd, &ps);
        TextOutA(hdc, 20, 20, "Hi?", 3);
        EndPaint(hwnd, &ps);
}

LRESULT CALLBACK wndproc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp)
{
        switch (msg) {
        case WM_CREATE:
                SetTimer(hwnd, 1, 500, timer_proc);
                return 0;
        case WM_PAINT: wm_paint(hwnd); return 0;
        case WM_SIZE: return 0;
        case WM_DESTROY: PostQuitMessage(0); return 0;
        default: return DefWindowProc(hwnd, msg, wp, lp);
        }
}

void init_wndclass(WNDCLASS *w, HINSTANCE hinstance, char *class_name)
{
        w->style = CS_HREDRAW | CS_VREDRAW;
        w->lpfnWndProc = wndproc;
        w->cbClsExtra = w->cbWndExtra = 0;
        w->hInstance = hinstance;
        w->hIcon = LoadIcon(NULL, IDI_APPLICATION);
        w->hCursor = LoadCursor(NULL, IDC_ARROW);
        w->hbrBackground = GetStockObject(WHITE_BRUSH);
        w->lpszMenuName = NULL;
        w->lpszClassName = class_name;
}

HWND create_window(HINSTANCE hinstance)
{
        WNDCLASS wndclass;
        char *class_name = "main window class";
        init_wndclass(&wndclass, hinstance, class_name);
        RegisterClass(&wndclass);
        return CreateWindowA(class_name, "TIMER TEST", WS_OVERLAPPEDWINDOW,
                        CW_USEDEFAULT, CW_USEDEFAULT, // position
                        CW_USEDEFAULT, CW_USEDEFAULT, // window size
                        NULL, /* owner window */ NULL, /* menu */
                        hinstance, NULL /* window-creation data */);
}

int WINAPI WinMain(HINSTANCE hinstance, HINSTANCE prev, PSTR cmdline,
                   int cmdshow)
{
        HWND hwnd = create_window(hinstance);
        ShowWindow(hwnd, cmdshow);
        UpdateWindow(hwnd);

        MSG msg;
        while (GetMessage(&msg, NULL, 0, 0))
        {
                TranslateMessage(&msg);
                DispatchMessage(&msg);
        }
}
c windows winapi
1个回答
0
投票

MessageBox()
运行自己的内部消息循环。在您关闭其对话框之前,它将继续为调用线程接收和分派窗口消息,包括计时器消息。您需要使用不同的方法向用户报告计时器事件。例如在 UI 上显示文本,或使用
OutputDebugString()
登录到调试器或 DebugView 应用程序等。

© www.soinside.com 2019 - 2024. All rights reserved.