Using Timer Functions to Create a Mousetrap
Sometimes it is necessary to prevent more input while you have a cursor on the screen. One way to accomplish this is to create a special routine that traps mouse input until a specific event occurs. Many developers refer to this routine as "building a mousetrap."
The following example uses the SetTimer and KillTimer functions to create a simple mousetrap. SetTimer creates a timer that sends a WM_TIMER message every 10 seconds. Each time the application receives a WM_TIMER message, it records the cursor location. If the current location is the same as the previous location and the application's main window is minimized, the application moves the cursor to the icon. When the application closes, KillTimer stops the timer.
HICON hIcon1; // icon handle
POINT ptOld; // previous cursor location
UINT uResult; // SetTimer's return value
HINSTANCE hinstance; // handle of 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 of 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 of main window
UINT message, // type of message
UINT wParam, // additional information
LONG lParam) // additional information
{
HDC hdc; // handle of 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.
//
}
Although the following example also creates a mousetrap, it processes the WM_TIMER message through the application-defined callback function MyTimerProc, rather than through the application's message queue.
UINT uResult; // SetTimer's return value
HICON hIcon1; // icon handle
POINT ptOld; // previous cursor location
HINSTANCE hinstance; // handle of 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 of 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 of main window
UINT message, // type of message
UINT wParam, // additional information
LONG lParam) // additional information
{
HDC hdc; // handle of 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 of 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;
}
}
}