我在非常简单的程序中工作,动画形状运动。可以使用鼠标右键将动画切换到开/关模式。我正在窗口过程中创建计时器并等待WM_TIMER事件。但是在创建计时器(SetTimer的返回值为1)后,WM_TIMER情况永远不会到达(我在下一行设置断点来检测它)。 我的窗口程序:
fn CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) -> LRESULT {
PAINTSTRUCT ps;
RECT win;
GetClientRect(hWnd, &win);
int w = win.right - win.left;
int h = win.bottom - win.top;
static COLORREF shape_color = RGB(0, 255, 255);
static int x = 50, y = 50;
static int r = 40;
int step = 50;
static bool animation = false;
switch (message) {
case WM_LBUTTONDOWN:
GetColorDlg(hWnd, shape_color);
break;
case WM_RBUTTONDOWN:
animation = !animation;
if (animation) {
timer_id = SetTimer(hWnd, 1, 500, NULL);
}
else {
KillTimer(hWnd, timer_id);
}
break;
case WM_TIMER:
++x_offset;
y_offset = sin(x_offset) * 20;
case WM_KEYDOWN: {
if (!animation) {
switch (wParam) {
case VK_UP:
y -= step;
break;
case VK_DOWN:
y += step;
break;
case VK_LEFT:
x -= step;
break;
case VK_RIGHT:
x += step;
break;
}
}
y += y_offset;
x += x_offset;
x = x + r > w ? w - r : x - r < 0 ? r : x;
y = y + r > h ? h - r : y - r < 0 ? r : y;
RECT invalid_area;
invalid_area.top = y + r;
invalid_area.left = x - r;
invalid_area.bottom = y - r;
invalid_area.right = x + r;
InvalidateRect(hWnd, &invalid_area, true);
break;
}
case WM_SIZE: {
if (x + r > w)
x = w - r;
if (y + r > h)
y = h - r;
break;
}
case WM_PAINT: {
//HDC hdc = BeginPaint(hWnd, &ps);
HDC hdc = GetDC(hWnd);
HBRUSH shape_brush = CreateSolidBrush(shape_color);
HPEN shape_pen = CreatePen(PS_SOLID, 2, RGB(0, 0, 0));
SelectObject(hdc, shape_pen);
SelectObject(hdc, shape_brush);
Circle(hdc, x, y, r);
DeleteObject(shape_pen);
DeleteObject(shape_brush);
DeleteObject(hdc);
ReleaseDC(hWnd, hdc);
//EndPaint(hWnd, &ps);
break;
}
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
答案 0 :(得分:4)
在WM_PAINT
处理程序中,您没有致电BeginPaint
/ EndPaint
,这意味着您的窗口将始终标记为无效。这将生成连续的WM_PAINT
消息流,这将阻止您的计时器工作,因为WM_TIMER
消息仅在消息队列为空时生成。
有关控制何时生成WM_TIMER
消息的基本算法,请参阅If my WM_TIMER handler takes longer than the timer period, will my queue fill up with WM_TIMER messages?。