0

I have a TPanel component on one of my form.This panel has lots of children like TLabel,TImage,TLine,TPanel etc.This panel is used to updated on a timer. I want to capture a screenshot of this panel at any time. When I only use TPanel.MakeScreenshot then it is only showing children like TImage and TLine. TLabels are missing.

Does any body has any idea how it can be achieved.

I am using Delphi XE5 and firemonkey.

Thanks.

Johan
  • 74,508
  • 24
  • 191
  • 319
Padam
  • 117
  • 1
  • 7
  • Just tried small test with XE5/XE6, it captures TLabel without any problems. You should provide more details about your project/form. If it is impossible to reproduce, then i guess it will be impossible to help you. – Andrei Galatyn Jun 20 '14 at 10:28
  • the TPanel is a kind of having dynamic children in my case. Children of TPanel are updated by a background thread continuously. – Padam Jun 20 '14 at 11:20
  • Put into description all information required to reproduce the problem. Try to reproduce it in new project with all default settings yourself using only description you provided. – Andrei Galatyn Jun 20 '14 at 11:35
  • Is it possible that the TLabels are created in code rather than dropped on the form in the IDE? If so, you may not be parenting them correctly. They may appear on the screen, but they're not attached to the TPanel. I'd drop the labels on the form in the IDE, then in the form's OnCreate set them to an empty string or whatever the initial value needs to be. If you're using multi-threading to update them, then you can either access them directly through some kind of critical section, or send a message to the form that it can use to update them itself. Personally, I'd go with the latter. – David Schwartz Jun 20 '14 at 14:58

1 Answers1

0

I had a similar problem once when making a component to capture the contents of a TLayout. In the tests some components were not showing in a screenshot taken with TLayout.MakeScreenshot.

This is due to the fact that when you create a TLabel in code it is not automatically painted when you parent it to a TPanel. It is painted only when actually shown for the first time. Hence if you do something like this, the label will not show:

var
  NewLabel: TLabel;
  Shot: TBitmap;
...
  NewLabel := TLabel.Create;
  NewLabel.Parent := Panel1; // I suppose you are setting the parent like this in your code
  NewLabel.Text := 'some new label';
  Shot := Panel1.MakeScreenshot;

To make the labels show you have to make them paint on the TPanel canvas. I did it with the ApplyStyleLookup method like:

  ...
  NewLabel.Text := 'some new label';
  NewLabel.ApplyStyleLookup;
  Shot := Panel1.MakeScreenshot; // Now the label will show

You will have to call ApplyStyleLookup for each label to make them appear.

It is the same if you set AutoSize of the TLabel to true and set the text. The Width of the label will not adjust before it is actually shown on the form.
I haven't looked this up in detail in the FMX source code, but is probably a bug somewhere, because it affects only some components.

You haven't shown your code, so I'm not sure if this is the same problem, but sure sounds like it.

Btw, you probably know that you can't update the FMX controls directly from another thread because they are not thread-safe, right? And you also Free the TBitmap returned from MakeScreenshot?

VGeorgiev
  • 491
  • 5
  • 16