以時間間隔繪製
您可以使用 SetTimer 函式建立計時器,以時間間隔繪製。 藉由使用計時器定期將 WM_TIMER 訊息傳送至視窗程式,應用程式可以在用戶端應用程式中執行簡單的動畫,而其他應用程式仍繼續執行。
在下列範例中,應用程式會將star從用戶端區域側邊跳回。 每當視窗程式收到WM_TIMER訊息時,程式就會清除目前位置的star、計算新位置,並在新位置內繪製star。 程式會在處理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 hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
PAINTSTRUCT ps;
RECT rc;
switch (message)
{
case WM_CREATE:
// Calculate the starting point.
GetClientRect(hwnd, &rc);
OffsetRect(&rcCurrent, rc.right / 2, rc.bottom / 2);
// Initialize the private DC.
hdc = GetDC(hwnd);
SetViewportOrgEx(hdc, rcCurrent.left,
rcCurrent.top, NULL);
SetROP2(hdc, R2_NOT);
// Start the timer.
SetTimer(hwnd, idTimer = 1, 10, NULL);
return 0L;
case WM_DESTROY:
KillTimer(hwnd, 1);
PostQuitMessage(0);
return 0L;
case WM_SIZE:
switch (wParam)
{
case SIZE_MINIMIZED:
// Stop the timer if the window is minimized.
KillTimer(hwnd, 1);
idTimer = -1;
break;
case SIZE_RESTORED:
// Move the star back into the client area
// if necessary.
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;
}
// Fall through to the next case.
case SIZE_MAXIMIZED:
// Start the timer if it had been stopped.
if (idTimer == -1)
SetTimer(hwnd, idTimer = 1, 10, NULL);
break;
}
return 0L;
case WM_TIMER:
// Hide the star if it is visible.
if (fVisible)
Polyline(hdc, aptStar, 6);
// Bounce the star off a side if necessary.
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;
// Show the star in its new position.
OffsetRect(&rcCurrent, X, Y);
SetViewportOrgEx(hdc, rcCurrent.left,
rcCurrent.top, NULL);
fVisible = Polyline(hdc, aptStar, 6);
return 0L;
case WM_ERASEBKGND:
// Erase the star.
fVisible = FALSE;
return DefWindowProc(hwnd, message, wParam, lParam);
case WM_PAINT:
// Show the star if it is not visible. Use BeginPaint
// to clear the update region.
BeginPaint(hwnd, &ps);
if (!fVisible)
fVisible = Polyline(hdc, aptStar, 6);
EndPaint(hwnd, &ps);
return 0L;
}
return DefWindowProc(hwnd, message, wParam, lParam);
}
此應用程式會使用私人裝置內容,將準備裝置內容以進行繪圖所需的時間降到最低。 視窗程式會在處理WM_CREATE訊息時擷取並初始化私人裝置內容,並將二進位點陣作業模式設定為允許清除star,並使用對Polyline函式的相同呼叫來繪製。 視窗程式也會設定檢視區原點,以允許使用相同的點集繪製star,而不論star在工作區中的位置為何。
每當視窗必須更新時,應用程式會使用WM_PAINT訊息來繪製star。 視窗程式只會在看不到時繪製star;也就是說,只有在WM_ERASEBKGND訊息已清除時。 視窗程式會攔截 WM_ERASEBKGND 訊息來設定 fVisible 變數,但會將訊息傳遞至 DefWindowProc ,讓系統可以繪製視窗背景。
應用程式會使用 WM_SIZE 訊息,在視窗最小化時停止計時器,並在還原最小化的視窗時重新開機計時器。 如果視窗的大小已減少,則視窗程式也會使用訊息來更新star的目前位置,讓star不再位於工作區中。 應用程式會使用 rcCurrent 所指定的結構來追蹤star目前的位置,此結構會定義star的周框。 在工作區中保留矩形的所有角落,會將star保留在區域中。 處理WM_CREATE訊息時,視窗程式一開始會將工作區中的star置中。