Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Delphi: Bring TImage to front

Look at the image below:

enter image description here

As you can see I cannot send Buttons to back. This only works for labels.

So how can I send TImage to front with its transparency.

By the way I've read This related question but didn't help me. Because you cannot even click on a button after running Andreas Rejbrand's code. Not only buttons, everything (like the scrollbar in this image)

Edit: I don't want to make the button reachable after I send that back to the image. Just want to bring TImage to front of everything.

Thanks.

like image 299
Sky Avatar asked Sep 20 '13 20:09

Sky


2 Answers

One way which could you near the goal would be to use interposer classes for the TWincontrols and paint the image moved on them, after they have been painted already, using a TControlCanvas and "hooking" WM_PAINT.
The code is showing a raw draft using a semitransparent PNG image and may be enhanced.

enter image description here

unit Unit2;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, Buttons, dxGDIPlusClasses, ExtCtrls;

type
  TButton=Class (StdCtrls.TButton)
      Procedure WMPaint(var MSG:TMessage);Message WM_Paint;
  End;
  TEdit=Class (StdCtrls.TEdit)
      Procedure WMPaint(var MSG:TMessage);Message WM_Paint;
  End;

  TForm2 = class(TForm)
    Image1: TImage;
    SpeedButton1: TSpeedButton;
    Button1: TButton;
    Edit1: TEdit;
    Edit2: TEdit;
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form2: TForm2;

implementation

{$R *.dfm}

{ TButton }

procedure TButton.WMPaint(var MSG: TMessage);
var
  cc:TControlCanvas;
begin
   inherited;
    CC:=TControlCanvas.Create;
    CC.Control := TControl(Self);
    CC.Draw(-Left,-Top,Form2.Image1.Picture.Graphic);
    CC.Free;
end;

procedure TEdit.WMPaint(var MSG: TMessage);
var
  cc:TControlCanvas;
begin
   inherited;
    CC:=TControlCanvas.Create;
    CC.Control := TControl(Self);
    CC.Draw(-Left,-Top,Form2.Image1.Picture.Graphic);
    CC.Free;

end;

end.

Another (better) place to "hook" would be overriding PaintWindow

unit Unit2;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, Buttons, dxGDIPlusClasses, ExtCtrls;

type
  TButton=Class (StdCtrls.TButton)
      procedure PaintWindow(DC: HDC);override;
  End;
  TEdit=Class (StdCtrls.TEdit)
      procedure PaintWindow(DC: HDC);override;
  End;

  TForm2 = class(TForm)
    Image1: TImage;
    SpeedButton1: TSpeedButton;
    Button1: TButton;
    Edit1: TEdit;
    Edit2: TEdit;
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form2: TForm2;

implementation

{$R *.dfm}

{ TButton }

procedure TButton.PaintWindow(DC: HDC);
var
  cc:TCanvas;
begin
   inherited;
    CC:=TCanvas.Create;
    CC.Handle := DC;
    CC.Draw(-Left,-Top,Form2.Image1.Picture.Graphic);
    CC.Free;
end;

procedure TEdit.PaintWindow(DC: HDC);
var
  cc:TCanvas;
begin
   inherited;
    CC:=TCanvas.Create;
    CC.Handle := DC;
    CC.Draw(-Left,-Top,Form2.Image1.Picture.Graphic);
    CC.Free;

end;

end.
like image 91
bummi Avatar answered Sep 21 '22 03:09

bummi


You do not want the Image brought to front (which by the way is impossible over a windowed control), because you want the button also reachable.

Although your question is contradicting itself, and it is not at all clear what exactly you want to achieve, I think you mean to have a transparent button over an image.

If so, then use a TSpeedButton, and set its Transparent and Flat property to True.

Here an example with the three button states: normal, hovered, pressed:

enter image description here

like image 45
NGLN Avatar answered Sep 21 '22 03:09

NGLN