Win32 против MFC - часть II

ОГЛАВЛЕНИЕ

В данной части рассматривается оконная процедура в приложении MFC и как команда MFC построила ее для программистов MFC.

Введение

В первой части серии было описано, как MFC инкапсулирует функцию WinMain, и как она создает цикл обработки сообщений внутри. Более того, было сказано, что все программы Windows имеют минимум две функции, WinMain и wndProc, но wndProc детально не разбиралась.

Если вы еще не прочитали первую часть статьи, начните с нее, поскольку она посвящена основам приложений Win32 и MFC.

Оконная процедура

Оконная процедура (или оконная функция) является определенной в приложении функцией, обрабатывающей сообщения, отправленные окну. Сообщения варьируются от сообщений, генерируемых мышью, до сообщений, отправляемых приложению другим процессом. Эта специальная функция не вызывается ни программой, ни MFC, она вызывается Windows.

Программа ждет, пока Windows не отправит ей сообщение. При получении сообщения (через заданную функцию обратного вызова) программа должна предпринять соответствующее действие путем выполнения некоторых процессов, вызова одного-двух API и предоставления конечному пользователю функциональности, которую программа должна предоставлять.
В терминологии Windows функция обратного вызова является функцией, вызываемой Windows. Оконная процедура является прекрасным примером функции обратного вызова, прототип которой создается следующим образом:

LRESULT CALLBACK WindowProc
    (
    HWND hwnd, //описатель окна
    UINT uMsg, //идентификатор сообщения
    WPARAM wParam, //первый параметр сообщения
    LPARAM lParam //второй параметр сообщения
    );

Где LRESULT объявлен как тип данных long, и CALLBACK задает соглашение о вызовах __stdcall (Чтобы увидеть это, подведите курсор к нужному типу данных и нажмите F12 при взаимодействии в VC++ 6.0).

В первой части статьи написано, как работает оконная процедура и что она должна делать. Но для простоты чтения здесь снова приведена функция обратного вызова:

LRESULT CALLBACK wndProc(HWND hWnd, UINT message,
                         WPARAM wParam, LPARAM lParam)
{
    switch(message)
    {
    case WM_DESTROY:
        PostQuitMessage(0);
        break;

    default:
        return DefWindowProc(hWnd, message, wParam,
            lParam);
    }
    return 0;
}

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

При получении WM_DESTROY вызывается PostQuitMessage, говорящий системе, что поток сделал запрос на завершение. Это прерывает цикл обработки сообщений, и программа успешно завершается.