15 мая 2023 года "Исходники.РУ" отмечают своё 23-летие!
Поздравляем всех причастных и неравнодушных с этим событием!
И огромное спасибо всем, кто был и остаётся с нами все эти годы!

Главная Форум Журнал Wiki DRKB Discuz!ML Помощь проекту


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

Содержиние:

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

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

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

}

Следующий пример показывает как отследить мышку через 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;
        }
    }
}