如何将 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 时不起作用。我会留给你去完善它。
给定 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 时不起作用。我会留给你去完善它。