Использование Таймеров


Создание таймера

В следующем примере используется функция 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;

//
// Обрабатываем другие сообщения.
//

}
 
« Предыдущая статья   Следующая статья »