WinAPI - избегать перерисовки окна - PullRequest
0 голосов
/ 21 сентября 2011

Я рисую в WinAPI-окне с помощью функции SetPixel().

Если я масштабирую окно или теряю фокус (другое окно сверху), я теряю весь контент, который рисую в окне.

Я только что использовал

RECT rc;
GetClientRect(hwnd, &rc);
RedrawWindow(hwnd, &rc, NULL, RDW_NOERASE | RDW_NOFRAME | RDW_VALIDATE);

, что помогло избежать перерисовки контента при перемещении окна, но при масштабировании и потере фокуса контент по-прежнему удаляется. У кого-нибудь есть идеи, что я пропустил?

Ответы [ 5 ]

6 голосов
/ 21 сентября 2011

Нарисуйте его в буфер / растровое изображение, а затем нарисуйте его в своем окне.

3 голосов
/ 21 сентября 2011

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

Как подсказал @daniel, если рисование - интенсивный процесс, и вы не хотите делать это каждый раз, когдатребуется перекраска, рендеринг вашего контента в растровое изображение (которое в данном случае будет закадровым буфером) и BitBlt (копирование) его в окно по мере необходимости.

Возьмите себе копию книги Чарльза Петцольда "Программирование Windows »для получения информации о том, как вам следует заниматься рисованием.Если вы пишете приложение WinAPI, но используете SetPixel, я бы порекомендовал прочитать полные первые несколько глав, чтобы понять, как должна быть структурирована программа Windows для старой школы.

2 голосов
/ 21 сентября 2011

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

Наиболее важные параметры StretchDIBits:

CONST VOID * lpBits - массив памяти (в пикселях). Вам нужно заполнить его в памяти вместо вызовов SetPixel.

CONST BITMAPINFO * lpBitsInfo - структура BITMAPINFO, которая должна описывать растровую структуру. Например, если lpBits имеет структуру BGRW (4 байта на пиксель), BITMAPINFO должен описывать растровое изображение истинного цвета.

1 голос
/ 21 сентября 2011

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

0 голосов
/ 21 сентября 2011

Создайте поверхность DIB и нарисуйте ее. Затем перерисовать растровое изображение при перерисовке окна.

Вы пытаетесь рисовать в Windows до Windows. ;)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...