Clipboard
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>