• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 318
  • Last Modified:

TImage problem

TImage problem

How to put components to TImage and save them as picture file, if components are hided (on TForm) or visible:=false ?

Thank You.
0
zuipo
Asked:
zuipo
  • 2
1 Solution
 
DeerBearCommented:
Hi,

To do this you need to get a snapshot of the control, not an easy task.
Looking into JCL sources, you will find a ScreenShot routine that you can use as a base to derive your own code.

HTH,

Andrew
0
 
zuipoAuthor Commented:
Thank You, DeerBear !

Can You give me example for screenshot.

I tried :

screenshot(Image1.Picture.Bitmap,0,0,100,100,BitBtn1);

and Delphi shows me this error :

[Error] Unit1.pas(29): There is no overloaded version of 'ScreenShot' that can be called with these arguments
0
 
Pierre CorneliusCommented:
The problem is that various controls have different ways of rendering themselves on the screen. e.g. Descendents of TWinControl could have a PainTo method which you can use to paint to any canvas but even this I couldn't get working properly. When using this method on a TEdit for example, it painted the edit box, but not the text inside it.

I reckon your best bet is to let the controls draw themselves (they know their individual ways of how to do it) and then capture the screen.

I've put together a new form class for you that can do this. It captures the entire screen when you close the form, but you could customise it to capture each control in a separate bitmap if you wish simply modify the BitBlt function parameters accordingly using the controls Top, left, width and height properties.

To do:
1.) Create a new application
2.) drop a TButton on it and assign the following to its OnClick event:
         
            procedure TForm1.Button1Click(Sender: TObject);
            begin
                  with TShowInvisibleControls.Create(self) do Show;
            end;

3.) Add the following to your units type declaration interface:

  TShowInvisibleControls = class(TCustomForm)
  private
    procedure Show;
    procedure Showmodal; reintroduce;
  public
    constructor Create(AOwner: TForm); reintroduce;
    procedure DoOnClose(Sender: TObject; var Action: TCloseAction);
  end;

4.) Add the following to your implementation section of the unit:

{ TShowInvisibleControls }

constructor TShowInvisibleControls.Create(AOwner: TForm);
begin
  //no different, only enforcing a TForm as the owner
  CreateNew(AOwner);
  Caption:= 'Invisible Controls on Form:' +TForm(AOwner).Name;
  Width:= TForm(Owner).Width;
  Height:= TForm(Owner).Height;
  Position:= poDesktopCenter;
  OnClose:= DoOnClose;
end;

procedure TShowInvisibleControls.Show;
begin
  //only allow modal state because controls parents must be
  //reset to the owner when finished
  ShowModal;
end;

procedure TShowInvisibleControls.Showmodal;
var i: integer;
    InvisibleControls: array of TControl;
begin
  //get the invisible controls
  for i:= 0 to TForm(Owner).ControlCount-1 do
  begin
    if (NOT TForm(Owner).Controls[i].Visible) then
    begin
      SetLength(InvisibleControls, Length(InvisibleControls)+1);
      InvisibleControls[Length(InvisibleControls)-1]:= TForm(Owner).Controls[i];
    end;
  end;

  try
    //Become parent for the invisible controls
    for i:= low(InvisibleControls) to High(InvisibleControls) do
    begin
      InvisibleControls[i].Parent:= self;
      InvisibleControls[i].Visible:= true;
    end;

    inherited ShowModal;

  finally
    //reset controls parent to the owner
    for i:= low(InvisibleControls) to High(InvisibleControls) do
    begin
      InvisibleControls[i].Visible:= false;
      InvisibleControls[i].Parent:= TForm(Owner);
    end;
    Free;
  end;

end;


procedure TShowInvisibleControls.DoOnClose(Sender: TObject; var Action: TCloseAction);
var SaveDlg: TSaveDialog;
    bmp: TBitmap;
begin
  SaveDlg:= tSaveDialog.Create(self);
  SaveDlg.Filter:= 'Bitmap *.bmp|*.bmp';
  if SaveDlg.Execute then
  begin
    bmp:= TBitmap.Create;
    bmp.Width:= self.ClientWidth;
    bmp.Height:= self.ClientHeight;
    BringToFront;
    Repaint;
    bitblt(bmp.Canvas.Handle, ClientRect.Left, ClientRect.Top,
           ClientWidth, ClientHeight, self.Canvas.Handle,
           0,0, SRCCOPY);
    bmp.SaveToFile(SaveDlg.FileName);
    bmp.Free;
  end;
  SaveDlg.Free;
end;


One thing I haven't built in is the fact that the controls viewed in the new derived form are live and working. You should consider disabling them to prevent the user from doing anything to or with them.


Kind regards
Pierre Cornelius
0
 
zuipoAuthor Commented:
OK. Thank You.

I'll give all points to

PierreC.
0

Featured Post

Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now