Использование Таймеров
В следующем примере используется функция SetTimer для создания двух таймеров. Интервал срабатывания первого таймера устанавливается на 10 секунд, а второго на каждые пять минут.
Пример:
// Устанавливаем два таймера.
SetTimer(hwnd, // хэндл главного окна
IDT_TIMER1, // идентификатор таймера
10000, // интервал - 10 секунд
(TIMERPROC) NULL); // процедуры таймера нет
SetTimer(hwnd, // хэндл главного окна
IDT_TIMER2, // идентификатор таймера
300000, // пяти-минутный интервал
(TIMERPROC) NULL); // процедуры таймера нет
Чтобы обработать сообщения WM_TIMER, генерируемые этими таймерами, добавьте выражение case WM_TIMER в оконную процедуру для параметра hwnd .
Пример:
case WM_TIMER:
switch (wParam)
{
case IDT_TIMER1:
// обрабатываем 10-ти секундный таймер
return 0;
case IDT_TIMER2:
// обрабатываем пятиминутный таймер
return 0;
}
Так же можно создать таймер, сообщения WM_TIMER которого будут обрабатываться не главной оконной процедурой, а предопределённой процедурой таймера (так называемой callback-функцией). В следующем примере обработкой сообщений WM_TIMER будет заниматься callback-функция MyTimerProc.
// Устанавливаем таймер.
SetTimer(hwnd, // хэндл главного окна
IDT_TIMER3, // идентификатор таймера
5000, // интервал - 5 секунд
(TIMERPROC) MyTimerProc); // процедура таймера
Вызов MyTimerProc должен быть преобразован к функции TimerProc.
Если при создании таймера не указывается хэндл окна, то приложение должно отслеживать очередь сообщений и искать в ней сообщения WM_TIMER, а затем диспатчить их в соответствующее окно. Обратите внимание, что GetMessage может вернуть -1 в случае ошибки.
Пример:
HWND hwndTimer; // хэндл окна для сообщений таймера
MSG msg; // структура сообщения
while (GetMessage(&msg, // структура сообщения
NULL, // хэндл окна для приёма сообщений
NULL, // самое младшее сообщение
NULL) // самое старшее сообщение
!= 0 && GetMessage(&msg, NULL, NULL, NULL) != -1)
{
// Постим сообщения WM_TIMER в процедуру hwndTimer.
if (msg.message == WM_TIMER)
{
msg.hwnd = hwndTimer;
}
TranslateMessage(&msg); // транслируем коды виртуальных клавиш
DispatchMessage(&msg); // диспатчим сообщение в окно
}
Если таймер больше не нужен, то его необходимо уничтожить при помощи функции KillTimer. Следующий пример уничтожает таймеры с идентификаторами IDT_TIMER1, IDT_TIMER2, и IDT_TIMER3.
// Удаляем таймеры.
KillTimer(hwnd, IDT_TIMER1);
KillTimer(hwnd, IDT_TIMER2);
KillTimer(hwnd, IDT_TIMER3);
Использование таймера для отслеживания мышки
Sometimes it is necessary to prevent more input while you have a mouse pointer 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."
Следующий пример использует функции SetTimer и KillTimer для отслеживания мышки. SetTimer создаёт таймер, который посылает сообщение WM_TIMER каждые 10 секунд. Каждый раз, когда приложение получает сообщение WM_TIMER, то оно записывает координаты курсора мышки. Если текущие координаты равны предыдущим и главное окно приложения минимизировано, то курсор мышки насильственно перемещается на иконку. При закрытии приложения вызывается KillTimer для уничтожения таймера.
Пример:
HICON hIcon1; // хэндл иконки
POINT ptOld; // предыдущие координаты курсора
UINT uResult; // Значение, которое вернёт SetTimer
HINSTANCE hinstance; // хэндл текущего экземпляра
//
// инициализация приложения.
//
wc.hIcon = LoadIcon(hinstance, MAKEINTRESOURCE(400));
wc.hCursor = LoadCursor(hinstance, MAKEINTRESOURCE(200));
// Записываем начальные координаты курсора.
GetCursorPos(&ptOld);
// Устанавливаем таймер для отслеживания мышки.
uResult = SetTimer(hwnd, // хэндл главного окна
IDT_MOUSETRAP, // идентификатор таймера
10000, // интервал - 10 секунд
(TIMERPROC) NULL); // процедуры таймера нет
if (uResult == 0)
{
ErrorHandler("No timer is available.");
}
LONG APIENTRY MainWndProc(
HWND hwnd, // хэндл главного окна
UINT message, // тип сообщения
WPARAM wParam, // дополнительная информация
LPARAM lParam) // дополнительная информация
{
HDC hdc; // хэндл контекста устройства
POINT pt; // текущие координаты курсора
RECT rc; // координаты свёрнутого окна
switch (message)
{
//
// Обрабатываем другие сообщения.
//
case WM_TIMER:
// Если окно минимизировано, то сравниваем текущие координаты
// курсора с предыдущими. Если координаты не изменились, то
// перемещаем курсор к иконке.
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:
// Уничтожаем таймер.
KillTimer(hwnd, IDT_MOUSETRAP);
PostQuitMessage(0);
break;
//
// Обрабатываем другие сообщения.
//
}
{mospagebreak}
Следующий пример показывает как отследить мышку через callback-функцию MyTimerProc.
Пример:
UINT uResult; // Значение, которое вернёт SetTimer
HICON hIcon1; // хэндл иконки
POINT ptOld; // предыдущие координаты курсора
HINSTANCE hinstance; // хэндл текущего экземпляра
//
// инициализация приложения.
//
wc.hIcon = LoadIcon(hinstance, MAKEINTRESOURCE(400));
wc.hCursor = LoadCursor(hinstance, MAKEINTRESOURCE(200));
// Записываем текущие координаты курсора.
GetCursorPos(&ptOld);
// Устанавливаем таймер для отслеживания мышки.
uResult = SetTimer(hwnd, // хэндл главного окна
IDT_MOUSETRAP, // идентификатор таймера
10000, // интервал - 10 секунд
(TIMERPROC) MyTimerProc); // процедура таймера
if (uResult == 0)
{
ErrorHandler("No timer is available.");
}
LONG APIENTRY MainWndProc(
HWND hwnd, // хэндл главного окна
UINT message, // тип сообщения
WPARAM wParam, // дополнительная информация
LPARAM lParam) // дополнительная информация
{
HDC hdc; // хэндл контекста устройства
switch (message)
{
//
// Обрабатываем другие сообщения.
//
case WM_DESTROY:
// Уничтожаем таймер.
KillTimer(hwnd, IDT_MOUSETRAP);
PostQuitMessage(0);
break;
//
// Обрабатываем другие сообщения.
//
}
// MyTimerProc - callback-функция, которая обрабатывает
// сообщения WM_TIMER.
VOID CALLBACK MyTimerProc(
HWND hwnd, // хэндл окна для сообщений таймера
UINT message, // сообщение WM_TIMER
UINT idTimer, // идентификатор таймера
DWORD dwTime) // текущее системное время
{
RECT rc;
POINT pt;
// Если окно минимизировано, то сравниваем текущие координаты
// курсора с предыдущими. Если координаты не изменились, то
// перемещаем курсор к иконке.
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;
}
}
}