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

发布于 2025-01-12 13:27:45 字数 340 浏览 0 评论 0原文

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

>AAAAA_AAAAA_AAAAA_AAAAA_AAAAA_AAAAA_A;0;_

当用户键入时,会自动插入一个空格每 5 个字符之后。

但是,如果用户粘贴已包含空格的文本(例如,从我们发送给他们的电子邮件中复制的文本),则每个空格都会占用所需字符之一,并且文本的最后 5 个字符将丢失。

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

Given this text for the EditMask property of a TMaskEdit control,

>AAAAA_AAAAA_AAAAA_AAAAA_AAAAA_AAAAA_A;0;_

When the user types, a space is automatically inserted after every 5 characters.

However, if the user pastes in text that already contains the spaces (for example, copied from an email we sent them), then each space uses up one of the required characters and the last 5 characters of the text are lost.

Is there a way to identify a particular character in the TEditMask so it is either empty or the specific character (in this case, a space)? Or is there a different control I could use?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

人疚 2025-01-19 13:27:45

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

  • 始终使文本大写。
  • 不要依赖键盘与鼠标输入。
  • 出于视觉原因,故意消除所有空间并将它们放置在您想要的任何位置。

另外,不要错误地为每个文本块使用多个 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 上成功测试:

文本中带有固定空格的TEdit

只删除单个字符感觉很奇怪,并且当最后一个字符是空格时不起作用。我会把它留给你让它变得完美。

Don't use TMaskEdit and its horrible optics and limitations. Since the text you want to operate on is rather short you can use a TEdit directly and react upon changes to its text:

  • Always make the text uppercase.
  • Don't rely on keyboard versus mouse input.
  • Kill all spaces on purpose and put them anywhere you want for optic reasons.

Also don't make the mistake to use several TEdits for each block of text, as that will disrupt anyone who wants to paste the clipboard content of the long serial(?) at once - I've seen software installations doing this and it was always a pain.

Have an empty form, add a TEdit and make this its OnChange event:

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;

Successfully tested on D7:

TEdit with fixed spaces in text

Deleting only single characters feels weird, tho, and does not work when the last one is a space. I'll leave it to you to make it perfect.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文