2012-02-11 2 views
3

可能でしょうか、もしそうなら、独自のクリップボードの実装についてどう思いますか?独自の非システムクリップボードを作成するには?

これは、Windowsのクリップボードのように、コピーして貼り付けできることですが、実際にはシステムのクリップボードに干渉することはありません。

これは私が試したものですより良いアイデアを与えること:

uses 
    ClipBrd; 

... 

procedure TMainForm.actCopyExecute(Sender: TObject); 
var 
    MyClipboard: TClipboard; 
begin 
    MyClipboard := TClipboard.Create; 
    try 
    MyClipboard.AsText := 'Copy this text'; 
    finally 
    MyClipboard.Free; 
    end; 
end; 

それはクリップボードに「このテキストをコピーし、」文字列をコピーすることで動作しますが、それはWindowsのクリップボードにあったものは何でも上書きすること。

上記はWindowsクリップボードのインスタンスを作成するだけで、実際には独自のクリップボードを作成する必要はありません。

カスタムクリップボードには、プレーンテキストだけでなくあらゆるデータを保持できることに注意してください。それはWindowsのクリップボードと同じように動作するはずですが、干渉することなく(その上にあったものはすべて失われます)。

これはどのように達成できますか?

ありがとうございました。

+1

'Clipboard.AsText:= 'このテキストをコピーする';'; 'TClipboard'の新しいインスタンスを作成する必要はありません。 –

+0

はい、私は自分のクリップボードを必要としますが、Windowsのクリップボードは必要ありません。 –

+1

はい、私は知っています。私のコメントは話題にならなかった。 –

答えて

5

あなたの質問は混乱します。あなたはシステムクリップボードに影響を与えずにそれをしたいと言っていますが、あなた自身のコメントからあなたはMS OfficeのPaste Specialのようなものを実装したいと思っているようです。

ラップトップを使用している場合は、TClipboardラッパーを使用してそのことを行うことはできないと言われているように、最初の場合。独自に実装する必要があり、アプリケーション間で情報を渡すことは非常に難しいでしょう。

これは、Windows API RegisterClipboardFormatを使用して独自の形式を定義することで行います。

type 
    TForm1=class(TForm) 
    YourCustomFormat: Word; 
    procedure FormCreate(Sender: TObject); 
    end; 

implementation 

constructor TForm1.FormCreate(Sender: TObject); 
begin 
    YourCustomFormat := RegisterClipboardFormat('Your Custom Format Name'); 
end; 

カスタム形式でクリップボードに情報を入れるために、あなたは、グローバルメモリブロックを割り当て、ロックしGlobalAllocGlobalLockを使用し、そのブロックにデータをコピーし、GlobalUnlockを使用してブロックのロックを解除するにTClipboard.SetAsHandleを使用する必要がありますメモリブロックをクリップボードに転送します。メモリブロックを解放するには、GlobalFreeを呼び出す必要があります。

カスタム形式のものを取得するには、基本的に同じ手順を繰り返します。以前と同じようにGlobalAlloc/GlobalLockを使用し、TClipboard.GetAsHandleを使用してクリップボードのコンテンツを取得し、ローカル変数にコピーしてからGlobalFreeを呼び出します。

カスタムフォーマット(この場合はRTFテキスト)をクリップボードに入れる古い例は、TeamBというPeter Below博士のnewsgroup postです。 (コードと書式は元の投稿のものであり、私はそれをテストしなかったし、それをコンパイルしたこともありませんでした)。上記を変更するための手順から明らかにする必要があります。ワークアウトする。 :)

procedure TForm1.BtnSetRTFClick(Sender: TObject); 
Const 
    testtext: PChar = '{\rtf1\ansi\pard\plain 12{\ul 44444}}'; 
    testtext2: PChar = '{\rtf1\ansi'+ 
    '\deff4\deflang1033{\fonttbl{\f4\froman\fcharset0\fprq2 Times New Roman;}}' 
        +'\pard\plain 12{\ul 44444}}'; 
    flap: Boolean = False; 
Var 
    MemHandle: THandle; 
    rtfstring: PChar; 
begin 
    If flap Then 
     rtfstring := testtext2 
    Else 
     rtfstring := testtext; 
    flap := not flap; 
    MemHandle := GlobalAlloc(GHND or GMEM_SHARE, StrLen(rtfstring)+1); 
    If MemHandle <> 0 Then Begin 
     try 
     StrCopy(GlobalLock(MemHandle), rtfstring); 
     GlobalUnlock(MemHandle); 
     With Clipboard Do Begin 
      Open; 
      try 
      AsText := '1244444'; 
      SetAsHandle(CF_RTF, MemHandle); 
      finally 
      Close; 
      end; 
     End; 
     Finally 
     GlobalFree(MemHandle); 
     End; 
    End 
    Else 
     MessageDlg('Global Alloc failed!', 
       mtError, [mbOK], 0); 
end; 
+3

+1 RegisterClipboardFormat +1 @Blobbyへ行く道のように見える –

+1

本当に権威ある医者(彼はまだ医者ですか?)**コピー**をRTFフラグメント(プライベートフォーマットではありません)として実行するコードは、**仮説的なOPの問題を解決します**ペーストスペシャル**。 – OnTheFly

+0

RTFはあらかじめ定義されたクリップボード形式ではありません。「Text」は(CF_OEMTEXTまたはCF_TEXTまたはCF_UNICODETEXT)です.WinAPIを使用する場合は、カスタムクリップボード形式として実装する必要があります。 EasyGPSは実際にはXML(Text)である 'gpx'カスタムフォーマットを使用します。 – menjaraz

1

TClipboardは、システムのクリップボードをカプセル化しているクラスであるため、クリップボードの別のコピーをインスタンス化するために使用することはできません。 setterとgetterを持つ汎用バッファを表す独自のクラスを実装する必要があります。

+0

これは確かに実行可能ですが、これは完全に自明ではありません。 –

+0

それは異なります。独自のクリップボードでサポートされている各データ型を「理解」したい場合、これは簡単なことではありません。しかし、クライアントは「知っている」こと、彼らが何を設定して取得するかということを前提として、データを「そのまま」(バイナリストリームとして)保存して復元することは可能でしょう。 – Stan

+0

TClipboardの別のインスタンスは、クリップボード関数が返すように動作します。したがって、TClipboardを拡張するには、この関数のフックが必要です。 – OnTheFly

2

独自のカスタムクリップボードを定義する必要があります。

type 
    TMyCustomClipboard = class 
    private 
    FStream: TMemoryStream; 
    function GetAsText: string; 
    procedure SetAsText(const Value: string); 
    ... 
    public 
    constructor Create; 
    destructor Destroy; override; 
    procedure Clear; 
    property AsText: string read GetAsText write SetAsText; 
    procedure AsAnyThing: AnyType read GetAsAnyThing write AsAnyThing; 
    ... 
    end; 

その後、カスタムクリップボードコンテナとしてFStream使用することができます。それは次のようになります。あなたは、そのストリームの中の任意のデータを保存(コピー)し、必要なときにそれを使用(貼り付け)することができます。あなたは、あなたのデータ型にいくつかのGet/Setメソッドを書く必要があります。

+0

これは達成可能なサンプルを提供してくれた面白い投稿 –

+1

理想的な世界では、抽象基盤TClipboard、WinAPI具体的子孫、X/freedesktop具象子孫のようになります。 – OnTheFly

1

できません。データを内部と外部に移動する内部メモリバッファを持つことができます。必要に応じて "コピー"と "貼り付け"を行うことができますが、そのようにユーザーインターフェイスに入れないでください。そうしないと、混乱しますあなたのユーザー。システムクリップボードは1つしかなく、他のプログラムに影響を与えることなくデータを入れることはできません。あなたの次の考えは、あなたのもので上書きし、元の内容を復元するクリップボードを保存する場合は、気にしないでください。

関連する問題