設置 SetTimer(hwnd, 1, 100, NULL),在 WM_TIMER case 下打斷點,調試器從未命中。
GetMessage/DispatchMessage 循環卡住,定時器消息無法分發。#include <windows.h>
#define ID_TIMER 1
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp) {
switch (msg) {
case WM_CREATE:
SetTimer(hwnd, ID_TIMER, 1000, NULL); // 建議 1s 觀察
return 0;
case WM_TIMER:
// 僅做輕量操作,如 InvalidateRect 觸發重繪
InvalidateRect(hwnd, NULL, FALSE);
return 0;
case WM_PAINT: {
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hwnd, &ps);
SYSTEMTIME st; GetLocalTime(&st);
TCHAR buf[64];
wsprintf(buf, TEXT("%02d:%02d:%02d"), st.wHour, st.wMinute, st.wSecond);
TextOut(hdc, 10, 10, buf, lstrlen(buf));
EndPaint(hwnd, &ps);
return 0;
}
case WM_DESTROY:
KillTimer(hwnd, ID_TIMER);
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hwnd, msg, wp, lp);
}
int WINAPI WinMain(HINSTANCE hInst, HINSTANCE, LPSTR, int nCmdShow) {
WNDCLASS wc = {CS_HREDRAW|CS_VREDRAW, WndProc, 0,0, hInst,
LoadIcon(NULL,IDI_APPLICATION), LoadCursor(NULL,IDC_ARROW),
(HBRUSH)(COLOR_WINDOW+1), NULL, TEXT("TimerDemo")};
RegisterClass(&wc);
HWND hwnd = CreateWindow(TEXT("TimerDemo"), TEXT("Timer"), WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, 300, 200, NULL, NULL, hInst, NULL);
ShowWindow(hwnd, nCmdShow);
MSG msg;
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
WM_TIMER 僅設置標誌位或 InvalidateRect,耗時操作放入工作線程。OutputDebugString 替代斷點輸出調試信息,避免調試器干擾消息泵。