textpub.neocities.org . [ список статей ]

Мой перевод англоязычной статьи «Painting the Window» с сайта компании Microsoft (ссылка на оригинал: новая, старая), автор статьи там не указан, дата публикации оригинала: 05.10.2010 г.

Отрисовка (перерисовка) окна на экране

Итак, мы создали окно. Теперь мы хотим что-то отобразить в этом окне. В терминологии Windows это называется отрисовкой окна на экране. Метафорически окно является чистым холстом, ожидающим, чтобы его заполнили.

В какие-то моменты наша программа будет запускать отрисовку для обновления содержимого окна. В другие моменты операционная система будет оповещать программу о том, что она должна перерисовать какую-то часть окна. Когда эти моменты настанут, операционная система пошлет окну сообщение WM_PAINT. Часть окна, которая должна быть перерисована, называется обновляемой областью.

Когда окно отображается на экране в первый раз после запуска программы, вся клиентская область окна должна быть отрисована. Поэтому вы всегда будете получать хотя бы одно сообщение WM_PAINT, когда отображаете окно на экране.


Обновляемая область окна включает всю клиентскую область

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

Теперь предположим, что пользователь передвинул другое окно так, что оно скрыло часть нашего окна. Когда скрытая часть снова станет видимой, информация о ней будет добавлена в информацию об обновляемой области и наше окно получит очередное сообщение WM_PAINT.


Рисунок, показывающий, как изменяется информация об обновляемой области, когда происходит перекрытие одного окна другим

Информация об обновляемой области изменяется также, когда пользователь растягивает окно (изменяет его размеры). На следующем рисунке пользователь растянул окно вправо. Информация о новой части окна с его правой стороны добавляется в информацию об обновляемой области.


Изменение обновляемой области (информации о ней) при изменении размеров окна

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

    switch (uMsg)
    {

    case WM_PAINT:
        {
            PAINTSTRUCT ps;
            HDC hdc = BeginPaint(hwnd, &ps);

            // Вся отрисовка описывается здесь, между
            // функциями BeginPaint и EndPaint

            FillRect(hdc, &ps.rcPaint, (HBRUSH) (COLOR_WINDOW+1));

            EndPaint(hwnd, &ps);
        }
        return 0;

    }

Начало операции отрисовки инициируется вызовом функции BeginPaint. Эта функция заполняет структуру типа PAINTSTRUCT информацией о запросе на перерисовку. Информация о текущей обновляемой области задается в элементе rcPaint структуры типа PAINTSTRUCT. Координаты этой обновляемой области определяются относительно начала координат клиентской области:


Обновляемая область в координатах клиентской области

При написании нашего программного кода отрисовки мы должны сделать выбор из двух возможностей:

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

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

            FillRect(hdc, &ps.rcPaint, (HBRUSH) (COLOR_WINDOW+1));

Подробности работы функции FillRect в этом примере не важны, но отметим, что второй параметр задает координаты прямоугольника для закрашивания. В данном случае мы передаем в функцию обновляемую область целиком (rcPaint является элементом структуры типа PAINTSTRUCT). После получения первого в цикле сообщений сообщения WM_PAINT (начало работы программы) нужно нарисовать всю клиентскую область главного окна, поэтому элемент rcPaint содержит координаты клиентской области окна целиком. В следующих сообщениях WM_PAINT элемент rcPaint может содержать и прямоугольник меньшего размера.

Функция FillRect является частью интерфейса графических устройств (GDI), который обеспечивал доступ к графике в Windows довольно долгое время. В Windows 7 компания Microsoft представила новый графический движок, названный Direct2D, который поддерживает высокопроизводительные операции с графикой, к примеру, использующие аппаратное ускорение. Direct2D также доступен в Windows Vista посредством обновления платформы для Windows Vista и для Windows Server 2008 посредством обновления платформы для Windows Server 2008. (При этом интерфейс GDI всё еще полностью поддерживается.)

После того, как мы закончили отрисовку, вызываем функцию EndPaint. Эта функция стирает информацию об обновляемой области, что является сигналом для Windows о том, что окно закончило отрисовывать себя.

textpub.neocities.org . [ список статей ]