Как эффективно отображать окно с двойной буферизацией без эффекта разрыва?

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

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

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

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

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

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

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

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

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

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

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

Спасибо!

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

5
задан smit 27 March 2012 в 18:09
поделиться