📄 wwmask.pas
字号:
else
if EditText[SelStart+1] in LeadBytes then
CursorInc(SelStart, 2)
else
CursorInc(SelStart, 1);
end;
end;
end;
procedure TwwSpecialMaskEdit.CursorInc(CursorPos: Integer; Incr: Integer);
var
NuPos: Integer;
begin
NuPos := CursorPos + Incr;
NuPos := GetNextEditChar(NuPos);
if IsLiteralChar(EditMask, nuPos) then
NuPos := CursorPos;
SetCursor(NuPos);
end;
procedure TwwSpecialMaskEdit.CursorDec(CursorPos: Integer);
var
nuPos: Integer;
begin
nuPos := CursorPos;
Dec(nuPos);
nuPos := GetPriorEditChar(nuPos);
SetCursor(NuPos);
end;
function TwwSpecialMaskEdit.GetFirstEditChar: Integer;
begin
Result := 0;
if IsMasked then
Result := GetNextEditChar(0);
end;
function TwwSpecialMaskEdit.GetLastEditChar: Integer;
begin
Result := GetMaxChars;
if IsMasked then
Result := GetPriorEditChar(Result - 1);
end;
function TwwSpecialMaskEdit.GetNextEditChar(Offset: Integer): Integer;
begin
Result := Offset;
while(Result < FMaxChars) and (IsLiteralChar(EditMask, Result)) do
Inc(Result);
end;
function TwwSpecialMaskEdit.GetPriorEditChar(Offset: Integer): Integer;
begin
Result := Offset;
while(Result >= 0) and (IsLiteralChar(EditMask, Result)) do
Dec(Result);
if Result < 0 then
Result := GetNextEditChar(Result);
end;
procedure TwwSpecialMaskEdit.HomeEndKeys(CharCode: Word; Shift: TShiftState);
var
SelStart, SelStop : Integer;
begin
GetSel(SelStart, SelStop);
if (CharCode = VK_HOME) then
begin
if (ssShift in Shift) then
begin
if (SelStart <> FCaretPos) and (SelStop <> (SelStart + 1)) then
SelStop := SelStart + 1;
SetSel(0, SelStop);
CheckCursor;
end
else
SetCursor(0);
FCaretPos := 0;
end
else
begin
if (ssShift in Shift) then
begin
if (SelStop <> FCaretPos) and (SelStop <> (SelStart + 1)) then
SelStart := SelStop - 1;
SetSel(SelStart, FMaxChars);
CheckCursor;
end
else
SetCursor(FMaxChars);
FCaretPos := FMaxChars;
end;
end;
procedure TwwSpecialMaskEdit.DeleteKeys(CharCode: Word);
var
SelStart, SelStop : Integer;
NuSelStart: Integer;
Str: string;
begin
if ReadOnly then Exit;
GetSel(SelStart, SelStop);
if ((SelStop - SelStart) <= 1) and (CharCode = VK_BACK) then
begin
NuSelStart := SelStart;
CursorDec(SelStart);
GetSel(SelStart, SelStop);
if SelStart = NuSelStart then Exit;
end;
if (SelStop - SelStart) < 1 then Exit;
Str := EditText;
DeleteSelection(Str, SelStart, SelStop - SelStart);
Str := Copy(Str, SelStart+1, SelStop - SelStart);
SendMessage(Handle, EM_REPLACESEL, 0, LongInt(PChar(Str)));
if (SelStop - SelStart) <> 1 then
begin
SelStart := GetNextEditChar(SelStart);
SetCursor(SelStart);
end
else begin
GetSel(SelStart, SelStop);
SetCursor(SelStart - 1);
end;
end;
procedure TwwSpecialMaskEdit.CMEnter(var Message: TCMEnter);
begin
if IsMasked and not (csDesigning in ComponentState) then
begin
if not (wwmsReEnter in FMaskState) then
begin
FOldValue := EditText;
inherited;
end;
Exclude(FMaskState, wwmsReEnter);
CheckCursor;
end
else
inherited;
end;
procedure TwwSpecialMaskEdit.CMTextChanged(var Message: TMessage);
var
SelStart, SelStop : Integer;
Temp: Integer;
begin
inherited;
FOldValue := EditText;
if HandleAllocated then
begin
GetSel(SelStart, SelStop);
Temp := GetNextEditChar(SelStart);
if Temp <> SelStart then
SetCursor(Temp);
end;
end;
procedure TwwSpecialMaskEdit.CMWantSpecialKey(var Message: TCMWantSpecialKey);
begin
inherited;
if (Message.CharCode = VK_ESCAPE) and IsMasked and Modified then
Message.Result := 1;
end;
procedure TwwSpecialMaskEdit.CMExit(var Message: TCMExit);
begin
if IsMasked and not (csDesigning in ComponentState) then
begin
ValidateEdit;
CheckCursor;
end;
inherited;
end;
procedure TwwSpecialMaskEdit.ValidateEdit;
var
Str: string;
Pos: Integer;
begin
Str := EditText;
if IsMasked and Modified then
begin
if not Validate(Str, Pos) then
begin
if not (csDesigning in ComponentState) then
begin
Include(FMaskState, wwmsReEnter);
SetFocus;
end;
SetCursor(Pos);
ValidateError;
end;
end;
end;
procedure TwwSpecialMaskEdit.ValidateError;
begin
MessageBeep(0);
raise EDBEditError.CreateResFmt(@SMaskEditErr, [EditMask]);
end;
function TwwSpecialMaskEdit.AddEditFormat(const Value: string; Active: Boolean): string;
begin
if not Active then
Result := MaskDoFormatText(EditMask, Value, ' ')
else
Result := MaskDoFormatText(EditMask, Value, FMaskBlank);
end;
function TwwSpecialMaskEdit.RemoveEditFormat(const Value: string): string;
var
I: Integer;
OldLen: Integer;
Offset, MaskOffset: Integer;
CType: TMaskCharType;
Dir: TMaskDirectives;
begin
Offset := 1;
Result := Value;
for MaskOffset := 1 to Length(EditMask) do
begin
CType := MaskGetCharType(EditMask, MaskOffset);
if CType in [mcLiteral, mcIntlLiteral] then
Result := Copy(Result, 1, Offset - 1) +
Copy(Result, Offset + 1, Length(Result) - Offset);
if CType in [mcMask, mcMaskOpt] then Inc(Offset);
end;
Dir := MaskGetCurrentDirectives(EditMask, 1);
if mdReverseDir in Dir then
begin
Offset := 1;
for I := 1 to Length(Result) do
begin
if Result[I] = FMaskBlank then
Inc(Offset)
else
break;
end;
if Offset <> 1 then
Result := Copy(Result, Offset, Length(Result) - Offset + 1);
end
else begin
OldLen := Length(Result);
for I := 1 to OldLen do
begin
if Result[OldLen - I + 1] = FMaskBlank then
SetLength(Result, Length(Result) - 1)
else Break;
end;
end;
if FMaskBlank <> ' ' then
begin
OldLen := Length(Result);
for I := 1 to OldLen do
begin
if Result[I] = FMaskBlank then
Result[I] := ' ';
if I > OldLen then Break;
end;
end;
end;
function TwwSpecialMaskEdit.InputChar(var NewChar: Char; Offset: Integer): Boolean;
var
MaskOffset: Integer;
CType: TMaskCharType;
InChar: Char;
begin
Result := True;
if EditMask <> '' then
begin
Result := False;
MaskOffset := OffsetToMaskOffset(EditMask, Offset);
if MaskOffset >= 0 then
begin
CType := MaskGetCharType(EditMask, MaskOffset);
InChar := NewChar;
Result := DoInputChar(NewChar, MaskOffset);
if not Result and (CType in [mcMask, mcMaskOpt]) then
begin
MaskOffset := FindLiteralChar (MaskOffset, InChar);
if MaskOffset > 0 then
begin
MaskOffset := MaskOffsetToOffset(EditMask, MaskOffset);
SetCursor (MaskOffset);
Exit;
end;
end;
end;
end;
if not Result then
MessageBeep(0)
end;
function TwwSpecialMaskEdit.DoInputChar(var NewChar: Char; MaskOffset: Integer): Boolean;
var
Dir: TMaskDirectives;
Str: string;
CType: TMaskCharType;
function IsKatakana(const Chr: Byte): Boolean;
begin
Result := (SysLocale.PriLangID = LANG_JAPANESE) and (Chr in [$A1..$DF]);
end;
function TestChar(NewChar: Char): Boolean;
var
Offset: Integer;
begin
Offset := MaskOffsetToOffset(EditMask, MaskOffset);
Result := not ((MaskOffset < Length(EditMask)) and
(UpCase(EditMask[MaskOffset]) = UpCase(EditMask[MaskOffset+1]))) or
(ByteType(EditText, Offset) = mbTrailByte) or
(ByteType(EditText, Offset+1) = mbLeadByte);
end;
begin
Result := True;
CType := MaskGetCharType(EditMask, MaskOffset);
if CType in [mcLiteral, mcIntlLiteral] then
NewChar := MaskIntlLiteralToChar(EditMask[MaskOffset])
else
begin
Dir := MaskGetCurrentDirectives(EditMask, MaskOffset);
case EditMask[MaskOffset] of
mMskNumeric, mMskNumericOpt:
begin
if not ((NewChar >= '0') and (NewChar <= '9')) then
Result := False;
end;
mMskNumSymOpt:
begin
if not (((NewChar >= '0') and (NewChar <= '9')) or
(NewChar = ' ') or(NewChar = '+') or(NewChar = '-')) then
Result := False;
end;
mMskAscii, mMskAsciiOpt:
begin
if (NewChar in LeadBytes) and TestChar(NewChar) then
begin
Result := False;
Exit;
end;
if IsCharAlpha(NewChar) then
begin
Str := ' ';
Str[1] := NewChar;
if (mdUpperCase in Dir) then
Str := AnsiUpperCase(Str)
else if mdLowerCase in Dir then
Str := AnsiLowerCase(Str);
NewChar := Str[1];
end;
end;
mMskAlpha, mMskAlphaOpt, mMskAlphaNum, mMskAlphaNumOpt:
begin
if (NewChar in LeadBytes) then
begin
if TestChar(NewChar) then
Result := False;
Exit;
end;
Str := ' ';
Str[1] := NewChar;
if IsKatakana(Byte(NewChar)) then
begin
NewChar := Str[1];
Exit;
end;
if not IsCharAlpha(NewChar) then
begin
Result := False;
if ((EditMask[MaskOffset] = mMskAlphaNum) or
(EditMask[MaskOffset] = mMskAlphaNumOpt)) and
(IsCharAlphaNumeric(NewChar)) then
Result := True;
end
else if mdUpperCase in Dir then
Str := AnsiUpperCase(Str)
else if mdLowerCase in Dir then
Str := AnsiLowerCase(Str);
NewChar := Str[1];
end;
end;
end;
end;
function TwwSpecialMaskEdit.Validate(const Value: string; var Pos: Integer): Boolean;
var
Offset, MaskOffset: Integer;
CType: TMaskCharType;
begin
Result := True;
Offset := 1;
for MaskOffset := 1 to Length(EditMask) do
begin
CType := MaskGetCharType(EditMask, MaskOffset);
if CType in [mcLiteral, mcIntlLiteral, mcMaskOpt] then
Inc(Offset)
else if (CType = mcMask) and (Value <> '') then
begin
if (Value [Offset] = FMaskBlank) or
((Value [Offset] = ' ') and (EditMask[MaskOffset] <> mMskAscii)) then
begin
Result := False;
Pos := Offset - 1;
Exit;
end;
Inc(Offset);
end;
end;
end;
function TwwSpecialMaskEdit.DeleteSelection(var Value: string; Offset: Integer;
Len: Integer): Boolean;
var
EndDel: Integer;
StrOffset, MaskOffset, Temp: Integer;
CType: TMaskCharType;
begin
Result := True;
if Len = 0 then Exit;
StrOffset := Offset + 1;
EndDel := StrOffset + Len;
Temp := OffsetToMaskOffset(EditMask, Offset);
if Temp < 0 then Exit;
for MaskOffset := Temp to Length(EditMask) do
begin
CType := MaskGetCharType(EditMask, MaskOffset);
if CType in [mcLiteral, mcIntlLiteral] then
Inc(StrOffset)
else if CType in [mcMask, mcMaskOpt] then
begin
Value[StrOffset] := FMaskBlank;
Inc(StrOffset);
end;
if StrOffset >= EndDel then Break;
end;
end;
function TwwSpecialMaskEdit.InputString(var Value: string; const NewValue: string;
Offset: Integer): Integer;
var
NewOffset, MaskOffset, Temp: Integer;
CType: TMaskCharType;
NewVal: string;
NewChar: Char;
begin
Result := Offset;
if NewValue = '' then Exit;
{ replace chars with new chars, except literals }
NewOffset := 1;
NewVal := NewValue;
Temp := OffsetToMaskOffset(EditMask, Offset);
if Temp < 0 then Exit;
MaskOffset := Temp;
While MaskOffset <= Length(EditMask) do
begin
CType := MaskGetCharType(EditMask, MaskOffset);
if CType in [mcLiteral, mcIntlLiteral, mcMask, mcMaskOpt] then
begin
NewChar := NewVal[NewOffset];
if not (DoInputChar(NewChar, MaskOffset)) then
begin
if (NewChar in LeadBytes) then
NewVal[NewOffset + 1] := FMaskBlank;
NewChar := FMaskBlank;
end;
{ if pasted text does not contain a literal in the right place,
insert one }
if not ((CType in [mcLiteral, mcIntlLiteral]) and
(NewChar <> NewVal[NewOffset])) then
begin
NewVal[NewOffset] := NewChar;
if (NewChar in LeadBytes) then
begin
Inc(NewOffset);
Inc(MaskOffset);
end;
end
else
NewVal := Copy(NewVal, 1, NewOffset-1) + NewChar +
Copy(NewVal, NewOffset, Length (NewVal));
Inc(NewOffset);
end;
if (NewOffset + Offset) > FMaxChars then Break;
if (NewOffset) > Length(NewVal) then Break;
Inc(MaskOffset);
end;
if (Offset + Length(NewVal)) < FMaxChars then
begin
if ByteType(Value, OffSet + Length(NewVal) + 1) = mbTrailByte then
begin
NewVal := NewVal + FMaskBlank;
Inc(NewOffset);
end;
Value := Copy(Value, 1, Offset) + NewVal +
Copy(Value, OffSet + Length(NewVal) + 1,
FMaxChars -(Offset + Length(NewVal)));
end
else
begin
Temp := Offset;
if (ByteType(NewVal, FMaxChars - Offset) = mbLeadByte) then
Inc(Temp);
Value := Copy(Value, 1, Offset) +
Copy(NewVal, 1, FMaxChars - Temp);
end;
Result := NewOffset + Offset - 1;
end;
function TwwSpecialMaskEdit.FindLiteralChar(MaskOffset: Integer; InChar: Char): Integer;
var
CType: TMaskCharType;
LitChar: Char;
begin
Result := -1;
while MaskOffset < Length(EditMask) do
begin
Inc(MaskOffset);
CType := MaskGetCharType(EditMask, MaskOffset);
if CType in [mcLiteral, mcIntlLiteral] then
begin
LitChar := EditMask[MaskOffset];
if CType = mcIntlLiteral then
LitChar := MaskIntlLiteralToChar(LitChar);
if LitChar = InChar then
Result := MaskOffset;
Exit;
end;
end;
end;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -