Как эффективно визуализировать окно с двойным буфером без каких-либо разрывов? - PullRequest
5 голосов
/ 27 марта 2012

Я хочу создать свою собственную крошечную систему GUI без окон, для этого я использую GDI +. Я не могу опубликовать здесь код, потому что он стал огромным (c ++), но ниже приведены основные шаги, которым я следую ...

  1. Создать растровое изображение размером, равным окну приложения.
  2. Для всех событий мыши и клавиатуры обновите пользовательские состояния элементов управления (например, если мышь в данный момент удерживается над определенным элементом управления, например, т. С.)
  3. Для события WM_PAINT закрасьте фон в закадровое растровое изображение, а затем закрасьте все обновленные элементы управления поверх него и, наконец, скопируйте все изображение вне экрана в передний буфер с помощью вызова Graphics :: DrawImage (..).
  4. Для WM_SIZE / WM_SIZING удалить предыдущее закадровое растровое изображение и создать еще одно с новым размером окна.

Также есть некоторые проверки для предотвращения повторного рисования элементов управления, то есть элементы управления рисуются только тогда, когда требуется перекрасить его, другими словами, когда состояние элемента управления изменяется только тогда, когда оно окрашивается, например, e.t.c.

Система работает нормально, но только с одним исключением ... при изменении размера окна появляется что-то вроде разрывающего эффекта. Теперь, что я имею в виду под эффектом разрыва, я попытаюсь объяснить ...

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

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

Сначала мне показалось, что использование закадрового экрана с постоянным полноэкранным размером может минимизировать артефакт, но когда я попробовал его, результаты были не столь удовлетворительными. Я также пытался вызвать Sleep () во время определения размера, чтобы переворачивание было выполнено полностью перед началом другого переворота, но странным образом даже это не сработало для меня!

Я слышал, что GDI на Vista не аппаратно ускоряется, может ли это быть проблемой?

Также мне интересно, как фреймворки, такие как Qt, визуализируют GUI без окон так гладко, даже если вы масштабируете сложное окно Qt GUI, очень быстро появляется незначительный артефакт. Насколько я знаю, Qt может использовать opengl для рендеринга GUI, но это второй вариант.

Если я использую directx, то изменение размера в реальном времени будет еще сложнее, с другой стороны, opengl, похоже, подходит для изменения размера без каких-либо проблем, но я потеряю все возможности 2D-рисования GDI +.

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

Спасибо!

Я всегда хотел проектировать интерфейсы, такие как Windows Media Player 11, но кто-то может сказать мне, что есть прямое решение для программиста на C ++ (я хочу знать, как, а не использовать какой-либо существующий каркас и т. Д.)? Подклассы, рисование владельца, пользовательское рисование ничего не дают вам такого уровня контроля, я не знаю, как нарисовать полупрозрачный контроль с общими элементами управления, поэтому я думаю, что этот вопрос заслуживает особого внимания. Еще раз спасибо.

1 Ответ

5 голосов
/ 27 марта 2012

Может ли это быть причиной сообщения WM_ERASEBKGND?

см. Этот вопрос: GDI + двойная буферизация в C ++

Кроме того, если вам нужен быстрый ответ из графического интерфейса пользователяЯ бы посоветовал против GDI +.

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