Требуется сделать контрол (например, кнопку) в виде картинки, которая содержит прозрачные, полупрозрачные и непрозрачные области произвольной формы.
Есть ли стандартный механизм для дочерних окон наподобие WS_EX_LAYERED и UpdateLayeredWindow?
Для отсечения прозрачной области воспользовался SetWindowRgn.
А вот с полупрозрачностью возникли проблемы:
1) WM_PAINT почему-то приходит в "неправильном" порядке (сверху вниз), в итоге при сворачивании/разворачивании окна фоном оказывается другое приложение.
2) Полупрозрачный контрол не отслеживает изменения содержимого окна и не перерисовывается, когда надо.
Пробовал использовать WS_EX_TRANSPARENT, но с ним контрол видно только после ресайза окна.
Пока единственная мысль кэшировать фон и при каждом изменении содержимого окна его обновлять, но это муторно и быстро работать не будет
Здравствуйте, Lonkar, Вы писали:
L>Требуется сделать контрол (например, кнопку) в виде картинки, которая содержит прозрачные, полупрозрачные и непрозрачные области произвольной формы. L>Есть ли стандартный механизм для дочерних окон наподобие WS_EX_LAYERED и UpdateLayeredWindow?
L>Для отсечения прозрачной области воспользовался SetWindowRgn. L>А вот с полупрозрачностью возникли проблемы: L>1) WM_PAINT почему-то приходит в "неправильном" порядке (сверху вниз), в итоге при сворачивании/разворачивании окна фоном оказывается другое приложение. L>2) Полупрозрачный контрол не отслеживает изменения содержимого окна и не перерисовывается, когда надо.
L>Пробовал использовать WS_EX_TRANSPARENT, но с ним контрол видно только после ресайза окна.
L>Пока единственная мысль кэшировать фон и при каждом изменении содержимого окна его обновлять, но это муторно и быстро работать не будет
Увы, WS_EX_LAYERED и WS_CHILD несовместимы.
Могу только посоветовать нарисовать фрагменты GUI в памяти заранее (с прозрачностью),
чтобы при их перерисовке не тратить на это время.
Здравствуйте, okman, Вы писали: O>Могу только посоветовать нарисовать фрагменты GUI в памяти заранее (с прозрачностью), O>чтобы при их перерисовке не тратить на это время.
Так и планирую сделать. Вот только получается, что каждый полупрозрачный контрол должен хранить в памяти фон под ним.
Кроме того КАЖДЫЙ контрол должен информировать ВСЕ контролы, которые лежат выше него, при изменении своего состония, чтобы те обновили фон.
Надеялся, что существует более простой способ.
L>Пока единственная мысль кэшировать фон и при каждом изменении содержимого окна его обновлять, но это муторно и быстро работать не будет
Прозрачное child окно эмулируется достаточно просто. Базовая идея: перед отрисовкой попросить parent нарисовать нам свой background.
Обычное child окно (т.е. не transparent)
В обработчике WM_PAINT создаем offscreen bitmap и DC на её основе.
1) Берем этот DC и отправляем WM_PRINTCLIENT родителю с этим DC и соотв. SetViewportOrg.
после этого в нашем offscreen bitmap содержится фон окна родителя по месту нашего окна.
2) В этом нашем DC/bitmap рисуем нашу полупрозрачную картинку и
3) BitBlt нашу offscreen bitmap в DC окна.
Здравствуйте, c-smile, Вы писали:
CS>Прозрачное child окно эмулируется достаточно просто. Базовая идея: перед отрисовкой попросить parent нарисовать нам свой background. CS>В обработчике WM_PAINT создаем offscreen bitmap и DC на её основе. CS>1) Берем этот DC и отправляем WM_PRINTCLIENT родителю с этим DC и соотв. SetViewportOrg. CS>после этого в нашем offscreen bitmap содержится фон окна родителя по месту нашего окна.
Такое подойдет только, если прозрачное окно рисуется прямо поверх непрозрачного родителя.
А как быть, если между parent и прозрачным child окном оказались другие дочерние окна?
Получается, что им тоже требуется отправить WM_PRINT. А если, не дай бог, родитель сам оказался прозрачным, то и дедушку потревожить придётся...
Здравствуйте, kero, Вы писали: K>Ссылка из соседнего топика: статья "Layered Windows with Direct2D". K>Не готовый "простой способ", но в плане "информации к размышлению"
Статья интересная, но там предлагается использовать всё тот же WS_EX_LAYERED, который не понятно как подружить с WS_CHILD.
Здравствуйте, Lonkar, Вы писали:
L>Такое подойдет только, если прозрачное окно рисуется прямо поверх непрозрачного родителя. L>А как быть, если между parent и прозрачным child окном оказались другие дочерние окна? L>Получается, что им тоже требуется отправить WM_PRINT. А если, не дай бог, родитель сам оказался прозрачным, то и дедушку потревожить придётся...
Если parent сам полупрозрачный то он тоже должен посылать WM_PRINTCLIENT своему parent.
Собственно другого [надежного] способа в Windows нет.
Иначе использовать windowless элементы. Например как в htmlayout.
Здравствуйте, kero, Вы писали:
L>>Надеялся, что существует более простой способ.
K>Ссылка из соседнего топика: статья "Layered Windows with Direct2D". K>Не готовый "простой способ", но в плане "информации к размышлению"
Осторожно! Window 7 Aero не дружит иногда с DirecDraw Не знаю, как с отдельными окнами, у меня с десктопом была (и остаётся) проблема: при старте программы аэро вырубается
Здравствуйте, c-smile, Вы писали:
L>>Такое подойдет только, если прозрачное окно рисуется прямо поверх непрозрачного родителя. L>>А как быть, если между parent и прозрачным child окном оказались другие дочерние окна? L>>Получается, что им тоже требуется отправить WM_PRINT. А если, не дай бог, родитель сам оказался прозрачным, то и дедушку потревожить придётся...
CS>Если parent сам полупрозрачный то он тоже должен посылать WM_PRINTCLIENT своему parent. CS>Собственно другого [надежного] способа в Windows нет.
Далеко не все окна поддерживают WM_PRINT!!!
И, кстати, ровно вчера смотрел — между процессами вообще не работает даже на тех, кто поддерживает...
Btw, я рисую полупрозрачные контролы, в конкретном случае, через апдейт родителя. Мельканий нету... (интерактивная от мыши кнопка, 100х100, 25 кадров в секунду)
А, не, даже не совсем так, при обычной отрисовке берётся рект под контролом и InvalidateRect родителю, потом поверх рисуется. В случае таймера, создаётся HDC c битмапом, туда сохраняется кусок родителя и потом перед отрисовкой в контрол рендерится.
Ну, кстати, в случае нескольких контролов нужно просто в правильном порядке звать отрисовки... а я ещё делаю так: я не использую DC напрямую, я сделал пару неких классов(поток и картинка), которые использую для рисования многослойных вещей: вначале (поток) снимает 32-битное представление через HDC, потом всё в эту битовую карту рисуется через мои функции, потом, после того, как всё отрисовалось — заливается в изначальное HDC. Мельканий нет
Здравствуйте, Lonkar, Вы писали:
L>Спасибо за советы. L>Была надежда на существование "стандартного" механизма полупрозрачности, но велосипеды тоже не плохо — пойду собирать свой
Я тебя разочарую. В вин95 полупрозрачность отсутствовала вообще, а всё что ны имеем сейчас — убогий костыль над тем, что не предусматривает полупрозрачности. Не говоря уже о том, что мелкие муд@ки — в гуе черти-что еще со времен 3.х. До сих пор нет нормального универсального механизма и все извращаются как могут
Здравствуйте, о_О, Вы писали:
о_О>Я тебя разочарую. В вин95 полупрозрачность отсутствовала вообще, а всё что ны имеем сейчас — убогий костыль над тем, что не предусматривает полупрозрачности. Не говоря уже о том, что мелкие муд@ки — в гуе черти-что еще со времен 3.х. До сих пор нет нормального универсального механизма и все извращаются как могут
Не было бы проблем — мы бы и программы не писали...