Difference between revisions of "Clipboard"

From Free Pascal wiki
Jump to navigationJump to search
Line 57: Line 57:
 
<delphi>  procedure CopyToClipboard;  
 
<delphi>  procedure CopyToClipboard;  
 
   procedure CutToClipboard;  
 
   procedure CutToClipboard;  
   procedure PasteFromClipboard;</delpi>
+
   procedure PasteFromClipboard;</delphi>
  
 
==HTML source==
 
==HTML source==
  
 +
Example of reading HTML source from clipboard:
 
<delphi>uses
 
<delphi>uses
 
   Clipbrd, ...;
 
   Clipbrd, ...;
Line 85: Line 86:
 
   end;
 
   end;
 
end;</delphi>
 
end;</delphi>
 +
 +
Write html source to clipboard. This can be done with AddFormat either using TStream or memory Buffer.
 +
<delphi>// register the mime type for text/html. You can do this once at program start:
 +
  ClipbrdFmtHTML := RegisterClipboardFormat('text/html');
 +
...
 +
  // put text and html on the clipboard. Other applications will choose the best format automatically.
 +
  ThePlainUTF8Text := 'Simple text';
 +
  Clipboard.AsText := ThePlainUTF8Text;
 +
  HTMLSource := '<b>Formatted</b> text'; // text with formatrings
 +
  Clipboard.AddFormat(ClipbrdFmtHTML, HTMLSource[1], Length(HTMLSource));</delphi>
  
 
==Image==
 
==Image==
Line 117: Line 128:
 
==Getting notified of changes==
 
==Getting notified of changes==
  
The LCL does not pass on windows messages. It only passes on messages > WM_USER. This means you have to write your own message handler. [http://wiki.lazarus.freepascal.org/Win32/64_Interface#Processing_non-user_messages_in_your_window Processing non - user messages in your window]
+
The LCL does not pass on Windows messages. It only passes on messages > WM_USER. This means you have to write your own message handler. [http://wiki.lazarus.freepascal.org/Win32/64_Interface#Processing_non-user_messages_in_your_window Processing non - user messages in your window]
  
 
Sample code to implement message handler:
 
Sample code to implement message handler:

Revision as of 14:36, 27 January 2012

Predefined types

TPredefinedClipboardFormat MIME type
pcfText text/plain
pcfBitmap image/bmp
pcfPixmap image/xpm
pcfIcon image/lcl.icon
pcfPicture image/lcl.picture
pcfObject application/lcl.object
pcfComponent application/lcl.component
pcfCustomData application/lcl.customdata
pcfDelphiText text/plain
pcfDelphiBitmap text/delphi.bitmap
pcfDelphiPicture Delphi picture
pcfDelphiMetaFilePict image/delphimetafilepict
pcfDelphiObject application/delphi.object
pcfDelphiComponent Delphi component
pcfKylixPicture image/delphi.picture
pcfKylixBitmap image/delphi.bitmap
pcfKylixDrawing image/delphi.drawing
pcfKylixComponent application/delphi.component

Text

For use of simple text Clipboard offer property AsText which can be used for reading an writing plain text.

Writing text: <delphi>Clipboard.AsText := 'Hello clipboard!';</delphi>

Reading text: <delphi>ShowMessage('Clipboard content: ' + Clipboard.AsText);</delphi>

Text oriented components

Some visual components like TEdit, TMemo, TStringGrid, TLabeledEdit, TMaskEdit, TSpinEdit and TFloatSpinEdit have ability to select a part of contained text and offer additional functionality for handling clipboard operations on selected text.

<delphi> procedure CopyToClipboard;

 procedure CutToClipboard; 
 procedure PasteFromClipboard;</delphi>

HTML source

Example of reading HTML source from clipboard: <delphi>uses

 Clipbrd, ...;

procedure InsertHTMLSourceFromClipboard(Strings: TString); var

 Fid: TClipboardFormat
 Str: WideString;
 Stream: TMemoryStream;

begin

 Fid := Clipboard.FindFormatID('text/html');
 if Fid <> 0 then 
 try
   Stream := TMemoryStream.Create;
   if Clipboard.GetFormat(Fid, Stream) then 
   begin
     Stream.Position := 0;
     Str := PWideChar(Stream.Memory);
     Str[(Stream.Size div 2) + 1] := #0;
     Strings.Text := UTF8Encode(Str);
   end;
 finally
   Stream.Free;
 end;

end;</delphi>

Write html source to clipboard. This can be done with AddFormat either using TStream or memory Buffer. <delphi>// register the mime type for text/html. You can do this once at program start:

 ClipbrdFmtHTML := RegisterClipboardFormat('text/html');

...

 // put text and html on the clipboard. Other applications will choose the best format automatically.
 ThePlainUTF8Text := 'Simple text';
 Clipboard.AsText := ThePlainUTF8Text; 
 HTMLSource := 'Formatted text'; // text with formatrings
 Clipboard.AddFormat(ClipbrdFmtHTML, HTMLSource[1], Length(HTMLSource));</delphi>

Image

Load from clipboard

<delphi>uses

 Clipbrd, LCLIntf, LCLType, ...;

procedure LoadBitmapFromClipboard(Bitmap: TBitmap); begin

 if Clipboard.HasFormat(PredefinedClipboardFormat(pcfDelphiBitmap)) then
   Bitmap.LoadFromClipboardFormat(PredefinedClipboardFormat(pcfDelphiBitmap));
 if Clipboard.HasFormat(PredefinedClipboardFormat(pcfBitmap)) then
   Bitmap.LoadFromClipboardFormat(PredefinedClipboardFormat(pcfBitmap));

end;</delphi>

Save to clipboard

<delphi>uses

 Clipbrd, ...;

procedure SaveBitmapToClipboard(Bitmap: TBitmap); begin

 Clipboard.Assign(Bitmap);

end;</delphi>

Custom format

Multiple objects

Getting notified of changes

The LCL does not pass on Windows messages. It only passes on messages > WM_USER. This means you have to write your own message handler. Processing non - user messages in your window

Sample code to implement message handler:

<delphi>unit Unit1;

{$mode delphi}{$H+}

interface

uses

 Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs,
 Clipbrd, StdCtrls, Windows, Messages;

type

 TForm1 = class(TForm)
   Button1: TButton;
   procedure FormCreate(Sender: TObject);
   procedure FormDestroy(Sender: TObject);
 private
   FNextClipboardOwner: HWnd;   // handle to the next viewer
   // Here are the clipboard event handlers
   function WMChangeCBChain(wParam: WParam; lParam: LParam):LRESULT;
   function WMDrawClipboard(wParam: WParam; lParam: LParam):LRESULT;
 public
 end;

var

 Form1: TForm1;

implementation

{$R *.lfm} var

 PrevWndProc:windows.WNDPROC;

function WndCallback(Ahwnd: HWND; uMsg: UINT; wParam: WParam;

 lParam: LParam): LRESULT; stdcall;

begin

 if uMsg = WM_CHANGECBCHAIN then begin
   Result := Form1.WMChangeCBChain(wParam, lParam);
   Exit;
 end 
 else if uMsg=WM_DRAWCLIPBOARD then begin
   Result := Form1.WMDrawClipboard(wParam, lParam);
   Exit;
 end;
 Result := CallWindowProc(PrevWndProc, Ahwnd, uMsg, WParam, LParam);

end;

{ TForm1 }

procedure TForm1.FormCreate(Sender: TObject); begin

 PrevWndProc := Windows.WNDPROC(SetWindowLong(Self.Handle, GWL_WNDPROC, PtrInt(@WndCallback)));
 FNextClipboardOwner := SetClipboardViewer(Self.Handle);

end;

procedure TForm1.FormDestroy(Sender: TObject); begin

 ChangeClipboardChain(Handle, FNextClipboardOwner);

end;

function TForm1.WMChangeCBChain(wParam: WParam; lParam: LParam): LRESULT; var

 Remove, Next: THandle;

begin

 Remove := WParam;
 Next := LParam;
 if FNextClipboardOwner = Remove then FNextClipboardOwner := Next
   else if FNextClipboardOwner <> 0 then
     SendMessage(FNextClipboardOwner, WM_ChangeCBChain, Remove, Next)

end;

function TForm1.WMDrawClipboard(wParam: WParam; lParam: LParam): LRESULT; begin

 if Clipboard.HasFormat(CF_TEXT) Then Begin
   ShowMessage(Clipboard.AsText);
 end;
 SendMessage(FNextClipboardOwner, WM_DRAWCLIPBOARD, 0, 0);   // VERY IMPORTANT
 Result := 0;

end;

end.</delphi>

External links