3 votes

Comment créer votre propre Clipboard hors système ?

Est-ce possible et, dans l'affirmative, comment procéder pour mettre en place votre propre presse-papiers ?

Je veux dire par là qu'il est possible de copier et de coller n'importe quoi dans le presse-papiers, comme le fait le presse-papiers de Windows, mais sans interférer avec le presse-papiers du système.

Pour donner une meilleure idée, voici ce que j'ai essayé :

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;

Cela fonctionne en ce sens qu'il copiera la chaîne "Copier ce texte" dans le presse-papiers, mais il écrase ce qui se trouvait dans le presse-papiers de Windows.

Ce qui précède doit juste créer une instance du presse-papiers de Windows, sans créer réellement le vôtre.

Notez que le presse-papiers personnalisé peut contenir n'importe quelle donnée et pas seulement du texte brut. Il devrait fonctionner de la même manière que le presse-papiers de Windows, mais sans interférer avec lui (en perdant ce qui s'y trouvait).

Comment cela pourrait-il être réalisé ?

Merci.

5voto

Ken White Points 73213

Votre question est confuse ; vous dites que vous voulez le faire sans affecter le presse-papiers du système, mais ensuite (d'après votre propre commentaire à votre question) vous semblez vouloir implémenter quelque chose comme la fonction de MS Office Paste Special .

Si c'est le premier, comme d'autres l'ont dit, vous ne pouvez pas le faire en utilisant la fonction TClipboard Vous devez implémenter votre propre wrapper, et le transfert d'informations entre applications sera très difficile.

Si c'est le second, vous pouvez utiliser l'API Windows RegisterClipboardFormat pour définir votre propre format.

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;

Pour placer des informations dans le presse-papiers dans un format personnalisé, vous devez utiliser les éléments suivants GlobalAlloc et GlobalLock pour allouer et verrouiller un bloc de mémoire globale, copier vos données dans ce bloc, déverrouiller le bloc à l'aide de la fonction GlobalUnlock utiliser TClipboard.SetAsHandle pour transférer le bloc de mémoire dans le presse-papiers. Vous devez ensuite appeler GlobalFree pour libérer le bloc mémoire.

Pour récupérer les éléments dans votre format personnalisé, vous faites essentiellement la même chose, mais en inversant certaines étapes. Vous utilisez GlobalAlloc/GlobalLock comme précédemment, utilisez TClipboard.GetAsHandle pour récupérer le contenu du presse-papiers, le copier dans une variable locale, puis appeler GlobalFree.

Voici un vieil exemple de mise en place d'un format personnalisé (dans ce cas, du texte RTF) dans le presse-papiers - il provient d'une message de newsgroup par le Dr. Peter Below de TeamB . (Le code et le formatage sont ceux du post original ; je ne l'ai pas testé ni même compilé). Inverser le processus pour le faire sortir devrait être clair d'après mes instructions sur ce qu'il faut changer ci-dessus, et je vous laisse le soin de le faire :)

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;

2voto

Vahid Nasehi Points 445

Vous devez définir votre propre Clipboard personnalisé. Il peut ressembler à quelque chose comme ceci :

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;

Vous pouvez alors utiliser FStream comme conteneur de presse-papiers personnalisé. Vous pouvez stocker (copier) n'importe quelle donnée dans ce flux et l'utiliser (coller) quand vous en avez besoin. Il vous suffit d'écrire quelques méthodes Get/Set pour vos types de données.

1voto

Stan Points 3474

TClipboard est une classe incapsulant le presse-papiers du système, vous ne pouvez donc pas l'utiliser pour instancier une autre copie d'un presse-papiers. Vous devez implémenter votre propre classe, représentant un tampon universel avec des setters et des getters.

1voto

Chris Thornton Points 11083

Vous ne pouvez pas. Vous pouvez avoir un tampon de mémoire interne dans lequel vous déplacez des données, vous pouvez l'appeler "copier" et "coller" si vous voulez, mais ne le mettez pas dans l'interface utilisateur de cette façon, ou vous allez juste embrouiller vos utilisateurs. Il n'existe qu'un seul presse-papiers système, et vous ne pouvez pas y placer des données sans affecter d'autres programmes. Si votre prochaine idée est d'enregistrer le presse-papiers, de l'écraser avec vos propres données, puis de restaurer le contenu original, ne vous donnez pas la peine.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X