您可以通过创建具有SetTimer功能的计时器以定时间隔绘制。通过使用定时器定期向窗口过程发送WM_TIMER消息,应用程序可以在其他应用程序继续运行时在客户端区域中执行简单的动画。
在下面的示例中,应用程序在客户区域中从一侧到另一侧弹回一个星。每次窗口程序接收到WM_TIMER消息时,该过程将擦除当前位置的星号,计算新位置,并在新位置内绘制星形。程序在处理WM_CREATE消息时调用SetTimer启动定时器。
RECT rcCurrent = {0,0,20,20};
POINT aptStar[6] = {10,1, 1,19, 19,6, 1,6, 19,19, 10,1};
int X = 2, Y = -1, idTimer = -1;
BOOL fVisible = FALSE;
HDC hdc;
LRESULT APIENTRY WndProc(hwnd,message,wParam,lParam)
HWND hwnd;
UINT message;
WPARAM wParam;
LPARAM lParam;
{
PAINTSTRUCT ps;
RECT rc;
switch(message){
case WM_CREATE:
/ *计算出发点。*/
GetClientRect(hwnd, &rc);
OffsetRect(&rcCurrent, rc.right / 2, rc.bottom / 2);
/ *初始化私有DC。*/
hdc = GetDC(hwnd);
SetViewportOrgEx(hdc,rcCurrent.left,
rcCurrent.top, NULL);
SetROP2(hdc, R2_NOT);
/ *启动计时器。*/
SetTimer(hwnd, idTimer = 1, 10, NULL);
return 0L;
case WM_DESTROY:
KillTimer(hwnd, 1);
PostQuitMessage(0);
return 0L;
case WM_SIZE:
开关(wParam){
case SIZE_MINIMIZED:
/ *如果窗口最小化,请停止定时器。*/
KillTimer(hwnd, 1);
idTimer = -1;
break;
case SIZE_RESTORED:
/*
*将明星移回客户区
*如有需要
*/
if(rcCurrent.right >(int)LOWORD(lParam))
rcCurrent.left =
(rcCurrent.right =
(int) LOWORD(lParam)) - 20;
if(rcCurrent.bottom >(int)HIWORD(lParam))
rcCurrent.top =
(rcCurrent.bottom =
(int) HIWORD(lParam)) - 20;
/ *落到下一个例子。*/
case SIZE_MAXIMIZED:
/ *启动定时器,如果它已经停止。*/
if (idTimer == -1)
SetTimer(hwnd, idTimer = 1, 10, NULL);
break;
}
return 0L;
case WM_TIMER:
/ *隐藏星星,如果它是可见的。*/
如果(fVisible)
Polyline(hdc, aptStar, 6);
/ *如有需要,可以将星光放在一边。*/
GetClientRect(hwnd, &rc);
if(rcCurrent.left + X < rc.left ||
rcCurrent.right + X > rc.right)
X = -X;
if(rcCurrent.top + Y < rc.top ||
rcCurrent.bottom + Y > rc.bottom)
Y = -Y;
/ *显示新星的新位置。*/
OffsetRect(&rcCurrent, X, Y);
SetViewportOrgEx(hdc,rcCurrent.left,
rcCurrent.top, NULL);
fVisible = Polyline(hdc, aptStar, 6);
return 0L;
case WM_ERASEBKGND:
/ *删除星。*/
fVisible = FALSE;
return DefWindowProc(hwnd, message, wParam, lParam);
case WM_PAINT:
/*
*如果明星不可见,则显示。使用BeginPaint
*清除更新区域。
*/
BeginPaint(hwnd, &ps);
如果(!fVisible)
fVisible = Polyline(hdc, aptStar, 6);
EndPaint(hwnd, &ps);
return 0L;
}
return DefWindowProc(hwnd, message, wParam, lParam);
}
此应用程序使用专用DC来最小化准备用于绘图的DC所需的时间。窗口过程在处理WM_CREATE消息时检索和初始化专用DC,设置二进制栅格操作模式,以允许使用与折线功能相同的调用来擦除和绘制星。窗口过程还设置视口原点,以允许使用相同的点集绘制星,而不考虑星型在客户区中的位置。
当窗口必须更新时,该应用程序使用WM_PAINT消息绘制星标。窗口程序仅在不可见时才绘制星形;也就是说,只有当它已被WM_ERASEBKGND消息删除。窗口过程拦截WM_ERASEBKGND消息以设置【fVisibleen】变量,但将消息传递给DefWindowProc,以便Windows可以绘制窗口背景。
当窗口最小化时,应用程序使用WM_SIZE消息来停止定时器,并在恢复最小化窗口时重新启动定时器。如果窗口的大小已经缩小,窗口过程也会使用该消息来更新星形的当前位置,以便星型不再在客户区域中。应用程序通过使用由rcCurrent指定的结构来跟踪星的当前位置,该结构定义了星形的边界矩形。保持客户区域中矩形的所有角落保持该区域中的星形。处理WM_CREATE消息时,窗口过程最初将客户区域中的星号居中。