Прозрачный фон контроля xp-themed

У меня есть несколько элементов управления windowsми, нарисованные на растровом изображении, а также на цветном фоне в диалоговом окне. Может ли быть какой-то возможный способ прозрачности фона в окне управления? В настоящее время они показывают цветной фон по умолчанию в диалоговом окне.

Пример. Я попытался вставить сплошное синее bitmap, и два элемента управления кнопки имеют заметный цветной прямоугольник по умолчанию.

Диалоговое окно, содержащее два пользовательских интерфейса в середине: «ОК» и «Отмена». Хотя кнопки по умолчанию не совсем белые, большая часть внутренней области диалогового окна имеет потрясающий ярко-синий фон.

Это легко решить, предоставив Windows ручку той кисти, которую вы хотите использовать, чтобы нарисовать фон вашей кнопки. Вы делаете это каждый раз, когда вы получаете сообщение WM_CTLCOLORBTN в WM_CTLCOLORBTN сообщения родительского windows кнопки.

Я высмеял небольшое демо-приложение, которое сравнивает две разные кнопки бок о бок. Оба являются стандартными элементами управления Win32 BUTTON , но один слева обрабатывает сообщение WM_CTLCOLORBTN и указывает кисть с тем же цветом, что и фон windows. Вы можете сразу увидеть разницу – светло-серый (или, точнее, цвет по умолчанию для 3D-элементов управления, COLOR_3DFACE ), окаймляющий прямоугольник кнопки, исчез, и кнопка выглядит намного лучше, чем пользовательский цвет фона:

Прозрачные образцы кнопок в Windows Vista

Эффект также работает в Windows XP с включенными визуальными темами – вот скриншот того же приложения:

Прозрачные образцы кнопок в Windows XP

И код, который я использовал для создания вышеупомянутого эффекта, почти смехотворно прост. Добавьте это в процедуру главного windows приложения ( MainWndProc ), как описано выше. Вам не нужно прикасаться к кнопкам.

 HBRUSH hButtonBackColor = NULL; LRESULT CALLBACK MainWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch(msg) { case WM_CTLCOLORBTN: { if (!hButtonBackColor) { // Create the brush, if it hasn't already been created. // (You can use any type of brush here; this is just an example.) hButtonBackColor = GetSysColorBrush(COLOR_3DDKSHADOW); } return (LRESULT)hButtonBackColor; } // ... } } 

Однако убедитесь, что указанная кисть представляет собой тот же цвет, что и цвет фона вашего windows – прозрачная кисть может работать неправильно. Точно так же для узорной кисти (кто-нибудь больше их использует?), Начало кисти должно быть установлено в соответствии с фоном.

Всегда убедитесь, что вы отпустите любые кисти, созданные вами, вызвав DeleteObject ! В C ++ вы сделаете это, сделав объект CBrush (или эквивалентный) членом вашего classа диалога, чтобы он был автоматически уничтожен. В C вам нужно обработать сообщение WM_NCDESTROY и вручную удалить кисть.

Также обратите внимание, что вам не нужно указывать стиль BS_OWNERDRAW чтобы этот трюк работал. В приведенном выше примере используются два стандартных элемента управления кнопками, созданных с использованием только следующих флажков стиля windows: WS_CHILD , WS_VISIBLE и BS_PUSHBUTTON .

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

Я не знаю, можете ли вы сделать действительно прозрачный фон, но мое решение может помочь вам в любом случае. Я всегда решал это, используя сообщение WM_CTLCOLORBTN в процедуре главного windows.
Предположим, что у нас есть switch , в котором мы обрабатываем сообщения, полученные в главном окне.

 case WM_CTLCOLORBTN: return (LRESULT)hBgColor; break; 

где hBgColor является HBRUSH , например:

 HBRUSH hBgColor=CreateSolidBrush(RGB(0, 0, 255)); 

Как я уже говорил, это не делает прозрачный фон управления прозрачным – он просто устанавливает его на указанный цвет.
EDIT: Извините, я сделал ошибку раньше. Я написал LPARAM вместо LRESULT . Теперь это правильно.