Я согласен с Андреасом и Сергом в том, что элемент управления прозрачен, когда темы включены.
Однажды я попытался сделать 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;