Solved

Transparent TPanel

Posted on 2004-04-11
4
9,569 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
Comment Utility
Try this:

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

Author Comment

by:coondog091800
Comment Utility
That had no effect.  The panel still showed.
0
 
LVL 26

Accepted Solution

by:
EddieShipman earned 250 total points
Comment Utility
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
Comment Utility
So, which one of these 3 methods is best to have the panel show what's behind it?
0

Featured Post

What Security Threats Are You Missing?

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

Join & Write a Comment

Have you ever had your Delphi form/application just hanging while waiting for data to load? This is the article to read if you want to learn some things about adding threads for data loading in the background. First, I'll setup a general applica…
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…
Internet Business Fax to Email Made Easy - With eFax Corporate (http://www.enterprise.efax.com), you'll receive a dedicated online fax number, which is used the same way as a typical analog fax number. You'll receive secure faxes in your email, fr…
You have products, that come in variants and want to set different prices for them? Watch this micro tutorial that describes how to configure prices for Magento super attributes. Assigning simple products to configurable: We assigned simple products…

771 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

Need Help in Real-Time?

Connect with top rated Experts

12 Experts available now in Live!

Get 1:1 Help Now