Clipboard/hu

From Lazarus wiki

Deutsch (de) English (en) magyar (hu) русский (ru)


Vágólap

Előre definiált típusok

TPredefinedClipboardFormat MIME típus
pcfText text/plain
pcfBitmap image/bmp
pcfPixmap image/xpm
pcfIcon image/lcl.icon
pcfPicture image/lcl.picture
pcfMetaFilePict image/lcl.metafilepict
pcfObject application/lcl.object
pcfComponent application/lcl.component
pcfCustomData application/lcl.customdata

Szöveg

Egyszerű szöveg kezeléséhez a vágólapon az AsText tulajdonság használata ajánlott, melynek segítségével sima szövegek olvashatók és írhatók.

Szöveg írása:

Clipboard.AsText := 'Helló vágólap!';

Szöveg olvasása:

ShowMessage('A vágólap tartalma: ' + Clipboard.AsText);

A Clipboard egy TClipboard típusú változó, aminek használatához a Clipbrd unit-ot a uses részhez kell adni:

uses
..., Clipbrd;

Szöveg tartalmú komponensek

Néhány grafikus komponens, mint a TEdit, TMemo, TStringGrid, TLabeledEdit, TMaskEdit, TSpinEdit és a TFloatSpinEdit lehetővé teszik a tartalmuk egy részének kijelölését és rendelkeznek a kijelölt szöveg vágólappal történő kezelésére ajánlott eljárásokkal.

  
procedure CopyToClipboard; 
  procedure CutToClipboard; 
  procedure PasteFromClipboard;

HTML forrás

Egy példa a HTML források kiolvasására a vágólapról:

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.Write(#0#0, Length(#0#0));
      Stream.Position := 0;
      Str := PWideChar(Stream.Memory);     
      Strings.Text := UTF8Encode(Str);
    end;
  finally
    Stream.Free;
  end;
end;

HTML forrás írása a vágólapra. Ez elvégezhető az AddFormat használatával, illetve TStream vagy memória Puffer segítségével.

// a text/html mime tipus bejegyzése. Ezt csak egyszer kell megtenni a program indulásakor:
  ClipbrdFmtHTML := RegisterClipboardFormat('text/html');
...
  // Minden korábbi formátum kitakarítása a vágólapról indulás előtt
  Clipboard.Clear;

  // szöveg és html elhelyezése a vágólapon. Más alkalmazások automatikusan a nekik legmegfelelőbbet fogják választani.
  ThePlainUTF8Text := 'Egyszerű szöveg';
  Clipboard.AsText := ThePlainUTF8Text; 

  HTMLSource := '<b>Formázott</b> szöveg'; // szöveg formázásokkal
  Clipboard.AddFormat(ClipbrdFmtHTML, HTMLSource[1], Length(HTMLSource));

Windows

Nem minden alkalmazás támogatja a 'text/html' mime típust. A Microsoft operációs rendszerei és alkalmazásai inkább a 'HTML Format' megjelölést támogatják, melyhez a vágólapon elhelyezendő tartalom leírása a következő címen olvasható:

https://msdn.microsoft.com/en-us/library/aa767917%28v=vs.85%29.aspx

(ha az URL megváltozik az írás címe: HTML Clipboard Format, és része az MSHTML Editing dokumentációnak)

Ez a leírás tartalmazza azt a követelményt, hogy a fejlécnek tartalmaznia kell a fejléc hosszát, ami bosszantó számolgatáshoz vezethet tekintettel arra, hogy a számlálás eredménye miatt megváltozhat a karakterek száma. A legegyszerűbb mód ennek megoldására, ha a számokat 10 számjeggyel és vezető nullákkal írjuk le, mint lentebb látható.

procedure AddHTMLToClipboard(AHTML: String);
const
  HTML_MIME = 'HTML Format';
  NATIVEHEADER = 'Version:0.9' + #13#10 +
                 'StartHTML:%.10d' + #13#10+
                 'EndHTML:%.10d' + #13#10+
                 'StartFragment:%.10d' + #13#10+
                 'EndFragment:%.10d' + #13#10;
  HEADER = '<html><head></head><body><!--StartFragment-->';
  FOOTER1 = '<!--EndFragment-->';
  FOOTER2 = '</body></html>';
var
  cfHTMLFormat: TClipboardFormat;
  HTMLSource : String;
  iStartHTML: Integer;
  iStartFragment: Integer;
  iEndFragment: Integer;
  iEndHTML: Integer;

begin
  // Biztosítani kell, hogy a 'HTML Format' mime típus be legyen jegyezve
  cfHTMLFormat := Clipboard.FindFormatID(HTML_MIME);
  If cfHTMLFormat = 0 Then
    cfHTMLFormat := RegisterClipboardFormat(HTML_MIME);

  iStartHTML := 105;
  iStartFragment := iStartHTML + Length(HEADER);
  iEndFragment := iStartFragment + Length(AHTML) + Length(FOOTER1);
  iEndHTML := iEndFragment + LENGTH(FOOTER2);

  // Fejléc és nyitó html cimkék elhelyezése a karakterlánc elején
  HTMLSource := Format(NATIVEHEADER, [iStartHTML, iEndHTML, iStartFragment,
    iEndFragment]) + HEADER + AHTML + FOOTER1 + FOOTER2;

  Clipboard.AddFormat(cfHTMLFormat, HTMLSource[1], Length(HTMLSource));
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  Clipboard.Clear;

  Clipboard.AsText:='Egyszerű szöveg';

  AddHTMLToClipboard('<b>Kövér szöveg</b>');
end;

Mivel a vágólap több formátumot támogat, ezért elhelyezhető rajta egyszerű szöveg (SimpleText), 'text/html' és 'HTML Format' elem egyszerre...

Kép

Betöltés vágólapról

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;

Mentés vágólapra

uses 
  Clipbrd, ...;

procedure SaveBitmapToClipboard(Bitmap: TBitmap);
begin
  Clipboard.Assign(Bitmap);
end;

Értesítés a változásokról

Az LCL-en nem futnak át a Windows üzeneteket, kivéve a WM_USER üzenetet. Ennek megfelelően saját üzenetkezelő írására lehet szükség. Processing non - user messages in your window

Példa saját üzenetkezelő kidolgozására:

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;   // A következő vágólapkezelő
    // A vágólap eseményeit kezelő eljárások következnek
    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);   // NAGYON FONTOS!
  Result := 0;
end;

end.

Külső hivatkozások