Difference between revisions of "Clipboard"
Line 112: | Line 112: | ||
==Custom format== | ==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. [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: | ||
+ | |||
+ | <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== | ==External links== | ||
* [http://delphi.about.com/od/vclusing/a/tclipboard.htm Basic Clipboard Operations (Cut/Copy/Paste) using the TClipboard object] | * [http://delphi.about.com/od/vclusing/a/tclipboard.htm Basic Clipboard Operations (Cut/Copy/Paste) using the TClipboard object] |
Revision as of 13:10, 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;</delpi>
HTML source
<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>
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>