Использование многослойных окон для создания гладких границ окон - PullRequest
9 голосов
/ 14 апреля 2009

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

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

Вот что я делаю: у меня есть окно, называемое A, с элементами управления и текстом и всем, что включает это окно. У меня есть окно B как потомок окна A, за исключением того, что оно имеет стиль WS_POPUP вместо WS_CHILD, поэтому оно может располагаться вне области A и рисуется поверх элементов управления A. Окно B также имеет стиль WS_EX_LAYERED, и при инициализации я вызываю UpdateLayeredWindow с флагом ULW_ALPHA и исходным DC с 32-битным битовым массивом с альфа-каналом, чтобы заставить его рисовать с альфа-пиксельным пикселем.

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

Итак, это в основном окно A со всеми дочерними элементами управления и чем угодно, с окном B, плавающим прямо над ним, рисуя красивую гладкую границу. Я отвечаю на сообщения WM_MOVE и т. Д., Перемещая вместе с ним окно B, и у меня отключено окно B, поэтому оно никогда не может получить фокус или ввод (щелчки уже проходят, поскольку его части с нулевой непрозрачностью, такие как большинство его внутренние части, уже исключены из комплектации).

Вот как выглядят фигуры, чтобы лучше понять, что я имею в виду.

Итак, это работает, но я не уверен, что это действительно лучший способ сделать это. У меня два вопроса:

  • Это звучит приемлемо, или в этом есть что-то явно ужасное?
  • Поскольку в настоящее время это работает, кажется, что он использует внеэкранный буфер размером с окно (которое может быть до 1024x768), даже если очень немногие пиксели имеют ненулевые данные непрозрачности - будет ли это стоит лишних затрат и дополнительной сложности - разрезать их на отдельные граничные части и соединить их вместе?

Ответы [ 3 ]

3 голосов
/ 15 апреля 2009

Я обнаружил одну вещь: наличие отдельных фрагментов кадра может рендериться значительно быстрее, чем наличие одного единственного окна гигантского кадра с большим пространством пустых пикселей в середине. У меня нет никаких фактических чисел, но только после быстрой проверки обоих, была заметная задержка, когда несколько окон с полнокадровыми окнами накладывались друг на друга, но когда их кадры были разрезаны на более мелкие компоненты, это было намного быстрее , Какие бы издержки не возникали из-за наличия многослойных окон с их собственными контекстами устройства, это не сильно сказывается, а наличие больших пространств пикселей (пустых или нет!) Все еще увеличивает нагрузку.

2 голосов
/ 20 апреля 2009

Мой продукт использует многоуровневые окна для рисования маленьких вкладок, которые я прикрепляю к каждому окну. Я использовал многослойные окна, чтобы получить плавное округление без наложения. Единственная неприятная проблема, с которой я столкнулся на данный момент, заключается в том, что некоторые окна OpenGL пишутся поверх многоуровневых окон в Windows XP и Vista без DWM. Это проблема низкого уровня, и Microsoft не очень помогла. Вы можете воспроизвести его, открыв Google Планета Земля и перетащив свое приложение через главное окно рендеринга, ваше многоуровневое окно исчезнет.

1 голос
/ 17 апреля 2009
  1. Не забудьте протестировать под RDP и VM (Hyper-V и VMWare)
  2. Попробуйте несколько карт gfx и на нетбуках и ноутбуках (если применимо).
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...