Проверка очереди сообщений


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

Вы можете использовать функцию PeekMessage, чтобы проверить очередь сообщений в течение длинной операции. PeekMessage подобен функции GetMessage; обе проверяют очередь на наличие сообщения, которое соответствует критериям фильтра, а затем копирует сообщение в структуру MSG. Основная разница между этими двумя функциями в том, что GetMessage не возвращает значения до тех пор, пока сообщение, соответствующее критериям фильтра не помещено в очередь, в то время как PeekMessage возвращает значение немедленно независимо от того, находится оно или нет в очереди.

Следующий пример показывает, как использовать PeekMessage, чтобы проверить очередь сообщений на щелчки клавишей мыши и ввод информации с клавиатуры в ходе длинной операции.

Демонстрационный пример
HWND hwnd; 
BOOL fDone; 
MSG msg; 
 
// Начнем операцию и продолжим её до тех пор, пока она не закончится 
// или пока пользователь не щелкнет мышью или не нажмет клавишу. 
 
fDone = FALSE; 
while (!fDone) 
{ 
    fDone = DoLengthyOperation(); // функция, определяемая приложением
 
    // Удаляем любое сообщение, которое может быть в очереди. Если 
    // очередь содержит какое-либо сообщение мыши или клавиатуры, 
    // закончить операцию. 
 
    while (PeekMessage(&msg, hwnd,  0, 0, PM_REMOVE)) 
    { 
        switch(msg.message) 
        { 
            case WM_LBUTTONDOWN: 
            case WM_RBUTTONDOWN: 
            case WM_KEYDOWN: 
                // 
                // Выполнение любой требуемой очистки. 
                // 
                fDone = TRUE; 
        } 
    } 
} 

Другие функции, включая GetQueueStatus и GetInputState, также позволяют проверять содержание очереди сообщений потока. GetQueueStatus возвращает массив флажков, которые указывают типы сообщений в очереди; использование ее - самый быстрый способ обнаружить, содержит ли очередь какие-либо сообщения. GetInputState возвращает значение ИСТИНА (TRUE), если очередь содержит сообщения клавиатуры или мыши. Обе из этих функций могут быть использованы, чтобы установить, содержит ли очередь сообщения, которые нуждаются в обработке.

Назад в оглавление темы
На главную страницу темы

Hosted by uCoz