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;

}

}

}