Solved

Transparent TPanel

Posted on 2004-04-11
4
9,596 Views
Last Modified: 2013-11-23
How can I make a TPanel in Delphi 5 transparent?  Or at least copy the area of the TForm behind the TPanel and paint it to the TPanel canvas?  I need to be able to do this without using a third-party component.

Rich
0
Comment
Question by:coondog091800
4 Comments
 
LVL 7

Expert Comment

by:sftweng
ID: 10804287
Try this:

  Panel1.Brush.Style := bsClear;
  SetWindowLong(Panel1.Handle, GWL_EXSTYLE, WS_EX_TRANSPARENT);
0
 
LVL 1

Author Comment

by:coondog091800
ID: 10807855
That had no effect.  The panel still showed.
0
 
LVL 26

Accepted Solution

by:
EddieShipman earned 250 total points
ID: 10808089
Try this, posted to the Borland Newsgroups by Josh Breitbach:

TSkinPanel = Class (TCustomPanel)
    Private
      Procedure WMEraseBkGnd (Var Msg : TWMEraseBkGnd); Message WM_ERASEBKGND;

    Protected
      Procedure Paint; Override;

    Public
      Constructor Create ( AOwner : TComponent); Override;
      Destructor Destroy; Override;
  End;




{------------------------------------------------------------------------------}
Constructor TSkinPanel.Create ( AOwner : TComponent);
Begin
  Inherited Create (AOwner);

  Width := 100;
  Height := 100;
End;
{------------------------------------------------------------------------------}
Destructor TSkinPanel.Destroy;
Begin
  Inherited Destroy;
End;
{------------------------------------------------------------------------------}
Procedure TSkinPanel.Paint;

Var
  TheClientRect : TRect;
  SaveIndex : Integer;

Begin

  { This code will re-paint the parent panel }
  { This way, you may have 1 trans panel on another }
  SaveIndex := SaveDC (Canvas.Handle);
  MoveWindowOrg (Canvas.Handle, -Left, -Top);
  Parent.Perform (WM_PAINT, Canvas.Handle, 0);
  RestoreDC (Canvas.Handle, SaveIndex);


  TheClientRect := ClientRect;

  { Do your drawing here }


End;
{------------------------------------------------------------------------------}
Procedure TSkinPanel.WMEraseBkGnd (Var Msg : TWMEraseBkGnd);
Begin
  Msg.Result := 0;
End;
{------------------------------------------------------------------------------}


or this one by Serge Gubenko

TMyTransparentPanel = class(TPanel)
  protected
    procedure CreateParams(var Params: TCreateParams); override;
    procedure Paint; override;
    end;

{...}

procedure TMyTransparentPanel.CreateParams(var Params: TCreateParams);
begin
  inherited CreateParams(Params);
  if not (csDesigning in ComponentState)
    then Params.ExStyle:=Params.ExStyle or WS_EX_TRANSPARENT;
  end;

procedure TMyTransparentPanel.Paint;
var
  XBitMap: TBitMap;
  XOldDC: HDC;
  XRect: TRect;
begin
{This panel will be transparent only in Run Time}
  if (csDesigning in ComponentState)
    then inherited Paint
  else begin
    XRect:=ClientRect;
    XOldDC:=Canvas.Handle;
    XBitMap:=TBitMap.Create;
    try
      XBitMap.Height:=Height; XBitMap.Width:=Width;
      Canvas.Handle:=XBitMap.Canvas.Handle;
      inherited Paint;
      RedrawWindow(Parent.Handle, @XRect, 0,
                   RDW_ERASE or RDW_INVALIDATE or
                   RDW_NOCHILDREN or RDW_UPDATENOW);
    finally
      Canvas.Handle:=XOldDC;
      Canvas.BrushCopy(XRect, XBitMap, XRect, Color);
      XBitMap.Free;
      end;
    end;
  end;

or this one by Peter Below:

unit TransparentPanel;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
Dialogs,
  ExtCtrls;

type
  TTransparentPanel = class(TPanel)
  private
    { Private declarations }
    FBackground: TBitmap;

    Procedure WMEraseBkGnd( Var msg: TWMEraseBkGnd );
      message WM_ERASEBKGND;
  protected
    { Protected declarations }
    Procedure CaptureBackground;
    Procedure Paint; override;
  public
    { Public declarations }
    Procedure SetBounds(ALeft, ATop, AWidth, AHeight: Integer); override;
    property Canvas;
    Constructor Create( aOwner: TComponent ); override;
    Destructor Destroy; override;
  published
    { Published declarations }
  end;

procedure Register;

implementation

procedure Register;
begin
  RegisterComponents('PBGoodies', [TTransparentPanel]);
end;

{ TTransparentPanel }

procedure TTransparentPanel.CaptureBackground;
var
  canvas: TCanvas;
  dc: HDC;
  sourcerect: TRect;
begin
  FBackground := TBitmap.Create;
  with Fbackground do begin
    width := clientwidth;
    height := clientheight;
  end; { with }
  sourcerect.TopLeft := ClientToScreen(clientrect.TopLeft);
  sourcerect.BottomRight := ClientToScreen( clientrect.BottomRight );
  dc:= CreateDC( 'DISPLAY', nil, nil, nil );
  try
    canvas:= TCanvas.Create;
    try
      canvas.handle:= dc;
      Fbackground.Canvas.CopyRect( clientrect, canvas, sourcerect );
    finally
      canvas.handle := 0;
      canvas.free;
    end; { finally }
  finally
    DeleteDC( dc );
  end; { finally }
end;

constructor TTransparentPanel.Create(aOwner: TComponent);
begin
  inherited;
  ControlStyle := controlStyle - [csSetCaption];
end;

destructor TTransparentPanel.Destroy;
begin
  FBackground.free;
  inherited;
end;

procedure TTransparentPanel.Paint;
begin
  if csDesigning In ComponentState Then
    inherited
  // would need to draw frame and optional caption here
  // do NOT call inherited, the control fills its client area if you do!
end;

procedure TTransparentPanel.SetBounds(ALeft, ATop, AWidth,
  AHeight: Integer);
begin
  if Visible and HandleAllocated and not (csDesigning In
ComponentState) then begin
    Fbackground.Free;
    Fbackground := Nil;
    Hide;
    inherited;
    Parent.Update;
    Show;
  end
  else
    inherited;
end;

procedure TTransparentPanel.WMEraseBkGnd(var msg: TWMEraseBkGnd);
var
  canvas: TCanvas;
begin
  if csDesigning In ComponentState Then
    inherited
  else begin
    if not Assigned( FBackground ) then
      Capturebackground;
    canvas := TCanvas.create;
    try
      canvas.handle := msg.DC;
      canvas.draw( 0, 0, FBackground );
    finally
      canvas.handle := 0;
      canvas.free;
    end; { finally }
    msg.result := 1;
  end;
end;

end.
0
 

Expert Comment

by:smartins
ID: 14973488
So, which one of these 3 methods is best to have the panel show what's behind it?
0

Featured Post

NAS Cloud Backup Strategies

This article explains backup scenarios when using network storage. We review the so-called “3-2-1 strategy” and summarize the methods you can use to send NAS data to the cloud

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
Intraweb submit form as a POST request 4 304
Machine not responding during CopyFile() 3 98
Delphi Form ownership 4 89
Base1 Encode/Decode 3 77
Creating an auto free TStringList The TStringList is a basic and frequently used object in Delphi. On many occasions, you may want to create a temporary list, process some items in the list and be done with the list. In such cases, you have to…
Introduction Raise your hands if you were as upset with FireMonkey as I was when I discovered that there was no TListview.  I use TListView in almost all of my applications I've written, and I was not going to compromise by resorting to TStringGrid…
Nobody understands Phishing better than an anti-spam company. That’s why we are providing Phishing Awareness Training to our customers. According to a report by Verizon, only 3% of targeted users report malicious emails to management. With compan…

778 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question