Win32 прозрачные элементы управления на всех версиях Windows - PullRequest
5 голосов
/ 13 декабря 2010

Я работаю над Win32 GUI-приложением, используя простой Win32 API (без MFC или .NET). У меня проблема с прозрачностью элементов управления. Я придумал метод, который работает для большинства вещей, в Windows Vista + я делаю это в WndProc:

case WM_CTLCOLORSTATIC:
{
    SetBkMode((HDC)wParam, TRANSPARENT);
    return (INT_PTR)::GetStockObject(NULL_PEN);
}
break;

В Windows XP я делаю это в WndProc:

case WM_CTLCOLORSTATIC:
{
    HBRUSH hbr = (HBRUSH)DefWindowProc(hDlg, message, wParam, lParam);
    ::DeleteObject(hbr);
    SetBkMode((HDC)wParam, TRANSPARENT);
    return (LRESULT)(HBRUSH)(COLOR_WINDOW);
}

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

Есть ли испытанный и проверенный метод для создания прозрачности элементов управления?

Спасибо, J

1 Ответ

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

Для достижения прозрачного контроля вы должны знать, что:

  • Ты не можешь на самом деле. Стандартные элементы управления окнами просто не поддерживают "прозрачную" рисование.
  • Даже если вы все сделаете правильно, диалоговое окно будет сильно мерцать, если вы измените его размер.
  • «Хаки» для получения прозрачного рисования рабочих элементов управления, как правило, различаются, если тематика включена или выключена, и меняются между версиями Windows.

Обычно цель сделать элементы управления "прозрачными", чтобы сквозь них отображалась растровая обложка под элементами управления. Способ достижения этого вида прозрачности заключается в создании растрового изображения для фона элемента управления. Затем используйте CreatePatternBrush из растрового изображения.

Этот фрагмент кода DialogProc реализует самый простой из возможных методов создания скинов, а затем позаботится о рисовании как фона диалога, так и большинства элементов управления, поддерживающих эту форму рисования:

  // _hwnd is the dialogs handle
  // _hbrSkin is a pattern brush handle
  HWND hwndCtl;
  POINT pt;
  HDC hdc;
case WM_CTLCOLORDLG:
  return (INT_PTR)_hbrSkin;
case WM_CTLCOLORSTATIC:
case WM_CTLCOLORBTN:
  hdc = (HDC)wParam;
  SetBkMode(hdc,TRANSPARENT); // Ensure that "static" text doesn't use a solid fill
  pt.x = 0; pt.y = 0;
  MapWindowPoints(hwndCtl,_hwnd,&pt,1);
  SetBrushOrgEx(hdc,-pt.x,-pt.y,NULL);
  return (INT_PTR)_hbrSkin;

Элементы управления, которые перекрываются, будут отображаться неправильно, так как один закрашивает свой «прозрачный» фон поверх другого. Вы можете уменьшить мерцание на:

  • Не позволяет изменить размер диалогового окна.
  • установка стиля WS_EX_COMPOSITED в диалоговом окне, но, поскольку Windows NT 6 DWM не поддерживает его, он по сути бесполезен с Vista на *.
  • Установка стиля WS_CLIPCHILDREN в диалоговом окне и / или WS_CLIPSIBLINGS - эти стили предотвращают использование групповых блоков и элементов управления вкладками, поскольку полагаются на перекрывающиеся элементы управления.
  • создание подклассов всех элементов управления, используя сообщение WM_PRINTCLIENT, чтобы закрасить их в буфер, а затем уничтожить подготовленный буфер за один проход. Тяжелая работа и не все элементы управления поддерживают WM_PRINTCLIENT.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...