Есть ли способ сделать TRadioButton прозрачным? - PullRequest
2 голосов

Ответы [ 6 ]

3 голосов
/ 17 мая 2010

Я согласен с Андреасом и Сергом в том, что элемент управления прозрачен, когда темы включены.

Однажды я попытался сделать CheckBox прозрачным, если темы времени выполнения не включены в настройках проекта или в ОС выбрана классическая тема; результат не был идеальным. Ниже приведен тот же код, примененный к RadioButton.

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

Ну, во всяком случае, вот оно;

type
  TMyRadioButton = class(TRadioButton)
  private
    procedure CnCtlColorStatic(var Msg: TWMCtlColorStatic); message CN_CTLCOLORSTATIC;
    procedure WmEraseBkgnd(var Msg: TWMEraseBkgnd); message WM_ERASEBKGND;
    procedure WmPaint(var Msg: TWMNCPaint); message WM_PAINT;
  protected
    procedure CreateParams(var Params: TCreateParams); override;
  end;

implementation

uses
  themes;

procedure TMyRadioButton.CreateParams(var Params: TCreateParams);
begin
  inherited CreateParams(Params);
  Params.ExStyle := Params.ExStyle or WS_EX_TRANSPARENT;
end;

procedure TMyRadioButton.WmPaint(var Msg: TWMNCPaint);
begin
  if not (ThemeServices.ThemesEnabled or DoubleBuffered) then
    InvalidateRect(Handle, nil, True);
  inherited;
end;

procedure TMyRadioButton.WmEraseBkgnd(var Msg: TWMEraseBkgnd);
var
  R: TRect;
begin
  if not (ThemeServices.ThemesEnabled or DoubleBuffered)
       and (Parent <> nil) then begin
    R := Rect(Left, Top, Left + Width, Height + Top);
    InvalidateRect(Parent.Handle, @R, True);
    UpdateWindow(Parent.Handle);
    Msg.Result := 1;
  end else
    inherited;
end;

procedure TMyRadioButton.CnCtlColorStatic(var Msg: TWMCtlColorStatic);
begin
  if not (ThemeServices.ThemesEnabled or DoubleBuffered) then begin
    SetBKMode(Msg.ChildDC, TRANSPARENT);
    Msg.Result := GetStockObject(NULL_BRUSH);
  end else
    inherited;
end;
2 голосов
/ 16 мая 2010

Цитата Реми Лебо (TeamB):

TLabel - это TGraphicControl потомок, и, следовательно, должен сделать все свой собственный рисунок вручную, так что он может реализовать прозрачность по мере необходимости. TCheckBox и TRadioButton, на С другой стороны, это TWinControl потомки, которые заворачивают стандарт Win32 Элементы управления API и, следовательно, подлежат все возможности, поддерживаемые ОС для них (прозрачность не является одним из их). https://forums.codegear.com/thread.jspa?threadID=24027&tstart=375

Вам либо нужно сделать серьезное переопределение, либо вам придется использовать сторонний компонент ...

1 голос
/ 16 мая 2010

Я экспериментировал со стандартным элементом управления VCL TRadioButton в Delphi 2009 (полагаю, что Delphi 2010 такой же).

Если вы компилируете проект с включенными темами выполнения (Project-> Options-> Application-> Enable Runtime Themes), элемент управления TRadioButton будет прозрачным, а его свойство 'Color' игнорируется. Если темы выполнения отключены, элемент управления TRadioButton не является прозрачным, а его фон определяется свойством Color.

Таким образом, я предполагаю, что стандартный VCL TRadioButton (и базовый элемент управления Windows) сделан прозрачным темой Windows, а не самим элементом управления. Вы можете отключить поддержку темы на уровне приложения, и в этом случае вы получите непрозрачный переключатель. Если вам нужна прозрачная кнопка с отключенными темами выполнения, используйте стороннюю пользовательскую кнопку (потомок TCustomControl, а не стандартную оболочку для кнопки Windows)

1 голос
/ 17 марта 2010

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

В противном случае, чтобы сделать кнопку действительно прозрачной, ее нужно нарисовать владельцем. Вы можете найти некоторые примеры в Интернете.

Я нашел некоторую информацию об ответе на сообщение WM_CTLCOLOR. Но я быстро попробовал, но не смог заставить его работать.

0 голосов
/ 15 мая 2010

http://www.torry.net/quicksearchd.php?String=transparent+radiobutton&Title=No может помочь. Ни один из них не D2010 или D2009, но я считаю, что портирование было бы возможно.

0 голосов
/ 17 марта 2010

Самый простой способ - купить набор компонентов, такой как Raize Components , который сделает это за вас и многое другое. Raize, в частности, позволяет настраивать множество аспектов пользовательского интерфейса.

...