LoginSignup
8
4

More than 3 years have passed since last update.

[Delphi] [FMX] クリップボードの使い方

Last updated at Posted at 2020-08-11

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) で上記のコードを使って読み出したところ。
image.png

ただ、このコードでは 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 の紹介ページはありませんでした)。

設計時画面とソースコードは以下の通り

設計とソース

image.png

unit1.pas
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)

Windows

macOS (Style: Steller)

macOS

Ubuntu 18.04 + VcXsrv (Style: Ubuntu ClearFantasy)

Linux

Delphi を使うと簡単に Windows, macOS, iOS, Android, Linux で Clipboard が使えますね!

ちなみに、ここに使った画像は 2020/8 現在はまっている SPACE ENGINE のスクリーンショットです!

8
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
4