Использование функций таймера для перехвата ввода данных от мыши


Иногда необходимо воспрепятствовать большому количеству вводимых данных, пока ваш курсор мыши на экране. Один из способов осуществить это состоит в том, чтобы создать специальную подпрограмму, которая перехватывает ввод данных от мыши до тех пор, пока не произойдет конкретное событие. Многие разработчики называют эту подпрограмму как "создание мышеловки".

Пример ниже использует функции 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: 
        // Если окно минимизировано, сравните текущую
        // позицию курсора с позицией на 10 секунд раньше.
        // Если позиция курсора не изменилась, поместите курсор в значок.

            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;

        //
        // Обработка других сообщений.
        // 

}

Хотя пример ниже также показывает, как перехватить вводимые данные мыши, он обрабатывает сообщение WM_TIMER через определяемую программой функцию обратного вызова 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 определяемая приложением функция обратного вызова, которая
// обрабатывает сообщения WM_TIMER.

VOID CALLBACK MyTimerProc( 
    HWND hwnd,        // дескриптор окна для сообщений таймера
    UINT message,     // сообщение WM_TIMER
    UINT idTimer,     // идентификатор таймера
    DWORD dwTime)     // текущее системное время
{

    RECT rc;
    POINT pt;

    // Если окно минимизировано, сравните текущую
    // позицию курсора с позицией на 10 секунд раньше.
    // Если позиция курсора не изменилась, поместите курсор в значок.

    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;
        }
    }
}

 

Назад в оглавление
На главную страницу
Переведено 22.04.2009 20:28 ©Copyright V. Sokovikov
Hosted by uCoz