views:

268

answers:

6

I'm using delphi 2010

+1  A: 

A simple trick: make the button color white, shrink it to the minimum size, only the button; and put a transparent label behind it.

Otherwise, to make a button really transparent you need to owner draw it. You may find some examples in the web.

I found some information on responding to the WM_CTLCOLOR message. But I gave a quick try but couldn't quite get it to work.

PA
Hm... You do know that a radio button is rount, not square, right? So even if we neglect the label, the radio button will still be a problem.
Andreas Rejbrand
A: 

The easiest way is to buy a component set like Raize Components which will do this for you and lots more besides. Raize in particular allows you to customize lots of aspects of the UI.

mj2008
I hope to use the same radiobutton that comes with Delphi
O Engenheiro
Yes, which is only a wrapper for the Win32 button, of course.
Andreas Rejbrand
@Andreas - No it isn't. If you saw the source and the complication of doing transparency, you'd know it is no plain wrapper.
mj2008
@mj2008: You are wrong. I have studied the VCL and RTL source code rather carefully for years, and all the standard controls - TButton, TRadioButton, TCheckBox, TListBox, etc., are all standard windows controls. It would be bad if they weren't. But of course, in order to make the VCL controls fit into the framework of the Visual Component Library, there is a lot of custom code around them. But in the end, these controls are just plain Windows controls, which you can SendMessage to, and create with CreateWindow.
Andreas Rejbrand
The OP didn't say they don't want 3rd party components, and the Raize components are not only powerful but also cheap for what they do. So why the down-voting? +1 from me...
Cosmin Prund
@Andreas If I'm wrong, why is the question here? Maybe you haven't tried to use complex background bitmaps, with panels and groups and such items. Sure, the standard stuff works fine for simple purposes, but if complicated you need a good solution. Raize provided that for me.
mj2008
The only thing I am saying is that a TRadioButton creates a pure Win32 radio button control, i.e. a TRadioButton does not do its own, Embarcadero-designed rendering and has its own custom behaviour, but it eventuelly only creates a Win32 button control. You could equally well create such a button using CreateWindow and control it using SendMessage and the other Win32 API functions. The VCL control simply does this for you. I think we all can agree on that! And I have never said anything else!
Andreas Rejbrand
@Cosmin The question is about to make TRadioButton transparent. Buy a 3rd party component, for me, is not make TRadioButton transparent.The answer for me is not useful. Just this.
O Engenheiro
A: 

http://www.torry.net/quicksearchd.php?String=transparent+radiobutton&Title=No might help. None of those are D2010 or D2009, but I believe porting would be possible.

Im0rtality
+1  A: 

Quote Remy Lebeau (TeamB):

TLabel is a TGraphicControl descendant, and thus has to do all of its own drawing manually, so it can implement transparency as needed. TCheckBox and TRadioButton, on the other hand, are TWinControl descendants that wrap standard Win32 API controls, and thus are subject to whatever capabilities the OS supports for them (transparency is not one of them). https://forums.codegear.com/thread.jspa?threadID=24027&tstart=375

You either need to do some heavy overriding, or else you will need to use a third party component...

Jørn E. Angeltveit
+1  A: 

I experimented with the standard VCL TRadioButton control in Delphi 2009 (I suppose Delphi 2010 is the same).

If you compile the project with runtime themes enabled (Project->Options->Application->Enable Runtime Themes), the TRadioButton control is transparent and its 'Color' property ignored. If the runtime themes disabled, the TRadioButton control is not transparent and its background is defined by its 'Color' property.

So I assume that the standard VCL TRadioButton (and the underlying windows control) is made transparent by the Windows theme, not by the control itself. You can switch off the theme support on application level, and in that case you get a non-transparent radio button. If you need a transparent radiobutton with runtime themes disabled, use 3rd party custom radiobutton (TCustomControl descendant, not a standard Windows radiobutton wrapper)

Serg
+1  A: 

I agree with Andreas and Serg in that the control is transparent when themes are enabled.

I, once, had tried to make the CheckBox transparent for when runtime themes are not enabled in project options, or a classic theme is selected with the OS; the result was not perfect. The below is the same code applied to the RadioButton.

Problems easily noticable are, as you would guess from the code, it's a bit flickery and it is not transparent when DoubleBuffered. A problem not easily noticable can (sometimes) be duplicated by bringing a different window in front of the form containing the controls, and then slowly moving it aside, sometimes this leaves some artifacts.

Well, anyway, here it is;

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;
Sertac Akyuz
For me works very well! Thanks Sertac!
O Engenheiro