从剪贴板粘贴到编辑框中的文本超过最大长度时如何获取通知?

时间:2018-04-20 08:27:55

标签: delphi

当从剪贴板粘贴到TEdit控件中的文本超过其允许的最大长度时,我需要向用户显示一条消息。但是,我不希望每次输入新的字母时都要检查程序,只有在粘贴文本时才会检查。

我该怎么做?

3 个答案:

答案 0 :(得分:9)

对编辑类进行子类化并侦听WM_PASTE消息。例如(对于Unicode Delphi):

uses
  Vcl.Clipbrd;

type
  TEdit = class(Vcl.StdCtrls.TEdit)
  private
    procedure WMPaste(var Msg: TWMPaste); message WM_PASTE;
  end;

implementation

procedure TEdit.WMPaste(var Msg: TWMPaste);
begin
  if (MaxLength > 0) and (Length(Clipboard.AsText) > MaxLength - GetTextLen + SelLength) then
    ShowMessage('Text is too long!');
  inherited;
end;

另一个更高效的WinAPI变体(它不会复制剪贴板缓冲区,只是查询它的大小),也可能是(也适用于Unicode Delphi):

type
  TEdit = class(Vcl.StdCtrls.TEdit)
  private
    procedure WMPaste(var Msg: TWMPaste); message WM_PASTE;
  end;

implementation

procedure TEdit.WMPaste(var Msg: TWMPaste);
var
  Data: THandle;
begin
  if (MaxLength > 0) and OpenClipboard(0) then
  try
    Data := GetClipboardData(CF_UNICODETEXT);
    if (Data <> 0) and ((GlobalSize(Data) div SizeOf(Char)) - 1 > MaxLength - GetTextLen + SelLength) then
      ShowMessage('Text is too long!');
  finally
    CloseClipboard;
  end;
  inherited;
end;

如果您想阻止将文字粘贴到控件中,请从上面的示例中移除inherited来电。

答案 1 :(得分:7)

TEdit进行子类化以处理EN_MAXTEXT通知:

  

当前文本插入超过编辑控件的指定字符数时发送。文本插入已被截断。

这适用于键入和粘贴,并为您考虑文本选择。例如:

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
  TEdit = class(Vcl.StdCtrls.TEdit)
  private
    procedure CNCommand(var Message: TWMCommand); message CN_COMMAND;
  end;

  TForm1 = class(TForm)
    Edit1: TEdit;
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TEdit.CNCommand(var Message: TWMCommand);
begin
  inherited;
  if Message.NotifyCode = EN_MAXTEXT then
    ShowMessage('Too much text!');
end;

end.

如果您只想处理粘贴,请在调用WM_PASTE之前抓住inherited设置标记,然后在inherited退出时清除标记,如果EN_MAXTEXT是在设置标志时发出,然后采取相应行动:

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
  TEdit = class(Vcl.StdCtrls.TEdit)
  private
    FIsPasting: Boolean;
    procedure CNCommand(var Message: TWMCommand); message CN_COMMAND;
    procedure WMPaste(var Message: TMessage); message WM_PASTE;
  end;

  TForm1 = class(TForm)
    Edit1: TEdit;
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TEdit.CNCommand(var Message: TWMCommand);
begin
  inherited;
  if (Message.NotifyCode = EN_MAXTEXT) and FIsPasting then
    ShowMessage('Too much text!');
end;

procedure TEdit.WMPaste(var Message: TMessage);
begin
  FIsPasting := True;
  try 
    inherited;
  finally
    FIsPasting := False;
  end;
end;

end.

答案 2 :(得分:6)

你走了:

unit Unit1;

interface

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

type
  TPasteEdit = class(TEdit)
    private
      FMaxPaste: Integer;
      procedure WMPaste(var Message: TWMPaste); message WM_PASTE;
    protected
    public
      constructor Create(AOwner: TComponent); override;
    published
      property MaxPaste: Integer read FMaxPaste write FMaxPaste default 0;
      //You can define it or use MaxLength as well
  end;
  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}



{ TPastEdit }

constructor TPasteEdit.Create(AOwner: TComponent);
begin
  inherited;
  FMaxPaste:= 0;
end;

procedure TPasteEdit.WMPaste(var Message: TWMPaste);
begin
  if Length(Clipboard.AsText) > FMaxPaste then
    ShowMessage('The text you paste is too long!') // Call inherited if you want to paste anyway
      else
        inherited;
end;

procedure TForm1.FormCreate(Sender: TObject);
Var
  PasteEdit: TPasteEdit;
begin
  PasteEdit:= TPasteEdit.Create(Self);
  PasteEdit.Parent:= Self;
  PasteEdit.MaxPaste:= 3;
end;

end.
相关问题