如何检测剪贴板文本更改?

How to detect clipboard text changes?

我的应用程序如何在剪贴板文本更改时收到通知?

例如:

我想 enable/disable 粘贴按钮并设置它的 Hint 属性 以显示剪贴板的文本(如 'Paste "%s"'

unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;

type
  TMyPasteForm = class(TForm)
    MyPasteButton: TButton;
    MyEdit: TEdit;
    procedure MyPasteButtonClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    procedure SyncMyPasteButton();
    { Private declarations }
  public
    { Public declarations }
  end;

var
  MyPasteForm: TMyPasteForm;

implementation

{$R *.dfm}

uses
  Clipbrd;

procedure TMyPasteForm.FormCreate(Sender: TObject);
begin
  MyPasteButton.ShowHint := True;
end;

procedure TMyPasteForm.MyPasteButtonClick(Sender: TObject);
begin
  MyEdit.Text := Clipboard.AsText;
end;

procedure TMyPasteForm.SyncMyPasteButton();
begin
  MyPasteButton.Enabled := Length(Clipboard.AsText) > 0;
  MyPasteButton.Hint := Format('Paste "%s"', [Clipboard.AsText]);
end;

end.

我发现了一个有趣的 PDF arcticle 并根据文章的 “使用剪贴板侦听器 API” 部分相应地编辑了我的示例:

unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;

type
  TMyPasteForm = class(TForm)
    MyPasteButton: TButton;
    MyEdit: TEdit;
    procedure MyPasteButtonClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    procedure SyncMyPasteButton();
    procedure WMClipboardUpdate(var Msg : TMessage); message WM_CLIPBOARDUPDATE;
  protected
    procedure CreateWnd(); override;
    procedure DestroyWnd(); override;
  public
    { Public declarations }
  end;

var
  MyPasteForm: TMyPasteForm;

implementation

{$R *.dfm}

uses
  Clipbrd;

procedure TMyPasteForm.FormCreate(Sender: TObject);
begin
  MyPasteButton.ShowHint := True;

  SyncMyPasteButton();
end;

procedure TMyPasteForm.CreateWnd();
begin
  inherited;
  //making sure OS notify this window when clipboard content changes
  AddClipboardFormatListener(Handle);
end;

procedure TMyPasteForm.DestroyWnd();
begin
  //remove the clipboard listener
  RemoveClipboardFormatListener(Handle);
  inherited;
end;

procedure TMyPasteForm.MyPasteButtonClick(Sender: TObject);
begin
  MyEdit.Text := Clipboard.AsText;
end;

procedure TMyPasteForm.SyncMyPasteButton();
begin
  MyPasteButton.Enabled := IsClipboardFormatAvailable(CF_TEXT);

  if(MyPasteButton.Enabled) then
    MyPasteButton.Hint := Format('Paste "%s"', [Clipboard.AsText])
  else
    MyPasteButton.Hint := '';
end;

procedure TMyPasteForm.WMClipboardUpdate(var Msg : TMessage);
begin
  //the clipboard content is changed!
  SyncMyPasteButton();
end;

end.

注: