如何将 TEditMask 格式设置为自动插入空格并在粘贴的文本中使用空格?

How do I set the TEditMask format to both automatically insert spaces and use the spaces in pasted text?

给定 EditMask 属性 TMaskEdit 控件的文本,

>AAAAA_AAAAA_AAAAA_AAAAA_AAAAA_AAAAA_A;0;_

当用户键入时,每 5 个字符后自动插入一个 space。

但是,如果用户粘贴已经包含 space 的文本(例如,从我们发送给他们的电子邮件中复制),那么每个 space 都会用完一个必需的字符并且文本的最后 5 个字符丢失。

有没有办法识别 TEditMask 中的特定字符,使其为空或特定字符(在本例中为 space)?或者我可以使用不同的控件吗?

不要使用 TMaskEdit 及其可怕的视觉效果和限制。由于您要操作的文本相当短,您可以直接使用 TEdit 并对文本的更改做出反应:

  • 始终将文本设为大写。
  • 不要依赖键盘而不是鼠标输入。
  • 故意杀死所有 spaces 并出于视觉原因将它们放在任何你想要的地方。

也不要错误地为每个文本块使用多个 TEdit,因为这会打扰任何想要立即粘贴长序列号(?)的剪贴板内容的人 - 我我见过软件安装这样做,这总是很痛苦。

有一个空表格,添加一个 TEdit 并使其成为 OnChange 事件:

procedure TForm1.Edit1Change( Sender: TObject );
var
  edt: TEdit;  // Easier access
  sText: String;  // Easier access
  iLen, iPos, iCur: Integer;  // Text length, Character to inspect, Text cursor position
begin
  // Sender might be nil in rare conditions
  if not (Sender is TEdit) then exit;
  edt:= Sender as TEdit;

  // Empty texts don't need our care
  iLen:= Length( edt.Text );
  if iLen= 0 then exit;

  // I guess you always want big letters
  sText:= UpperCase( edt.Text );

  // Kill all spaces, so it doesn't matter how many are in there
  iCur:= edt.SelStart;  // Remember text cursor position
  iPos:= Pos( ' ', sText );  // Find first occurance
  while iPos> 0 do begin
    Delete( sText, iPos, 1 );
    Dec( iLen );
    if iCur>= iPos then Dec( iCur );  // Was text cursor after that spot? Should move, too.
    iPos:= Pos( ' ', sText );  // Find next occurance
  end;

  iPos:= 5;  // Character of the text to inspect
  while iPos< iLen do begin  // Much better than "<=", credit: Tom Brunberg
    if sText[iPos+ 1]<> ' ' then begin  // Next character is not a space?
      Insert( ' ', sText, iPos+ 1 );  // Insert space
      if iCur> iPos then Inc( iCur );  // Was text cursor after that spot? Should move, too.
      Inc( iLen );  // Text size has been increased by us
    end;

    Inc( iPos, 6 );  // Go to next end of a "block"
  end;

  edt.OnChange:= nil;  // Otherwise setting .Text will trigger this event again
  edt.Text:= sText;  // We're done
  edt.OnChange:= Edit1Change;
  edt.SelStart:= iCur;  // Recover/fix text cursor
end;

在 D7 上测试成功:

只删除单个字符感觉很奇怪,并且当最后一个字符是 space 时不起作用。我会留给你去完善它。