cxmaskedit.pas

来自「胜天进销存源码,国产优秀的进销存」· PAS 代码 · 共 2,607 行 · 第 1/5 页

PAS
2,607
字号
      end
      else
        ActiveProperties.PrepareDisplayValue(EditValue, ADisplayValue, Focused);
    end;
    FEdit.SetInternalDisplayValue(ADisplayValue);
  end;
end;

procedure TcxMaskEditCustomMode.ClearText;
begin
  if HasEdit then
    FEdit.DataBinding.UpdateNotConnectedDBEditDisplayValue;
end;

function TcxMaskEditCustomMode.GetMaskKind: TcxEditMaskKind;
begin
  Result := emkStandard;
end;

function TcxMaskEditCustomMode.HasEdit: Boolean;
begin
  Result := (FEdit <> nil) and not FEdit.PropertiesChangeLocked;
end;

function TcxMaskEditCustomMode.GetProperties: TcxCustomMaskEditProperties;
begin
  if FEdit <> nil then
    Result := FEdit.ActiveProperties
  else
    Result := FProperties;
end;

{ TcxMaskEditStandardMode }

constructor TcxMaskEditStandardMode.Create(AEdit: TcxCustomMaskEdit;
  AProperties: TcxCustomMaskEditProperties);
begin
  inherited Create(AEdit, AProperties);

  FMask := TcxStandardMask.Create;
end;

destructor TcxMaskEditStandardMode.Destroy;
begin
  FMask.Free;
  inherited Destroy;
end;

procedure TcxMaskEditStandardMode.AfterPasteFromClipboard;
var
  AText: string;
begin
  AText := Clipboard.AsText;
  FEdit.SelStart := FSelStart + Length(AText);
  if FEdit.SelStart >= Length(FEdit.EditText) then
    FEdit.SelStart := Length(FEdit.EditText) - 1;
  if FEdit.SelStart < 0 then
    FEdit.SelStart := 0;
  if FMask.Items[FEdit.SelStart] is TcxStandardMaskLiteralItem then
  begin
    FEdit.FShiftOn := False;
    PressRight;
  end;
end;

procedure TcxMaskEditStandardMode.Compile(AMask: string);
begin
  FEditMask := AMask;
  if Properties.EmptyMask(AMask) then
    Exit;

  FMask.Compile(AMask);

  FNeedUpdateEditValue := not HasEdit;
end;

function TcxMaskEditStandardMode.GetEmptyString: string;
begin
  Result := FMask.EmptyString;
end;

function TcxMaskEditStandardMode.GetFormattedText(AText: string;
  AMatchForBlanksAndLiterals: Boolean = True): string;
begin
  FMask.Format(AText, True, AMatchForBlanksAndLiterals);
  Result := AText;
end;

procedure TcxMaskEditStandardMode.GotoEnd;
begin
end;

function TcxMaskEditStandardMode.IsCursorBegin: Boolean;
var
  I: Integer;
  ACount: Integer;
begin
  ACount := 0;
  for I := 0 to FMask.Count - 1 do
  begin
    if FMask.Items[I] is TcxStandardMaskLiteralItem then
      Inc(ACount)
    else
      Break;
  end;
  Result := (FEdit.SelStart <= ACount) and (FEdit.SelLength <= 1) or
    (FEdit.SelStart <= ACount) and (FEdit.CursorPos = FEdit.SelStart);
end;

function TcxMaskEditStandardMode.IsCursorEnd: Boolean;
begin
  Result := FEdit.SelStart = Length(FEdit.EditText);  
end;

function TcxMaskEditStandardMode.IsFullValidText(AText: string): Boolean;
begin
  Result := FMask.IsFullValid(AText);
  if not Result and Properties.IgnoreMaskBlank then
    Result := AText = GetFormattedText('');
end;

procedure TcxMaskEditStandardMode.LMouseDown;
begin
  if FEdit.HandleAllocated and Properties.IsMasked then
  begin
    if FEdit.SelLength = 0 then
      FEdit.DirectSetSelLength(1);
  end;
end;

procedure TcxMaskEditStandardMode.PrePasteFromClipboard;
var
  AText: string;
begin
  AText := Clipboard.AsText;
  FSelStart := FEdit.SelStart;
  FEdit.DirectSetSelStart(FSelStart);
  FEdit.DirectSetSelLength(Length(AText));
end;

function TcxMaskEditStandardMode.PressBackSpace: Boolean;
begin
  Result := False;

  if FEdit.SelLength <= 1 then
    PressLeft;
  PressDelete;
end;

function TcxMaskEditStandardMode.PressDelete: Boolean;
var
  ABlank: Char;
  ASelStart: Integer;
  AText: string;
  I: Integer;
begin
  Result := False;

  AText := FEdit.EditText;
  ASelStart := FEdit.SelStart;
  for I := FEdit.SelStart to FEdit.SelStart + FEdit.SelLength - 1 do
  begin
    if FMask.Items[I] is TcxStandardMaskManyItem then
    begin
      ABlank := GetBlank(I + 1);
      if ABlank <> #0 then
      begin
        Delete(AText, I + 1, 1);
        Insert(ABlank, AText, I + 1);
        FEdit.SetInternalDisplayValue(AText);
        FEdit.SelStart := ASelStart;
      end;
    end;
  end;
end;

function TcxMaskEditStandardMode.PressEnd: Boolean;
begin
  if FEdit.FShiftOn then
  begin
    Result := True;
    Exit;
  end
  else
    Result := False;

  FEdit.SelStart := Length(FEdit.EditText);
end;

function TcxMaskEditStandardMode.PressHome: Boolean;
begin
  if FEdit.FShiftOn then
  begin
    Result := True;
    Exit;
  end
  else
    Result := False;

  FEdit.SelStart := 0;
  if FMask.Count > 0 then
    if FMask.Items[FEdit.SelStart] is TcxStandardMaskLiteralItem then
      PressRight;
end;

function TcxMaskEditStandardMode.PressLeft: Boolean;
  function GetSelStart: Integer;
  var
    I: Integer;
    AReset: Boolean;
    AEnd: Integer;
  begin
    Result := 0;
    AReset := True;
    AEnd := FEdit.SelStart + FEdit.SelLength;
    if AEnd >= Length(FEdit.EditText) then
      Dec(AEnd);
    if AEnd < 0 then
      AEnd := 0;
    for I := FEdit.SelStart to AEnd do
    begin
      if FMask.Items[I] is TcxStandardMaskLiteralItem then
        Inc(Result)
      else
      begin
        AReset := False;
        Break;
      end;
    end;
    if AReset then
    begin
      if FEdit.SelStart + FEdit.SelLength >= Length(FEdit.EditText) then
      begin
        Result := AEnd - FEdit.SelStart;
        Inc(Result);
      end
      else
        Result := 0;
    end;
  end;
var
  ADec: Integer;
  ALeftLiteralCount: Integer;
  I: Integer;
begin
  if FEdit.FShiftOn then
  begin
    if FEdit.SelLength = 1 then
    begin
      FEdit.SelStart := FEdit.SelStart + 1;
      FEdit.SelLength := 0;
      FEdit.SendMyKeyDown(VK_LEFT, []);
      FEdit.SendMyKeyDown(VK_LEFT, []);
    end;

    Result := True;
    Exit;
  end
  else
    Result := False;

  if FEdit.SelLength > 1 then
  begin
    I := FEdit.SelStart + GetSelStart;
    FEdit.SelStart := 0;
    FEdit.SelStart := I;
    Exit;
  end;

  ALeftLiteralCount := 0;
  for I := FEdit.SelStart - 1 downto 0 do
  begin
    if FMask.Items[I] is TcxStandardMaskLiteralItem then
      Inc(ALeftLiteralCount)
    else
      Break;
  end;

  ADec := ALeftLiteralCount + 1;
  if FEdit.SelStart - ADec < 0 then
    ADec := 0;

  if FEdit.SelStart > 0 then
    FEdit.SelStart := FEdit.SelStart - ADec;
end;

function TcxMaskEditStandardMode.PressRight: Boolean;
  function GetSelStart(AI: Integer): Integer;
  var
    I: Integer;
    AReset: Boolean;
  begin
    Result := 0;
    AReset := True;
    for I := AI downto FEdit.SelStart do
    begin
      if FMask.Items[I] is TcxStandardMaskLiteralItem then
        Inc(Result)
      else
      begin
        AReset := False;
        Break;
      end;
    end;
    if AReset then
      Result := 0;
  end;
var
  AInc: Integer;
  ARightLiteralCount: Integer;
  I: Integer;
begin
  if FEdit.FShiftOn then
  begin
    if (FEdit.SelLength = 1) and (FEdit.SelStart = FEdit.CursorPos) then
      FEdit.SelLength := 0;

    Result := True;
    Exit;
  end
  else
    Result := False;

  if FEdit.SelLength > 1 then
  begin
    I := FEdit.SelStart + FEdit.SelLength;
    if I < Length(FEdit.EditText) then
    begin
      Dec(I);
      Dec(I, GetSelStart(I));
    end;
    FEdit.SelStart := 0;
    FEdit.SelStart := I;
    Exit;
  end;

  ARightLiteralCount := 0;
  for I := FEdit.SelStart + 1 to FMask.Count - 1 do
  begin
    if FMask.Items[I] is TcxStandardMaskLiteralItem then
      Inc(ARightLiteralCount)
    else
      Break;
  end;

  AInc := ARightLiteralCount + 1;
  if FEdit.SelStart + AInc > Length(FEdit.EditText) then
    AInc := 0;

  FEdit.SelStart := FEdit.SelStart + AInc;
end;

function TcxMaskEditStandardMode.PressSymbol(var ASymbol: Char): Boolean;
var
  AText: string;
  ASelStart: Integer;
begin
  Result := False;
  if Length(FEdit.EditText) <= 0 then
    Exit;
  if FEdit.SelStart >= Length(FEdit.EditText) then
    Exit;
  if FMask.Items[FEdit.SelStart] is TcxStandardMaskLiteralItem then
  begin
    FEdit.FShiftOn := False;
    if FEdit.SelLength > 1 then
      PressDelete;
    ASelStart := FEdit.SelStart;
    PressRight;
    if  FEdit.SelStart > ASelStart then
      PressSymbol(ASymbol);
  end
  else
  begin
    if FMask.Items[FEdit.SelStart].Check(ASymbol) and
      FEdit.IsCharValidForPos(ASymbol, FEdit.SelStart + 1) then
        if ASymbol <> #0 then
        begin
          if FEdit.SelLength > 1 then
            PressDelete;
          AText := FEdit.EditText;
          ASelStart := FEdit.SelStart;
          Delete(AText, FEdit.SelStart + 1 , 1);
          Insert(ASymbol, AText, FEdit.SelStart + 1);
          FEdit.SetInternalDisplayValue(AText);
          FEdit.SelStart := ASelStart;
          FEdit.FShiftOn := False;
          PressRight;
        end
        else
          BeepOnError;
  end;
end;

procedure TcxMaskEditStandardMode.SetText(AText: string);
begin
  LMouseDown;
end;

procedure TcxMaskEditStandardMode.SynchronizeEditValue;
begin
  inherited SynchronizeEditValue;
  LMouseDown;
end;

procedure TcxMaskEditStandardMode.UpdateEditValue;
begin
  if FNeedUpdateEditValue then
  begin
    FEdit.InternalEditValue := FMask.EmptyString;
    FNeedUpdateEditValue := False;
  end;
end;

function TcxMaskEditStandardMode.GetUpdatedText(const AText: string;
  AMatchForBlanksAndLiterals: Boolean = True): string;
begin
  Result := AText;
  if FMask.Count > 0 then
  begin
    FMask.Format(Result, Properties.CharCase = ecNormal, AMatchForBlanksAndLiterals);
    FMask.Format2(Result);
  end;
end;

function TcxMaskEditStandardMode.GetBlank(APos: Integer): Char;
begin
  Result := FMask.Blank;
end;

{ TcxMaskEditRegExprMode }

constructor TcxMaskEditRegExprMode.Create(AEdit: TcxCustomMaskEdit;
    AProperties: TcxCustomMaskEditProperties);
begin
  inherited Create(AEdit, AProperties);

  FRegExpr := TcxRegExpr.Create;
  FRegExpr.CaseInsensitive := Properties.CaseInsensitive;
  FMouseAction := False;
end;

destructor TcxMaskEditRegExprMode.Destroy;
begin
  FRegExpr.Free;
  inherited Destroy;
end;

procedure TcxMaskEditRegExprMode.AfterPasteFromClipboard;
begin
end;

procedure TcxMaskEditRegExprMode.Compile(AMask: string);
var
  I: Integer;
  AStream: TStringStream;
  AStr: string;
begin
  FEditMask := AMask;
  if Properties.EmptyMask(AMask) then
    Exit;

  AStream := TStringStream.Create(AMask);
  try
    try
      FRegExpr.Compile(AStream);
    except
      on E: EcxRegExprError do
      begin
        AStr := cxGetResourceString(@scxMaskEditRegExprError);
        for I := 0 to E.Errors.Count - 1 do
          AStr := AStr + #13#10 + E.Errors[I].FullMessage;
        raise EcxMaskEditError.Create(AStr);
      end;
    end;
  finally
    AStream.Free;
  end;
end;

function TcxMaskEditRegExprMode.PressDelete: Boolean;
begin
  CursorCorrection;
  if FEdit.SelLength <= 0 then
  begin
    if FTail <> '' then
    begin
      FSelect := FTail[1];
      Delete(FTail, 1, 1);

      if not NextTail then
      begin
        ClearTail;
        if FEdit.SelStart > 0 then
          FEdit.DirectSetSelStart(FEdit.SelStart - 1);
      end;
    end;

    Result := True;
  end
  else
  begin
    DeleteSelection;
    if NextTail then
      Result := True
    else
    begin
      FEdit.SendMyKeyDown(VK_DELETE, []);
      ClearTail;

      Result := False;
    end;
  end;

  FSelect := '';

  if not Result then
    BeepOnError;
end;

function TcxMaskEditRegExprMode.PressEnd: Boolean;
var

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?