Прочитать на английском

Поделиться через


Создание процедуры для окна

Функция DispatchMessage вызывает процедуру окна, которое является адресатом сообщения. Процедура обработки окна имеет следующую сигнатуру.

LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);

Существует четыре параметра:

  • Hwnd — это дескриптор окна.
  • uMsg — это код сообщения; например, сообщение WM_SIZE указывает, что окно было изменено в размере.
  • wParam и lParam содержат дополнительные данные, относящиеся к сообщению. Точное значение зависит от кода сообщения.

LRESULT — это целочисленное значение, которое программа возвращает в Windows. Он содержит ответ вашей программы на определенное сообщение. Значение этого значения зависит от кода сообщения. CALLBACK — это соглашение о вызовах для функции.

Обычная процедура обработки сообщений окна — это просто большой оператор switch, который переключает выполнение программы в зависимости от кода сообщения. Добавьте варианты для каждого сообщения, которое требуется обрабатывать.

switch (uMsg)
{
    case WM_SIZE: // Handle window resizing

    // etc
}

Дополнительные данные для сообщения содержатся в параметрах lParam и wParam. Оба параметра представляют собой целочисленные значения размера ширины указателя (32 бита или 64 бита). Значение каждого зависит от кода сообщения (uMsg). Для каждого сообщения необходимо будет найти код сообщения и привести параметры к правильному типу данных. Обычно данные являются числовым значением или указателем на структуру. Некоторые сообщения не имеют данных.

Например, в документации по сообщению WM_SIZE указано следующее:

  • wParam — это флаг, указывающий, было ли окно свернуто, максимизировано или изменено размер.
  • lParam содержит новую ширину и высоту окна в виде 16-разрядных значений, упакованных в один 32-или 64-разрядный номер. Чтобы получить эти значения, потребуется выполнить некоторые битовые сдвиги. К счастью, файл заголовка WinDef.h включает вспомогательные макросы, которые делают это.

Типичная процедура окна обрабатывает десятки сообщений, поэтому может стать довольно объёмной. Один из способов сделать код более модульным — поместить логику обработки каждого сообщения в отдельную функцию. В процедуре окна приведите параметры wParam и lParam к правильному типу данных и передайте эти значения в функцию. Например, чтобы обработать сообщение WM_SIZE , процедура окна будет выглядеть следующим образом:

LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch (uMsg)
    {
    case WM_SIZE:
        {
            int width = LOWORD(lParam);  // Macro to get the low-order word.
            int height = HIWORD(lParam); // Macro to get the high-order word.

            // Respond to the message:
            OnSize(hwnd, (UINT)wParam, width, height);
        }
        break;
    }
}

void OnSize(HWND hwnd, UINT flag, int width, int height)
{
    // Handle resizing
}

Макросы LOWORD и HIWORD получают 16-разрядные значения ширины и высоты из lParam. Процедура окна извлекает ширину и высоту, а затем передает эти значения OnSize функции.

Обработка сообщений по умолчанию

Если вы не обрабатываете определенное сообщение в процедуре окна, передайте параметры сообщения непосредственно в функцию DefWindowProc. Эта функция выполняет действие по умолчанию для сообщения, которое зависит от типа сообщения.

return DefWindowProc(hwnd, uMsg, wParam, lParam);

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

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

Вместо этого следует переместить работу в другой поток, используя одну из многозадаочных средств, встроенных в Windows:

  • Создайте новое обсуждение.
  • Используйте пул потоков.
  • Используйте асинхронные вызовы ввода-вывода.
  • Используйте асинхронные вызовы процедур.

Следующий

Рисование окна


Дополнительные ресурсы

Обучение

Модуль

Выбор оптимальной платформы приложений для проекта разработки Windows - Training

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