📄 dbflaedit.pas
字号:
inherited;
Exit;
end;
{ Since edit controls do not handle justification unless multi-line (and
then only poorly) we will draw right and center justify manually unless
the edit has the focus. }
if FCanvas = nil then
begin
FCanvas := TControlCanvas.Create;
FCanvas.Control := Self;
end;
DC := Message.DC;
if DC = 0 then DC := BeginPaint(Handle, PS);
FCanvas.Handle := DC;
try
FCanvas.Font := Font;
with FCanvas do
begin
R := ClientRect;
if not (NewStyleControls and Ctl3D) and (BorderStyle = bsSingle) then
begin
Brush.Color := clWindowFrame;
FrameRect(R);
InflateRect(R, -1, -1);
end;
Brush.Color := Color;
if not Enabled then
Font.Color := clGrayText;
if (csPaintCopy in ControlState) and (FDataLink.Field <> nil) then
begin
S := FDataLink.Field.DisplayText;
case CharCase of
ecUpperCase: S := AnsiUpperCase(S);
ecLowerCase: S := AnsiLowerCase(S);
end;
end else
S := EditText;
if PasswordChar <> #0 then FillChar(S[1], Length(S), PasswordChar);
Margins := GetTextMargins;
case AAlignment of
taLeftJustify: Left := Margins.X;
taRightJustify: Left := ClientWidth - TextWidth(S) - Margins.X - 1;
else
Left := (ClientWidth - TextWidth(S)) div 2;
end;
if SysLocale.MiddleEast then UpdateTextFlags;
TextRect(R, Left, Margins.Y, S);
end;
finally
FCanvas.Handle := 0;
if Message.DC = 0 then EndPaint(Handle, PS);
end;
end;
procedure TDBFlatEdit.CMGetDataLink(var Message: TMessage);
begin
Message.Result := Integer(FDataLink);
end;
function TDBFlatEdit.GetTextMargins: TPoint;
var
DC: HDC;
SaveFont: HFont;
I: Integer;
SysMetrics, Metrics: TTextMetric;
begin
if NewStyleControls then
begin
if BorderStyle = bsNone then I := 0 else
if Ctl3D then I := 1 else I := 2;
Result.X := SendMessage(Handle, EM_GETMARGINS, 0, 0) and $0000FFFF + I;
Result.Y := I;
end else
begin
if BorderStyle = bsNone then I := 0 else
begin
DC := GetDC(0);
GetTextMetrics(DC, SysMetrics);
SaveFont := SelectObject(DC, Font.Handle);
GetTextMetrics(DC, Metrics);
SelectObject(DC, SaveFont);
ReleaseDC(0, DC);
I := SysMetrics.tmHeight;
if I > Metrics.tmHeight then I := Metrics.tmHeight;
I := I div 4;
end;
Result.X := I;
Result.Y := I;
end;
end;
function TDBFlatEdit.ExecuteAction(Action: TBasicAction): Boolean;
begin
Result := inherited ExecuteAction(Action) or (FDataLink <> nil) and
FDataLink.ExecuteAction(Action);
end;
function TDBFlatEdit.UpdateAction(Action: TBasicAction): Boolean;
begin
Result := inherited UpdateAction(Action) or (FDataLink <> nil) and
FDataLink.UpdateAction(Action);
end;
function MaskGetCharType(const EditMask: string; MaskOffset: Integer): TMaskCharType;
var
MaskChar: Char;
begin
Result := mcLiteral;
MaskChar := #0;
if MaskOffset <= Length(EditMask) then
MaskChar := EditMask[MaskOffset];
if MaskOffset > Length(EditMask) then
Result := mcNone
else if ByteType(EditMask, MaskOffset) <> mbSingleByte then
Result := mcLiteral
else if (MaskOffset > 1) and (EditMask[MaskOffset - 1] = mDirLiteral) and
(ByteType(EditMask, MaskOffset - 1) = mbSingleByte) and
not ((MaskOffset > 2) and (EditMask[MaskOffset - 2] = mDirLiteral) and
(ByteType(EditMask, MaskOffset - 2) = mbSingleByte)) then
Result := mcLiteral
else if (MaskChar = MaskFieldSeparator) and
(Length(EditMask) >= 4) and
(MaskOffset > Length(EditMask) - 4) then
Result := mcFieldSeparator
else if (Length(EditMask) >= 4) and
(MaskOffset > (Length(EditMask) - 4)) and
(EditMask[MaskOffset - 1] = MaskFieldSeparator) and
not ((MaskOffset > 2) and (EditMask[MaskOffset - 2] = mDirLiteral) and
(ByteType(EditMask, MaskOffset - 2) <> mbTrailByte)) then
Result := mcField
else if MaskChar in [mMskTimeSeparator, mMskDateSeparator] then
Result := mcIntlLiteral
else if MaskChar in [mDirReverse, mDirUpperCase, mDirLowerCase,
mDirLiteral] then
Result := mcDirective
else if MaskChar in [mMskAlphaOpt, mMskAlphaNumOpt, mMskAsciiOpt,
mMskNumSymOpt, mMskNumericOpt] then
Result := mcMaskOpt
else if MaskChar in [mMskAlpha, mMskAlphaNum, mMskAscii, mMskNumeric] then
Result := mcMask;
end;
function MaskGetCurrentDirectives(const EditMask: string;
MaskOffset: Integer): TMaskDirectives;
var
I: Integer;
MaskChar: Char;
begin
Result := [];
for I := 1 to Length(EditMask) do
begin
MaskChar := EditMask[I];
if (MaskChar = mDirReverse) then
Include(Result, mdReverseDir)
else if (MaskChar = mDirUpperCase) and (I < MaskOffset) then
begin
Exclude(Result, mdLowerCase);
if not ((I > 1) and (EditMask[I-1] = mDirLowerCase)) then
Include(Result, mdUpperCase);
end
else if (MaskChar = mDirLowerCase) and (I < MaskOffset) then
begin
Exclude(Result, mdUpperCase);
Include(Result, mdLowerCase);
end;
end;
if MaskGetCharType(EditMask, MaskOffset) = mcLiteral then
Include(Result, mdLiteralChar);
end;
function MaskIntlLiteralToChar(IChar: Char): Char;
begin
Result := IChar;
case IChar of
mMskTimeSeparator: Result := TimeSeparator;
mMskDateSeparator: Result := DateSeparator;
end;
end;
function MaskDoFormatText(const EditMask: string; const Value: string;
Blank: Char): string;
var
I: Integer;
Offset, MaskOffset: Integer;
CType: TMaskCharType;
Dir: TMaskDirectives;
begin
Result := Value;
Dir := MaskGetCurrentDirectives(EditMask, 1);
if not (mdReverseDir in Dir) then
begin
{ starting at the beginning, insert literal chars in the string
and add spaces on the end }
Offset := 1;
for MaskOffset := 1 to Length(EditMask) do
begin
CType := MaskGetCharType(EditMask, MaskOffset);
if CType in [mcLiteral, mcIntlLiteral] then
begin
Result := Copy(Result, 1, Offset - 1) +
MaskIntlLiteralToChar(EditMask[MaskOffset]) +
Copy(Result, Offset, Length(Result) - Offset + 1);
Inc(Offset);
end
else if CType in [mcMask, mcMaskOpt] then
begin
if Offset > Length(Result) then
Result := Result + Blank;
Inc(Offset);
end;
end;
end
else
begin
{ starting at the end, insert literal chars in the string
and add spaces at the beginning }
Offset := Length(Result);
for I := 0 to(Length(EditMask) - 1) do
begin
MaskOffset := Length(EditMask) - I;
CType := MaskGetCharType(EditMask, MaskOffset);
if CType in [mcLiteral, mcIntlLiteral] then
begin
Result := Copy(Result, 1, Offset) +
MaskIntlLiteralToChar(EditMask[MaskOffset]) +
Copy(Result, Offset + 1, Length(Result) - Offset);
end
else if CType in [mcMask, mcMaskOpt] then
begin
if Offset < 1 then
Result := Blank + Result
else
Dec(Offset);
end;
end;
end;
end;
function MaskOffsetToOffset(const EditMask: String; MaskOffset: Integer): Integer;
var
I: Integer;
CType: TMaskCharType;
begin
Result := 0;
for I := 1 to MaskOffset do
begin
CType := MaskGetCharType(EditMask, I);
if not (CType in [mcDirective, mcField, mcFieldSeparator]) then
Inc(Result);
end;
end;
function OffsetToMaskOffset(const EditMask: string; Offset: Integer): Integer;
var
I: Integer;
Count: Integer;
MaxChars: Integer;
begin
MaxChars := MaskOffsetToOffset(EditMask, Length(EditMask));
if Offset > MaxChars then
begin
Result := -1;
Exit;
end;
Result := 0;
Count := Offset;
for I := 1 to Length(EditMask) do
begin
Inc(Result);
if not (mcDirective = MaskGetCharType(EditMask, I)) then
begin
Dec(Count);
if Count < 0 then
Exit;
end;
end;
end;
function IsLiteralChar(const EditMask: string; Offset: Integer): Boolean;
var
MaskOffset: Integer;
CType: TMaskCharType;
begin
Result := False;
MaskOffset := OffsetToMaskOffset(EditMask, Offset);
if MaskOffset >= 0 then
begin
CType := MaskGetCharType(EditMask, MaskOffset);
Result := CType in [mcLiteral, mcIntlLiteral];
end;
end;
function PadSubField(const EditMask: String; const Value: string;
StartFld, StopFld, Len: Integer; Blank: Char): string;
var
Dir: TMaskDirectives;
StartPad: Integer;
K: Integer;
begin
if (StopFld - StartFld) < Len then
begin
{ found literal at position J, now pad it }
Dir := MaskGetCurrentDirectives(EditMask, 1);
StartPad := StopFld - 1;
if mdReverseDir in Dir then
StartPad := StartFld - 1;
Result := Copy(Value, 1, StartPad);
for K := 1 to (Len - (StopFld - StartFld)) do
Result := Result + Blank;
Result := Result + Copy(Value, StartPad + 1, Length(Value));
end
else if (StopFld - StartFld) > Len then
begin
Dir := MaskGetCurrentDirectives(EditMask, 1);
if mdReverseDir in Dir then
Result := Copy(Value, 1, StartFld - 1) +
Copy(Value, StopFld - Len, Length(Value))
else
Result := Copy(Value, 1, StartFld + Len - 1) +
Copy(Value, StopFld, Length(Value));
end
else
Result := Value;
end;
function PadInputLiterals(const EditMask: String; const Value: string;
Blank: Char): string;
var
J: Integer;
LastLiteral, EndSubFld: Integer;
Offset, MaskOffset: Integer;
CType: TMaskCharType;
MaxChars: Integer;
begin
LastLiteral := 0;
Result := Value;
for MaskOffset := 1 to Length(EditMask) do
begin
CType := MaskGetCharType(EditMask, MaskOffset);
if CType in [mcLiteral, mcIntlLiteral] then
begin
Offset := MaskOffsetToOffset(EditMask, MaskOffset);
EndSubFld := Length(Result) + 1;
for J := LastLiteral + 1 to Length(Result) do
begin
if Result[J] = MaskIntlLiteralToChar(EditMask[MaskOffset]) then
begin
EndSubFld := J;
Break;
end;
end;
{ we have found a subfield, ensure that it complies }
if EndSubFld > Length(Result) then
Result := Result + MaskIntlLiteralToChar(EditMask[MaskOffset]);
Result := PadSubField(EditMask, Result, LastLiteral + 1, EndSubFld,
Offset - (LastLiteral + 1), Blank);
LastLiteral := Offset;
end;
end;
{ensure that the remainder complies, too }
MaxChars := MaskOffsetToOffset(EditMask, Length(EditMask));
if Length (Result) <> MaxChars then
Result := PadSubField(EditMask, Result, LastLiteral + 1, Length (Result) + 1,
MaxChars - LastLiteral, Blank);
{ replace non-literal blanks with blank char }
for Offset := 1 to Length (Result) do
begin
if Result[Offset] = ' ' then
begin
if not IsLiteralChar(EditMask, Offset - 1) then
Result[Offset] := Blank;
end;
end;
end;
{ TCustomMaskEdit }
constructor TCustomMaskFlatEdit.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FMaskState := [];
FMaskBlank := DefaultBlank;
end;
procedure TCustomMaskFlatEdit.KeyDown(var Key: Word; Shift: TShiftState);
begin
if not FSettingCursor then inherited KeyDown(Key, Shift);
if IsMasked and (Key <> 0) and not (ssAlt in Shift) then
begin
if (Key = VK_LEFT) or(Key = VK_RIGHT) then
begin
ArrowKeys(Key, Shift);
if not ((ssShift in Shift) or (ssCtrl in Shift)) then
Key := 0;
Exit;
end
else if (Key = VK_UP) or(Key = VK_DOWN) then
begin
Key := 0;
Exit;
end
else if (Key = VK_HOME) or(Key = VK_END) then
begin
HomeEndKeys(Key, Shift);
Key := 0;
Exit;
end
else if ((Key = VK_DELETE) and not (ssShift in Shift)) or
(Key = VK_BACK) then
begin
if EditCanModify then
DeleteKeys(Key);
Key := 0;
Exit;
end;
CheckCursor;
end;
end;
procedure TCustomMaskFlatEdit.KeyUp(var Key: Word; Shift: TShiftState);
begin
if not FSettingCursor then inherited KeyUp(Key, Shift);
if IsMasked and (Key <> 0) then
begin
if ((Key = VK_LEFT) or(Key = VK_RIGHT)) and (ssCtrl in Shift) then
CheckCursor;
end;
end;
procedure TCustomMaskFlatEdit.KeyPress(var Key: Char);
begin
inherited KeyPress(Key);
if IsMasked and (Key <> #0) and not (Char(Key) in [^V, ^X, ^C]) then
begin
CharKeys(Key);
Key := #0;
end;
end;
procedure TCustomMaskFlatEdit.WMLButtonDown(var Message: TWMLButtonDown);
begin
inherited;
FBtnDownX := Message.XPos;
end;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -