Карта сайта Kansoftware
НОВОСТИУСЛУГИРЕШЕНИЯКОНТАКТЫ
KANSoftWare

Работа с буфером обмена через свой формат

Delphi , ОС и Железо , Буфер обмена

Работа с буфером обмена через свой формат

Автор: Xavier Pacheco

{
Copyright © 1999 by Delphi 5 Developer's Guide - Xavier Pacheco and Steve Teixeira
}
unit cbdata;
interface
uses
  SysUtils, Windows, clipbrd;

const

  DDGData = 'CF_DDG'; // constant for registering the clipboard format.
type

  // Record data to be stored to the clipboard

  TDataRec = packed record
    LName: string[10];
    FName: string[10];
    MI: string[2];
    Age: Integer;
    BirthDate: TDateTime;
  end;

  { Define an object around the TDataRec that contains the methods
    for copying and pasting the data to and from the clipboard }
  TData = class
  public
    Rec: TDataRec;
    procedure CopyToClipBoard;
    procedure GetFromClipBoard;
  end;

var
  CF_DDGDATA: word; // Receives the return value of RegisterClipboardFormat().

implementation

procedure TData.CopyToClipBoard;
{ This function copies the contents of the TDataRec field, Rec, to the
  clipboard as both binary data, as text. Both formats will be
  available from the clipboard }
const
  CRLF = #13#10;
var
Data: THandle;
  DataPtr: Pointer;
  TempStr: string[50];
begin
  // Allocate SizeOf(TDataRec) bytes from the heap
  Data := GlobalAlloc(GMEM_MOVEABLE, SizeOf(TDataRec));
  try
    // Obtain a pointer to the first byte of the allocated memory
    DataPtr := GlobalLock(Data);
    try
      // Move the data in Rec to the memory block
      Move(Rec, DataPtr^, SizeOf(TDataRec));
      { Clipboard.Open must be called if multiple clipboard formats are
        being copied to the clipboard at once. Otherwise, if only one
        format is being copied the call isn't necessary }
      ClipBoard.Open;
      try
        // First copy the data as its custom format
        ClipBoard.SetAsHandle(CF_DDGDATA, Data);
        // Now copy the data as text format
        with Rec do
          TempStr := FName + CRLF + LName + CRLF + MI + CRLF + IntToStr(Age) +
            CRLF +
            DateTimeToStr(BirthDate);
        ClipBoard.AsText := TempStr;
        { If a call to Clipboard.Open is made you must match it
          with a call to Clipboard.Close }
      finally
        Clipboard.Close
      end;
    finally
      // Unlock the globally allocated memory
      GlobalUnlock(Data);
    end;
  except
    { A call to GlobalFree is required only if an exception occurs.
      Otherwise, the clipboard takes over managing any allocated
      memory to it.}
    GlobalFree(Data);
    raise;
  end;
end;

procedure TData.GetFromClipBoard;
{ This method pastes memory saved in the clipboard if it is of the
  format CF_DDGDATA. This data is stored in the TDataRec field of
  this object. }
var
  Data: THandle;
  DataPtr: Pointer;
  Size: Integer;
begin
  // Obtain a handle to the clipboard
  Data := ClipBoard.GetAsHandle(CF_DDGDATA);
  if Data = 0 then
    Exit;
  // Obtain a pointer to the memory block referred to by Data
  DataPtr := GlobalLock(Data);
  try
    // Obtain the size of the data to retrieve
    if SizeOf(TDataRec) > GlobalSize(Data) then
      Size := GlobalSize(Data)
    else
      Size := SizeOf(TDataRec);
    // Copy the data to the TDataRec field
    Move(DataPtr^, Rec, Size)
  finally
    // Free the pointer to the memory block.
    GlobalUnlock(Data);
  end;
end;

initialization
  // Register the custom clipboard format
  CF_DDGDATA := RegisterClipBoardFormat(DDGData);
end.
{
Copyright © 1999 by Delphi 5 Developer's Guide - Xavier Pacheco and Steve Teixeira
}

unit MainFrm;

interface

uses
  SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,
  Forms, Dialogs, StdCtrls, clipbrd, Mask, ComCtrls;
type

  TMainForm = class(TForm)
    edtFirstName: TEdit;
    edtLastName: TEdit;
    edtMI: TEdit;
    btnCopy: TButton;
    btnPaste: TButton;
    meAge: TMaskEdit;
    btnClear: TButton;
    lblFirstName: TLabel;
    lblLastName: TLabel;
    lblMI: TLabel;
    lblAge: TLabel;
    lblBirthDate: TLabel;
    memAsText: TMemo;
    lblCustom: TLabel;
    lblText: TLabel;
    dtpBirthDate: TDateTimePicker;
    procedure btnCopyClick(Sender: TObject);
    procedure btnPasteClick(Sender: TObject);
    procedure btnClearClick(Sender: TObject);
  end;

var
  MainForm: TMainForm;

implementation
uses cbdata;

{$R *.DFM}

procedure TMainForm.btnCopyClick(Sender: TObject);
// This method copies the data in the form's controls onto the clipboard
var
  DataObj: TData;
begin
  DataObj := TData.Create;
  try
    with DataObj.Rec do
    begin
      FName := edtFirstName.Text;
      LName := edtLastName.Text;
      MI := edtMI.Text;
      Age := StrToInt(meAge.Text);
      BirthDate := dtpBirthDate.Date;
      DataObj.CopyToClipBoard;
    end;
  finally
    DataObj.Free;
  end;
end;

procedure TMainForm.btnPasteClick(Sender: TObject);
{ This method pastes CF_DDGDATA formatted data from the clipboard to
  the form's controls. The text version of this data is copied to the
  form's TMemo component. }
var
  DataObj: TData;
begin
  btnClearClick(nil);
  DataObj := TData.Create;
  try
    // Check if the CF_DDGDATA format is available
    if ClipBoard.HasFormat(CF_DDGDATA) then
      // Copy the CF_DDGDATA formatted data to the form's controls
      with DataObj.Rec do
      begin
        DataObj.GetFromClipBoard;
        edtFirstName.Text := FName;
        edtLastName.Text := LName;
        edtMI.Text := MI;
        meAge.Text := IntToStr(Age);
        dtpBirthDate.Date := BirthDate;
      end;
  finally
    DataObj.Free;
  end;
  // Now copy the text version of the data to form's TMemo component.
  if ClipBoard.HasFormat(CF_TEXT) then
    memAsText.PasteFromClipBoard;
end;

procedure TMainForm.btnClearClick(Sender: TObject);
var
  i: integer;
begin
  // Clear the contents of all controls on the form
  for i := 0 to ComponentCount - 1 do
    if Components[i] is TCustomEdit then
      TCustomEdit(Components[i]).Text := '';
end;

end.
Скачать весь проект

Here's a translation of the content into Russian:

Этот проект демонстрирует, как работать с буфером обмена в Delphi с помощью custom-формата. Custom-формат зарегистрирован как 'CF_DDG' и содержит запись типа TDataRec, которая включает поля для имени, фамилии, среднего initials, возраста и даты рождения.

Основное окно имеет несколько контролов: текстовые поля для имени, фамилии, среднего initials и возраста; календарь для даты рождения; кнопки копирования, вставки и очистки данных; и многострочная область для отображения текстовой версии буферных данных.

Когда вы нажимаете на кнопку "Копировать", программа создает экземпляр TData, заполняет поле Rec значениями из контролов на форме, и копирует данные в буфер обмена в двоичном и текстовом форматах.

Когда вы нажимаете на кнопку "Вставить", программа проверяет, доступен ли custom-формат 'CF_DDG' в буфере обмена. Если он есть, она создает экземпляр TData, получает данные из буфера обмена с помощью метода GetFromClipBoard и заполняет контролов на форме значениями, полученными из буфера обмена. Она также вставляет текстовую версию буферных данных в многострочную область.

Кнопка "Очистить" просто очищает содержимое всех контролов на форме.

Вот некоторые улучшения, которые можно сделать в этом проекте:

  1. Обработка ошибок: программа не обрабатывает ошибки хорошо. Например, если пользователь вводит недопустимые данные в контроле, программа может рухнуть или выдать неожиданные результаты.
  2. Интерфейс пользователя: интерфейс пользователя прост и lacks функций, таких как валидация полей возраста и даты рождения, а также форматирование для многострочной области.
  3. Организация кода: код организован в отдельных единицах (cbdata.pas и mainfrm.pas), но может быть еще более организован в логические секции или классы.

Вот альтернативное решение, использующее одиночный класс для обертывания данных и операций буфера обмена:

unit Data;
interface
uses
  SysUtils, Windows, clipbrd;
type
  TData = class
  private
    FRec: TDataRec;
  public
    constructor Create;
    procedure CopyToClipBoard;
    procedure GetFromClipBoard;
    property Rec: TDataRec read FRec;
  end;
implementation
constructor TData.Create;
begin
  FRec := TDataRec.Create;
end;
procedure TData.CopyToClipBoard;
const
  CRLF = #13#10;
var
  Data: THandle;
  DataPtr: Pointer;
  TempStr: string[50];
begin
   // Allocate SizeOf(TDataRec) bytes from the heap
  Data := GlobalAlloc(GMEM_MOVEABLE, SizeOf(TDataRec));
  try
     // Obtain a pointer to the first byte of the allocated memory
    DataPtr := GlobalLock(Data);
    try
       // Move the data in Rec to the memory block
      Move(FRec, DataPtr^, SizeOf(TDataRec));
      ClipBoard.Open;
      try
         // First copy the data as its custom format
        ClipBoard.SetAsHandle(RegisterClipBoardFormat('CF_DDG'), Data);
         // Now copy the data as text format
        TempStr := FRec.FName + CRLF + FRec.LName + CRLF + FRec.MI + CRLF +
                   IntToStr(FRec.Age) + CRLF +
                   DateTimeToStr(FRec.BirthDate);
        ClipBoard.AsText := TempStr;
      finally
        ClipBoard.Close;
      end;
    finally
      GlobalUnlock(Data);
    end;
  except
    GlobalFree(Data);
    raise;
  end;
end;
procedure TData.GetFromClipBoard;
var
  Data: THandle;
  DataPtr: Pointer;
  Size: Integer;
begin
   // Obtain a handle to the clipboard
  Data := ClipBoard.GetAsHandle(RegisterClipBoardFormat('CF_DDG'));
  if Data = 0 then
    Exit;
   // Obtain a pointer to the memory block referred to by Data
  DataPtr := GlobalLock(Data);
  try
     // Obtain the size of the data to retrieve
    if SizeOf(TDataRec) > GlobalSize(Data) then
      Size := GlobalSize(Data)
    else
      Size := SizeOf(TDataRec);
     // Copy the data to the TDataRec field
    Move(DataPtr^, FRec, Size);
  finally
    GlobalUnlock(Data);
  end;
end;
end.

Этот класс обертывает данные и операции буфера обмена, что делает его более удобным для использования и поддержки. Метод CopyToClipBoard копирует данные в буфер обмена в двоичном и текстовом форматах, а метод GetFromClipBoard получает данные из буфера обмена с помощью custom-формата.

Основное окно можно обновить, используя этот класс следующим образом:

procedure TMainForm.btnCopyClick(Sender: TObject);
var
  DataObj: TData;
begin
  DataObj := TData.Create;
  try
    with DataObj.Rec do
    begin
      FName := edtFirstName.Text;
      LName := edtLastName.Text;
      MI := edtMI.Text;
      Age := StrToInt(meAge.Text);
      BirthDate := dtpBirthDate.Date;
      DataObj.CopyToClipBoard;
    end;
  finally
    DataObj.Free;
  end;
end;

procedure TMainForm.btnPasteClick(Sender: TObject);
var
  DataObj: TData;
begin
  btnClearClick(nil);
  DataObj := TData.Create;
  try
    if ClipBoard.HasFormat(RegisterClipBoardFormat('CF_DDG')) then
      with DataObj.Rec do
      begin
        DataObj.GetFromClipBoard;
        edtFirstName.Text := FName;
        edtLastName.Text := LName;
        edtMI.Text := MI;
        meAge.Text := IntToStr(Age);
        dtpBirthDate.Date := BirthDate;
      end;
  finally
    DataObj.Free;
  end;
end;

В этом коде создается экземпляр TData, заполняется поле Rec значениями из контролов на форме, и вызывается метод CopyToClipBoard для копирования данных в буфер обмена. Когда нажимается кнопка "Вставить", программа проверяет, доступен ли custom-формат 'CF_DDG' в буфере обмена, получает данные из буфера обмена с помощью метода GetFromClipBoard и заполняет контролов на форме значениями, полученными из буфера обмена.

Работа с буфером обмена через свой формат: в статье описана реализация механизма работы с буфером обмена в программе на языке Delphi, при помощи которого можно копировать и вставлять пользовательские данные.


Комментарии и вопросы

Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS




Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.


:: Главная :: Буфер обмена ::


реклама


©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007
Top.Mail.Ru

Время компиляции файла: 2024-08-19 13:29:56
2024-10-24 19:55:45/0.0043408870697021/0