Сохранить TPanel как изображение на диске

У меня есть компонент TPanel в одной из моих форм. У этой панели много дочерних элементов, таких как TLabel, TImage, TLine, TPanel и т. д. Эта панель используется для обновления по таймеру. Я хочу сделать скриншот этой панели в любое время. Когда я использую только TPanel.MakeScreenshot, он показывает только дочерние элементы, такие как TImage и TLine. TLables отсутствуют.

Кто-нибудь знает, как этого можно достичь.

Я использую Delphi XE5 и firemonkey.

Спасибо.


person Padam    schedule 20.06.2014    source источник
comment
Только что попробовал небольшой тест с XE5/XE6, без проблем захватывает TLabel. Вы должны предоставить более подробную информацию о вашем проекте/форме. Если это невозможно воспроизвести, то, я думаю, вам будет невозможно помочь.   -  person Andrei Galatyn    schedule 20.06.2014
comment
TPanel в моем случае является своего рода динамическим дочерним элементом. Дети TPanel постоянно обновляются фоновым потоком.   -  person Padam    schedule 20.06.2014
comment
Поместите в описание всю информацию, необходимую для воспроизведения проблемы. Попробуйте самостоятельно воспроизвести его в новом проекте со всеми настройками по умолчанию, используя только предоставленное вами описание.   -  person Andrei Galatyn    schedule 20.06.2014
comment
Возможно ли, чтобы TLabels создавались в коде, а не помещались в форму в среде IDE? Если это так, возможно, вы неправильно их воспитываете. Они могут отображаться на экране, но не привязаны к TPanel. Я бы отбрасывал метки на форму в IDE, а затем в OnCreate формы задавал им пустую строку или любое другое начальное значение. Если вы используете многопоточность для их обновления, вы можете либо получить к ним доступ напрямую через какой-то критический раздел, либо отправить сообщение в форму, которую она может использовать для их обновления сама. Лично я бы пошел с последним.   -  person David Schwartz    schedule 20.06.2014


Ответы (1)


У меня была похожая проблема однажды при создании компонента для захвата содержимого TLayout. В тестах некоторые компоненты не отображались на снимках экрана, сделанных с помощью TLayout.MakeScreenshot.

Это связано с тем, что когда вы создаете TLabel в коде, он не рисуется автоматически, когда вы делаете его родительским для TPanel. Он рисуется только тогда, когда его действительно показывают в первый раз. Следовательно, если вы сделаете что-то подобное, метка не будет отображаться:

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;

Чтобы метки отображались, вы должны заставить их рисовать на холсте TPanel. Я сделал это с помощью метода ApplyStyleLookup, например:

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

Вам нужно будет вызвать ApplyStyleLookup для каждой метки, чтобы они появились.

Это то же самое, если вы установите для AutoSize TLabel значение true и установите текст. Ширина метки не изменится до того, как она будет фактически показана в форме.
Я не просматривал это подробно в исходном коде FMX, но, вероятно, это где-то ошибка, потому что она влияет только на некоторые компоненты.

Вы не показали свой код, поэтому я не уверен, что это та же проблема, но звучит так.

Кстати, вы, вероятно, знаете, что вы не можете обновлять элементы управления FMX напрямую из другого потока, потому что они не являются потокобезопасными, верно? И вы также бесплатно возвращаете TBitmap из MakeScreenshot?

person VGeorgiev    schedule 30.06.2014