Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Transparent group box

I have inherited from TGroupBox of the Delphi native control and overriden its Paint method to draw rounded rectangle.

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

After overriding the Create params, the Paint method is as below.

   procedure TclTransparentGroupBox.Paint;
   begin
     // Draw the rounded rect to show the group box bounds
     Canvas.Pen.Color := clWindowFrame;
     Canvas.RoundRect(5, 15, ClientRect.Right - 5, ClientRect.Bottom - 5, 10, 10);
     if Caption <> EmptyStr then
     begin
       Canvas.Brush.Style := bsClear;
       Canvas.TextOut(10, 0, Caption);
     end;
   end;

The major problem i m facing is that, i have few labels on top of the transparent group box. When i open the form the labels look fine, but when the text changes, some bounding rectangles of the labels will be visible. This is looking weird on top of transparent box.

Even when i resize the form, the group box itself disappears, when i change the focus to another application and bring back my application, the group box draws itself.

Am i missing anything with respect to drawing? Any windows messages that i need to take care of???

Thanks in advance Rahul

like image 619
Rahul W Avatar asked Jan 19 '12 14:01

Rahul W


1 Answers

To make a control transparent you have to :

Make it non-opaque

ControlStyle := ControlStyle - [csOpaque]

Handle WM_ERASEBKGND:

procedure TTransPanel.WM_ERASEBKGND(var Msg: TWM_ERASEBKGND); 
var
    SaveDCInd: Integer;
    Position: TPoint;
begin
    SaveDCInd := SaveDC(Msg.DC); 
    //save device context state (TCanvas does not have that func)
    GetViewportOrgEx(Msg.DC, Position);
    SetViewportOrgEx(Msg.DC, Position.X - Left, Position.Y - Top, nil);
    IntersectClipRect(Msg.DC, 0, 0, Parent.ClientWidth, Parent.ClientHeight);
    try
        Parent.Perform(WM_ERASEBKGND, Msg.DC, 0 );
        Parent.Perform(WM_PAINT, Msg.DC, 0);
        //or
        // Parent.Perform(WM_PRINTCLIENT, Msg.DC, prf_Client); //Themeing
    except
    end;       
    RestoreDC(Msg.DC, SaveDCInd);
    Canvas.Refresh;       
    Msg.Result := 1; //We painted out background
end;

In the proc above you first save device context state, then draw the canvas of our parent (TForm maybe) onto our canvas (TGroupBox). At the end restore DC and return 1 to indicate that we did paint the background.

like image 112
Mihaela Avatar answered Oct 30 '22 15:10

Mihaela