Как получить цвет шрифта заголовка темы TGroupBox

Я хотел бы получить цвет шрифта заголовка TGroupBox, чтобы я мог назначить этот цвет TLabel.

Думаю, мне нужно использовать GetThemeColor, но Я не могу понять, какие параметры использовать?


Обновление. Это код, который я использую на основе ответа:

function GetGroupBoxTextColor: TColor;
var
  C: COLORREF;
  ElementDetails: TThemedElementDetails;
begin
  Result := clWindowText;
  if ThemeServices.ThemesEnabled then
  begin
    ElementDetails := ThemeServices.GetElementDetails(tbGroupBoxNormal);
    if GetThemeColor(ThemeServices.Theme[teButton], ElementDetails.Part, ElementDetails.State, TMT_TEXTCOLOR, C) = S_OK then
      Result := C;
  end;
end;

person ZigiZ    schedule 25.11.2012    source источник


Ответы (1)


Я думаю, что это работает:

var
  h: HTHEME;
  clr: COLORREF;
begin
  h := OpenThemeData(Handle, 'BUTTON');
  if h <> 0 then
    try
      OleCheck(GetThemeColor(h, BP_GROUPBOX, GBS_NORMAL, TMT_TEXTCOLOR, clr));
    finally
      CloseThemeData(h);
    end;

(использует OleAuto, UxTheme)

person Andreas Rejbrand    schedule 25.11.2012
comment
К чему относится Handle? форма? - person ZigiZ; 25.11.2012
comment
@ZigiZ, да, скорее всего, это дескриптор формы. - person TLama; 25.11.2012
comment
@ user539484: Спасибо, что указали на это. К сожалению, я всегда считал, что это правильный способ делать что-то, и я не уверен, что мне следует делать вместо этого. Пожалуйста, дополните. - person Andreas Rejbrand; 25.11.2012
comment
Я использую то же самое, и теперь я тоже немного смущен. Ни в OpenThemeData, ни в CloseThemeData ссылках явно не говорится, что вы должны закрыть этот дескриптор. Но примечание в CloseThemeData я понимаю, что вы должны вызывать его, когда окно, использующее дескриптор темы для своего рендеринга, уничтожается (или когда получено сообщение WM_THEMECHANGED). Итак, я бы сказал, что его следует воспринимать как дескриптор другого системного объекта - когда вы его открываете, позаботьтесь о его закрытии, и в этом случае мы используем самый безопасный способ. @ user539484, что вы думаете? - person TLama; 25.11.2012
comment
@Andreas, самый простой способ обходного решения это, ИМХО, использовать то, что ZigiZ показал в своем обновлении ответа, и просто попросить ThemeServices (теперь устарело) дать вам Theme дескриптор указанного элемента. Затем ThemeServices позаботится о том, чтобы закрыть все открытые дескрипторы при завершении Themes модуля. - person TLama; 25.11.2012
comment
Что ж, эта конструкция кода подразумевает, что GetThemeColor может генерировать исключение, но не может. Вместо этого он может возвращать отрицательное значение HRESULT, регистр которого никогда не проверяется. @TLama, здесь все как обычно, вы приобрели объект - вы несете ответственность за его выпуск. - person OnTheFly; 25.11.2012
comment
Похоже, не имеет значения, вызываете ли вы CloseThemeData или нет. OpenThemeData возвращает какой-то псевдодескриптор, и закрытие данных темы не оказывает никакого влияния на дескриптор, который позже будет открыт. Возможно, было бы важно, если бы вы закрыли данные темы в последнем окне системы (для этого примера). - person Sertac Akyuz; 25.11.2012
comment
Лично я не верю, что утечка HTHEME может вызвать какой-либо хаос, но я бы все равно написал такой код, потому что это хорошая привычка :-) - person OnTheFly; 25.11.2012
comment
@Andreas Rejbrand, просто окружите вызов OleCheck, и фрейм исключения найдет свое применение. - person OnTheFly; 25.11.2012