Clipboard
つい先日、Clipboard の記事を見かけて、そういえば Delphi で Clipboard 使うのは簡単すぎて Qiita に書いてないなあと、そして、もしかしたら Berlin から登場している新しい Clipboard サービスを知らない方も居そう!と思って書いてみることに。
※この記事は FireMonkey 向けです。VCL はまた別の方法になります。
IFMXClipboardService
Delphi FireMonkey で Clipboard といえば IFMXClipboardService !
ということで、これを使うと
var Clipboard: IFMXClipboardService;
if
not TPlatformServices.Current.SupportsPlatformService(
IFMXClipboardService,
Clipboard)
then
Exit;
// 値の読み出し T は任意の型
var X := Clipboard.GetClipboard.AsType<T>;
// 値の設定 X は任意の変数
Clipboard.SetClipboard(X);
こんな感じになります。
めっちゃ簡単。
GetClipboad / SetClipboard はどちらも TValue 型の値を読み書きするので、どんな型でも入れられますが、Clipboard が対応している形式ではない場合は意味がありません。
特に Android は特殊で Text, Uri オブジェクト, Intent オブジェクトのみ扱えます。
詳しくは↓こちらを
■Android デベロッパー
コピー&ペースト
Android の場合は、単機能のアプリを Intent を介して順々に実行するスタイルの OS なので、Text, Uri, Intent のみがサポートされているのは頷けますね。
それ以外のプラットフォームでは Text, Image がデフォルトでサポートされています。
つまり、Text であれば、Windows, macOS, iOS, Android, Linux でクリップボードが使えるということです。
Image に限ると Windows, macOS, iOS, Linux で使えます。
Image の読み出し
先ほどの T の部分を FMX.Surface.TBitmapSurface にして、画像を読み出してみます。
var X := Clipboard.GetClipboard.AsType<TBitmapSurface>;
if X <> nil then
Image1.Bitmap.Assign(X);
Linux (Ubuntu 18.04 + VcXsrv) で上記のコードを使って読み出したところ。
ただ、このコードでは Clipboard 内に T 型のデータ(ここでは TBitmapSurface のデータ)が無い場合エラーになってしまいます。
事前に、Clipboard 内に何が入っているのか判ったらいいですよね。
IFMXExtendedClipboardService
Berlin から登場した新しい Clipboard Service の IFMXExtendedClipboardService を使うと、Clipboard 内のデータがどんな型なのか事前に把握できます。
まずはコードを見てください。
var Clipboard: IFMXExtendedClipboardService;
if
not TPlatformServices.Current.SupportsPlatformService(
IFMXExtendedClipboardService,
Clipboard)
then
Exit;
if Clipboard.HasText then // Text が格納されている?
Edit1.Text := Clipboard.GetText; // Clipboard 内を文字列として取り出す
if Clipboard.HasImage then // Image が格納されている?
Image1.Bitmap.Assign(Clipboard.GetImage); // Clipboard 内を TBitmapSurface として取り出す
このように HasXXX で、Clipboard に XXX 型のデータがあるか?が判別でき、さらに GetXXX で XXX 型のデータを取り出せます。
では、用意されている XXX は何があるかというと
- Text
- Image (ただし上述のように Android では常に False, nil を返す)
- CustomFormat
となります。
ここで、CustomFormat は任意のデータを Clipboard
扱う仕組みです…が、 Format を RegisterCustomFormat を使って事前に登録するので、同じアプリケーション間くらいでしか使い道は無さそうです。
なお、IFMXExtendedClipboardService は IFMXClipboardService を継承しているので、データを登録する方法は IMFXClipboardService と変わらず
SetClipboard(X);
を使います。
最後に
ということで、最後に Desktop 系 OS で Clipboard から画像を取り出したスクリーンショットを貼っておきます(せっかくなので全部違うスタイルで色とりどりに。Steller と Ubuntu ClearFantsy は DelphiStyles.com の紹介ページはありませんでした)。
設計時画面とソースコードは以下の通り
設計とソース
unit Unit1;
interface
uses
System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.StdCtrls,
FMX.Controls.Presentation, FMX.Edit, FMX.Objects, FMX.Layouts;
type
TForm1 = class(TForm)
Image1: TImage;
Edit1: TEdit;
Panel1: TPanel;
Button1: TButton;
Layout1: TLayout;
StyleBook1: TStyleBook;
procedure Button1Click(Sender: TObject);
private
public
end;
var
Form1: TForm1;
implementation
{$R *.fmx}
uses
FMX.Clipboard, FMX.Platform;
procedure TForm1.Button1Click(Sender: TObject);
begin
var Clipboard: IFMXExtendedClipboardService;
if
not TPlatformServices.Current.SupportsPlatformService(
IFMXExtendedClipboardService,
Clipboard)
then
Exit;
if Clipboard.HasText then
Edit1.Text := Clipboard.GetText;
if Clipboard.HasImage then
Image1.Bitmap.Assign(Clipboard.GetImage);
end;
end.
Screenshot ギャラリー
Windows (Style: ClearCerulean)

macOS (Style: Steller)

Ubuntu 18.04 + VcXsrv (Style: Ubuntu ClearFantasy)

Delphi を使うと簡単に Windows, macOS, iOS, Android, Linux で Clipboard が使えますね!
ちなみに、ここに使った画像は 2020/8 現在はまっている SPACE ENGINE のスクリーンショットです!