Прозрачный фон элемента управления xp-themed - PullRequest
4 голосов
/ 19 декабря 2010

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

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

Dialog window containing two UI-buttons in the middle: 'OK' and 'Cancel'. Though the buttons are a default off-white, most of the inside area of the dialog-box has a shocking bright blue background.

Ответы [ 2 ]

6 голосов
/ 29 декабря 2010

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

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

Transparent Buttons Sample in Windows Vista

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

Transparent Buttons Sample in Windows XP

И код, которыйЯ использовал для создания вышеупомянутого эффекта почти смехотворно просто.Добавьте это к процедуре главного окна вашего приложения (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;
      }

      // ...
   }
}

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

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

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

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

0 голосов
/ 19 декабря 2010

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

case WM_CTLCOLORBTN:
    return (LRESULT)hBgColor;
break;

, где hBgColor - это HBRUSH, например:

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

Как я уже говорил, это на самом деле не делает фон элемента управления прозрачным - он просто устанавливает его в заданный цвет.
РЕДАКТИРОВАТЬ: Извините, я сделал ошибку раньше. Я написал LPARAM вместо LRESULT. Теперь это правильно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...