使用計時器
本主題說明如何建立和終結計時器,以及如何使用計時器以指定間隔捕捉滑鼠輸入。
本主題包含下列各節。
建立計時器
下列範例會使用 SetTimer 函式來建立兩個計時器。 第一個計時器每 10 秒設定一次,第二個計時器每五分鐘設定一次。
// Set two timers.
SetTimer(hwnd, // handle to main window
IDT_TIMER1, // timer identifier
10000, // 10-second interval
(TIMERPROC) NULL); // no timer callback
SetTimer(hwnd, // handle to main window
IDT_TIMER2, // timer identifier
300000, // five-minute interval
(TIMERPROC) NULL); // no timer callback
若要處理這些計時器所產生的 WM_TIMER 訊息,請將 WM_TIMER case 語句新增至 hwnd 參數的視窗程式。
case WM_TIMER:
switch (wParam)
{
case IDT_TIMER1:
// process the 10-second timer
return 0;
case IDT_TIMER2:
// process the five-minute timer
return 0;
}
應用程式也可以建立計時器,其 WM_TIMER 訊息不是由主視窗程式處理,而是由應用程式定義的回呼函式處理,如下列程式碼範例所示,它會建立計時器,並使用回呼函式 MyTimerProc 來處理計時器的 WM_TIMER 訊息。
// Set the timer.
SetTimer(hwnd, // handle to main window
IDT_TIMER3, // timer identifier
5000, // 5-second interval
(TIMERPROC) MyTimerProc); // timer callback
MyTimerProc的呼叫慣例必須以TimerProc 回呼函式為基礎。
如果您的應用程式建立計時器而不指定視窗控制碼,您的應用程式必須監視訊息佇列 中的WM_TIMER 訊息,並將其分派至適當的視窗。
HWND hwndTimer; // handle to window for timer messages
MSG msg; // message structure
while (GetMessage(&msg, // message structure
NULL, // handle to window to receive the message
0, // lowest message to examine
0)) // highest message to examine
{
// Post WM_TIMER messages to the hwndTimer procedure.
if (msg.message == WM_TIMER)
{
msg.hwnd = hwndTimer;
}
TranslateMessage(&msg); // translates virtual-key codes
DispatchMessage(&msg); // dispatches message to window
}
終結計時器
應用程式應該使用 KillTimer 函 式來終結不再需要的計時器。 下列範例會終結常數IDT_TIMER1、IDT_TIMER2和IDT_TIMER3所識別的計時器。
// Destroy the timers.
KillTimer(hwnd, IDT_TIMER1);
KillTimer(hwnd, IDT_TIMER2);
KillTimer(hwnd, IDT_TIMER3);
使用計時器函式來捕捉滑鼠輸入
有時候,您必須在畫面上有滑鼠指標時防止輸入更多。 若要達成此目的,其中一個方法是建立特殊的常式,以捕捉滑鼠輸入,直到發生特定事件為止。 許多開發人員將此常式稱為「建置 mousetrap」。
下列範例會使用 SetTimer 和 KillTimer 函式來捕捉滑鼠輸入。 SetTimer 會建立計時器,每 10 秒傳送 WM_TIMER 訊息。 每次應用程式收到 WM_TIMER 訊息時,都會記錄滑鼠指標位置。 如果目前的位置與上一個位置相同,且應用程式的主視窗最小化,應用程式會將滑鼠指標移至圖示。 當應用程式關閉時, KillTimer 會停止計時器。
HICON hIcon1; // icon handle
POINT ptOld; // previous cursor location
UINT uResult; // SetTimer's return value
HINSTANCE hinstance; // handle to current instance
//
// Perform application initialization here.
//
wc.hIcon = LoadIcon(hinstance, MAKEINTRESOURCE(400));
wc.hCursor = LoadCursor(hinstance, MAKEINTRESOURCE(200));
// Record the initial cursor position.
GetCursorPos(&ptOld);
// Set the timer for the mousetrap.
uResult = SetTimer(hwnd, // handle to main window
IDT_MOUSETRAP, // timer identifier
10000, // 10-second interval
(TIMERPROC) NULL); // no timer callback
if (uResult == 0)
{
ErrorHandler("No timer is available.");
}
LONG APIENTRY MainWndProc(
HWND hwnd, // handle to main window
UINT message, // type of message
WPARAM wParam, // additional information
LPARAM lParam) // additional information
{
HDC hdc; // handle to device context
POINT pt; // current cursor location
RECT rc; // location of minimized window
switch (message)
{
//
// Process other messages.
//
case WM_TIMER:
// If the window is minimized, compare the current
// cursor position with the one from 10 seconds
// earlier. If the cursor position has not changed,
// move the cursor to the icon.
if (IsIconic(hwnd))
{
GetCursorPos(&pt);
if ((pt.x == ptOld.x) && (pt.y == ptOld.y))
{
GetWindowRect(hwnd, &rc);
SetCursorPos(rc.left, rc.top);
}
else
{
ptOld.x = pt.x;
ptOld.y = pt.y;
}
}
return 0;
case WM_DESTROY:
// Destroy the timer.
KillTimer(hwnd, IDT_MOUSETRAP);
PostQuitMessage(0);
break;
//
// Process other messages.
//
}
雖然下列範例也會示範如何捕捉滑鼠輸入,但它會透過應用程式定義的回呼函式MyTimerProc來處理WM_TIMER訊息,而不是透過應用程式的訊息佇列。
UINT uResult; // SetTimer's return value
HICON hIcon1; // icon handle
POINT ptOld; // previous cursor location
HINSTANCE hinstance; // handle to current instance
//
// Perform application initialization here.
//
wc.hIcon = LoadIcon(hinstance, MAKEINTRESOURCE(400));
wc.hCursor = LoadCursor(hinstance, MAKEINTRESOURCE(200));
// Record the current cursor position.
GetCursorPos(&ptOld);
// Set the timer for the mousetrap.
uResult = SetTimer(hwnd, // handle to main window
IDT_MOUSETRAP, // timer identifier
10000, // 10-second interval
(TIMERPROC) MyTimerProc); // timer callback
if (uResult == 0)
{
ErrorHandler("No timer is available.");
}
LONG APIENTRY MainWndProc(
HWND hwnd, // handle to main window
UINT message, // type of message
WPARAM wParam, // additional information
LPARAM lParam) // additional information
{
HDC hdc; // handle to device context
switch (message)
{
//
// Process other messages.
//
case WM_DESTROY:
// Destroy the timer.
KillTimer(hwnd, IDT_MOUSETRAP);
PostQuitMessage(0);
break;
//
// Process other messages.
//
}
// MyTimerProc is an application-defined callback function that
// processes WM_TIMER messages.
VOID CALLBACK MyTimerProc(
HWND hwnd, // handle to window for timer messages
UINT message, // WM_TIMER message
UINT idTimer, // timer identifier
DWORD dwTime) // current system time
{
RECT rc;
POINT pt;
// If the window is minimized, compare the current
// cursor position with the one from 10 seconds earlier.
// If the cursor position has not changed, move the
// cursor to the icon.
if (IsIconic(hwnd))
{
GetCursorPos(&pt);
if ((pt.x == ptOld.x) && (pt.y == ptOld.y))
{
GetWindowRect(hwnd, &rc);
SetCursorPos(rc.left, rc.top);
}
else
{
ptOld.x = pt.x;
ptOld.y = pt.y;
}
}
}
相關主題