Как задать прозрачность для заднего фона элемента управления

Обсуждения по программированию для ОС Windows безотносительно используемого языка программирования. Windows NT, Win32, Windows API, ядро и драйверы.
Admiralisimys
Постоялец
Постоялец
 
Сообщения: 315
Зарегистрирован: 01.06.2009 (Пн) 10:26

Как задать прозрачность для заднего фона элемента управления

Сообщение Admiralisimys » 02.09.2011 (Пт) 19:55

Здравствуйте.

Допустим, есть окно с несколькими элементами управления (Группа, Надпись, Флажок, Переключатель, Текст, Вкладки, Ссылка*)
1_ThemeOff_BothWindow.png
1_ThemeOff_BothWindow.png (6.14 Кб) Просмотров: 2127

При установки стандартной темы в Windows XP окно преобразится
2_ThemeOn_BothWindow.png
2_ThemeOn_BothWindow.png (10.91 Кб) Просмотров: 2127


Для придания более естественного вида контролам пишется знаменитый манифест
Код: Выделить всё
<?xml version='1.0' encoding='UTF-8' standalone='yes'?>
<assembly xmlns='urn:schemas-microsoft-com:asm.v1' manifestVersion='1.0'>
  <dependency>
    <dependentAssembly>
      <assemblyIdentity type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*' />
    </dependentAssembly>
  </dependency>
</assembly>

После чего окно преобразится (*и появится элемент управления Ссылка)
3_ThemeOn_StandartWindow_Man.png
3_ThemeOn_StandartWindow_Man.png (13.91 Кб) Просмотров: 2127


Появились так называемые "потёки". Для ликвидации такого на одном из элементов управления (Надпись), в исходный код приложения, в оконную функцию был добавлен следующий код
Код: Выделить всё
      case WM_CTLCOLORSTATIC:
      {
         TCHAR Class[64] = TEXT("");
         GetClassName((HWND)lParam, Class, 64);
         if((0 == lstrcmp(Class, TEXT("Static"))))
         {
            SetBkMode((HDC)wParam, TRANSPARENT);
            return (LRESULT)GetStockObject(NULL_BRUSH);
         }
      }
      break;

Вот что получилось
4_ThemeOn_StaticSaveWindow_Man.png
4_ThemeOn_StaticSaveWindow_Man.png (14.06 Кб) Просмотров: 2127

И при классической теме
5_ThemeOff_StaticSaveWindow_Man.png
5_ThemeOff_StaticSaveWindow_Man.png (6.53 Кб) Просмотров: 2127

Не будь хака с WM_CTLCOLORSTATIC , окно выглядело б так же как на первом скрине, но с отображаемым элементом управления Ссылка.

Собственно правильный ли путь выбран? Дело в том, что если добавить прокрутку окну или текстовое поле с прокруткой, то при использования последней (прокрутки) будет наблюдаться интересный эффект: смазывания (захлёста предыдущего “кадра” в новый).

P.S.
Оба примера (с case WM_CTLCOLORSTATIC: и без) компилировались с командной строки.

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

Вот по некоторым темам (дабы не подымать их) хотел дать пару комментариев
Стиль windows XP
InitCommonControls из "comctl32" не поможет ибо Under Comctl32.dll version 6.0 and later, InitCommonControls does nothing. >>

Re: Современное оформление приложений на VB6 под XP
Другое дело, что использовать промежуточный контейнер решили ещё тогда, когда визуальных стилей XP не существовало в природе. И с появлением визуальных стилей эти контейнеры дали о себе знать, как минимум своей непрозрачностью...

Любопытно, слово "непрозрачностью" использовано в значении технологии, однако для приведённого в этой теме случая подходит полностью по своему прямому назначению.

Там же, не понятно, с каким параметром werbersoft предлагал запускать InitCommonControlsEx из "comctl32.dll".
Со всей ответственностью говорю, что в Visual С++ было достаточно и манифеста. Но в данном примере есть вызов по запросу ICC_LINK_CLASS.

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16074
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Как задать прозрачность для заднего фона элемента управл

Сообщение Хакер » 03.09.2011 (Сб) 21:29

Предлагаю вылождить весь тестовый исходник, чтобы над ним можно было «поработать».
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

Admiralisimys
Постоялец
Постоялец
 
Сообщения: 315
Зарегистрирован: 01.06.2009 (Пн) 10:26

Re: Как задать прозрачность для заднего фона элемента управл

Сообщение Admiralisimys » 03.09.2011 (Сб) 22:37

Хакер вот исходник (изначально планировал писать как для форумного варианта, но два класса (SystemFont, UserControl) взял с другого проекта).
Window and Controls_Src.zip
(9.2 Кб) Скачиваний: 105

Как и говорил ранее, бинарники (с WM_CTLCOLORSTATIC и без)
Window and Controls_Bin(Redist).zip
(78.78 Кб) Скачиваний: 111

собирал с командной строки
Код: Выделить всё
cd .\msvc9
cl.exe "..\File.cpp" "..\SystemFont.cpp" "..\UserControl.cpp" "..\Window and Controls.cpp" "..\winmain.cpp" Kernel32.lib User32.lib Gdi32.lib /EHs /D "WIN32" /D "_WINDOWS" /Fo"..\trash\Debug\\" /link /OUT:"..\bin\Debug\Window and Controls.exe"
cl.exe "..\File.cpp" "..\SystemFont.cpp" "..\UserControl.cpp" "..\Window and Controls.cpp" "..\winmain.cpp" Kernel32.lib User32.lib Gdi32.lib /EHs /D "WIN32" /D "_WINDOWS" /D "SAVE_STATIC" /Fo"..\trash\Debug\\" /link /OUT:"..\bin\Debug\Window and Controls_SaveStatic.exe"

Вместо перехода в папку с проектом для Visual C++ 2008 (cd .\msvc9) можно перейти в любую подпапку проекта, лишь бы относительные пути в командой строке не порушить.

Для воссоздания тех же условий при сборки из студии в исходный код (например где нибудь в начале файла winmain.cpp(.h)) нужно добавить генерацию именно этого манифеста
Код: Выделить всё
#pragma comment(linker, "/MANIFESTDEPENDENCY:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")


P.S.
Вот не вместившийся скрин (ограничение на количество вложений в 5 файлов на один пост)
Не будь хака с WM_CTLCOLORSTATIC, окно выглядело б...

6_ThemeOff_StandartWindow_Man.png
6_ThemeOff_StandartWindow_Man.png (6.42 Кб) Просмотров: 2084

P.S.S.
Между прочем такая проблема встречается и в некотором фирменном ПО
Blank at White_VirtualBox 4.0.PNG
Blank at White_VirtualBox 4.0.PNG (88.17 Кб) Просмотров: 2084
Последний раз редактировалось Admiralisimys 03.09.2011 (Сб) 22:40, всего редактировалось 1 раз.

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16074
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Как задать прозрачность для заднего фона элемента управл

Сообщение Хакер » 03.09.2011 (Сб) 22:39

Давай так: статики и чекбоксы — дети фрейма или дети окна?
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

Admiralisimys
Постоялец
Постоялец
 
Сообщения: 315
Зарегистрирован: 01.06.2009 (Пн) 10:26

Re: Как задать прозрачность для заднего фона элемента управл

Сообщение Admiralisimys » 03.09.2011 (Сб) 22:44

Окна.
Кстати хороший вопрос, там с игрой в окне wcl.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); и wcl.hbrBackground = (HBRUSH)(COLOR_WINDOW); были кое-какие сомнения (без +1 отход от примера с MSDN).
В данном примере элемент Вкладки становится задним фоном.

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16074
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Как задать прозрачность для заднего фона элемента управл

Сообщение Хакер » 03.09.2011 (Сб) 23:11

Есть просто такая мысль: берём какой-нибудь системный диалог, где есть таб + фрейм + чекбокс, и анализируем разницу между своим и системным.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.


Вернуться в Windows-программирование

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 1

    TopList