Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people, just like you, are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
Solved

Transparent TPanel

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

Free Tool: SSL Checker

Scans your site and returns information about your SSL implementation and certificate. Helpful for debugging and validating your SSL configuration.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

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

Suggested Solutions

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…
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…
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…
In an interesting question (https://www.experts-exchange.com/questions/29008360/) here at Experts Exchange, a member asked how to split a single image into multiple images. The primary usage for this is to place many photographs on a flatbed scanner…

840 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