Solved

Transparent TPanel

Posted on 2004-04-11
4
9,614 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

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
Delphi 2 77
tidtcpserver connection lost handle 2 109
how to update exe applicatio from internet ? 6 91
How to convert memory stream to PDF file 6 169
Introduction The parallel port is a very commonly known port, it was widely used to connect a printer to the PC, if you look at the back of your computer, for those who don't have newer computers, there will be a port with 25 pins and a small print…
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…
A short tutorial showing how to set up an email signature in Outlook on the Web (previously known as OWA). For free email signatures designs, visit https://www.mail-signatures.com/articles/signature-templates/?sts=6651 If you want to manage em…

685 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