使用计时器
本主题介绍如何创建和销毁计时器,以及如何使用计时器按指定间隔捕获鼠标输入。
本主题包含以下各节:
创建计时器
以下示例使用 SetTimer 函数创建两个计时器。 第一个计时器设置为每 10 秒,第二个计时器设置为每 5 分钟一次。
// 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消息不是由main窗口过程处理,而是由应用程序定义的回调函数处理,如以下代码示例中所示,该函数创建计时器并使用回调函数 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);
使用计时器函数捕获鼠标输入
有时,当你在屏幕上有鼠标指针时,有必要阻止更多输入。 实现此目的的一种方法是创建一个特殊的例程,用于捕获鼠标输入,直到发生特定事件。 许多开发人员将此例程称为“构建鼠标陷阱”。
以下示例使用 SetTimer 和 KillTimer 函数捕获鼠标输入。 SetTimer 创建一个计时器,每隔 10 秒发送一条 WM_TIMER 消息。 每次应用程序收到 WM_TIMER 消息时,都会记录鼠标指针位置。 如果当前位置与上一个位置相同,并且应用程序的main窗口已最小化,则应用程序会将鼠标指针移动到图标。 应用程序关闭时, 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;
}
}
}
相关主题