cxmaskedit.pas

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

PAS
2,607
字号
        if ASelStart > Length(FHead) then
        begin
          FEdit.DirectSetSelStart(Length(FHead));
          Break;
        end
        else
          if ASelStart = Length(FHead) then
            Break;
      end;

  // Correct FEdit.SelLength
  if ASelEnd > ASelStart then
    CorrectSelLength;
end;

procedure TcxMaskEditRegExprExMode.DeleteSelection;
begin
  FRegExpr.UpdateOn := False;

  inherited DeleteSelection;

  FRegExpr.UpdateOn := True;

  if FUpdate <> '' then
  begin
    FRegExpr.Prev;
    Clear;
  end;
end;

function TcxMaskEditRegExprExMode.GetMaskKind: TcxEditMaskKind;
begin
  Result := emkRegExprEx;
end;

procedure TcxMaskEditRegExprExMode.UpdateTail;
var
  I: Integer;
begin
  Clear;

  if FTail = '' then
    Exit;

  for I := 1 to Length(FTail) do
  begin
    FRegExpr.Next(FTail[I]);
    FEdit.DirectSetSelStart(FEdit.SelStart + 1);
  end;

  FRegExpr.UpdateOn := True;

  if FUpdate <> '' then
    for I := 1 to Length(FUpdate) do
    begin
      FTail := FTail + FUpdate[I];
      FEdit.SendMyKeyPress(FUpdate[I]);
    end;

  FRegExpr.UpdateOn := False;

  for I := 1 to Length(FTail) do
  begin
    FRegExpr.Prev;
    FEdit.DirectSetSelStart(FEdit.SelStart - 1);
  end;
end;

procedure TcxMaskEditRegExprExMode.InternalSymbolUpdate(ASymbol: Char);
begin
  FInternalUpdate := FInternalUpdate + ASymbol;
end;

{ TcxCustomMaskEditProperties }

constructor TcxCustomMaskEditProperties.Create(AOwner: TPersistent);
begin
  inherited Create(AOwner);

  MaskKind := emkStandard;
  FAlwaysShowBlanksAndLiterals := False;
  ValidateOnEnter := True;
  CaseInsensitive := True;
  FTempMode := nil;
end;

destructor TcxCustomMaskEditProperties.Destroy;
begin
  FTempMode.Free;

  inherited Destroy;
end;

procedure TcxCustomMaskEditProperties.Assign(Source: TPersistent);
begin
  if Source is TcxCustomMaskEditProperties then
  begin
    BeginUpdate;
    try
      inherited Assign(Source);
      with Source as TcxCustomMaskEditProperties do
      begin
        Self.MaskKind := MaskKind;
        Self.EditMask := EditMask;
        Self.CaseInsensitive := CaseInsensitive;
        Self.IgnoreMaskBlank := IgnoreMaskBlank;
        Self.AlwaysShowBlanksAndLiterals := AlwaysShowBlanksAndLiterals;
      end
    finally
      EndUpdate;
    end
  end
  else
    inherited Assign(Source);
end;

procedure TcxCustomMaskEditProperties.Changed;
begin
  FreeAndNil(FTempMode);
  inherited Changed;
end;

class function TcxCustomMaskEditProperties.GetContainerClass: TcxContainerClass;
begin
  Result := TcxMaskEdit;
end;

function TcxCustomMaskEditProperties.UseLookupData: Boolean;
begin
  Result := not IsMasked and inherited UseLookupData;
end;

{function TcxCustomMaskEditProperties.GetEditValueSource(AEditFocused: Boolean): TcxDataEditValueSource;
begin
  if IsMasked then
    Result := evsValue
  else
    Result := inherited GetEditValueSource(AEditFocused);
end;}

function TcxCustomMaskEditProperties.IsEditValueValid(var EditValue: TcxEditValue;
  AEditFocused: Boolean): Boolean;
begin
  Result := IsMasked or inherited IsEditValueValid(EditValue, AEditFocused);
end;

procedure TcxCustomMaskEditProperties.PrepareDisplayValue(
  const AEditValue: TcxEditValue; var DisplayValue: TcxEditValue; AEditFocused: Boolean);
var
  AText: string;
begin
  if IsMasked and not (not AEditFocused and (IDefaultValuesProvider <> nil) and
    IDefaultValuesProvider.IsDisplayFormatDefined(True)) then
  begin
    AText := VarToStr(AEditValue);
    if (FTempMode = nil) or not TestTempMaskKind or not TestTempEditMask then
    begin
      FreeAndNil(FTempMode);
      FTempMode := CreateMode;
    end;
    if FTempMode <> nil then
    begin
      if not AEditFocused and (FTempMode is TcxMaskEditStandardMode) then
      begin
        if not FAlwaysShowBlanksAndLiterals then
          DisplayValue := FTempMode.GetUpdatedText(AText, False)
        else
          DisplayValue := FTempMode.GetFormattedText(AText, False);
      end
      else
        DisplayValue := FTempMode.GetFormattedText(AText, False);
    end;
  end
  else
    inherited PrepareDisplayValue(AEditValue, DisplayValue, AEditFocused);
end;

procedure TcxCustomMaskEditProperties.ValidateDisplayValue(var ADisplayValue: TcxEditValue;
    var AErrorText: TCaption; var Error: Boolean; AEdit: TcxCustomEdit);
var
  AText: string;
begin
  if not Error then
  begin
    if not IsMasked{ or IgnoreMaskBlank }then
      Error := False
    else
    begin
      AText := VarToStr(ADisplayValue);

      Error := not TcxCustomMaskEdit(AEdit).Mode.IsFullValidText(AText);

      if Error then
        AErrorText := cxGetResourceString(@scxMaskEditInvalidEditValue);
    end;
  end;

  inherited ValidateDisplayValue(ADisplayValue, AErrorText, Error, AEdit);
end;

function TcxCustomMaskEditProperties.CreateMode: TcxMaskEditCustomMode;
begin
  Result := nil;
  if not EmptyMask(EditMask) then
  begin
    Result := GetModeClass(FMaskKind).Create(nil, Self);
    Result.Compile(EditMask);
  end;
end;

function TcxCustomMaskEditProperties.CreateMode1: TcxMaskEditCustomMode;
begin
  Result := GetModeClass(MaskKind).Create(nil, Self);
end;

function TcxCustomMaskEditProperties.EmptyMask(AMask: string): Boolean;
var
  I: Integer;
begin
  Result := AMask = '';

  if not Result then
  begin
    for I := 1 to Length(AMask) do
      if not SpaceToken(AMask[I]) then
      begin
        Result := False;
        Exit;
      end;

    Result := True;
  end;
end;

function TcxCustomMaskEditProperties.GetEditMask: TcxEditMask;
begin
  if FMaskKind <> emkStandard then
    Result := FEditMask
  else
  begin
    if EmptyMask(FEditMask) then
    begin
      if IDefaultValuesProvider <> nil then
        Result := IDefaultValuesProvider.DefaultEditMask
      else
        Result := '';
    end
    else
      Result := FEditMask
  end;
end;

function TcxCustomMaskEditProperties.GetIsMasked: Boolean;
begin
  Result := not EmptyMask(EditMask);
end;

procedure TcxCustomMaskEditProperties.SetAlwaysShowBlanksAndLiterals(AValue: Boolean);
begin
  if AValue <> FAlwaysShowBlanksAndLiterals then
  begin
    FAlwaysShowBlanksAndLiterals := AValue;
    Changed;
  end;
end;

procedure TcxCustomMaskEditProperties.SetCaseInsensitive(AValue: Boolean);
begin
  if CharCase = ecNormal then
    FCaseInsensitive := AValue
  else
    FCaseInsensitive := True;
  Changed;
end;

procedure TcxCustomMaskEditProperties.SetEditMask(Value: TcxEditMask);
var
  AMode: TcxMaskEditCustomMode;
begin
  if EditMask = Value then
    FEditMask := Value
  else
  begin
    AMode := CreateMode1;
    try
      AMode.Compile(Value);
      FEditMask := Value;
      Changed;
    finally
      AMode.Free;
    end;
  end;
end;

procedure TcxCustomMaskEditProperties.SetMaskKind(Value: TcxEditMaskKind);
begin
  if Value <> FMaskKind then
  begin
    FMaskKind := Value;
    Changed;
  end;
end;

function TcxCustomMaskEditProperties.GetDisplayFormatOptions: TcxEditDisplayFormatOptions;
begin
 if not IsMasked then
    Result := [dfoSupports]
  else
    Result := [];
end;

function TcxCustomMaskEditProperties.GetModeClass(
  AMaskKind: TcxEditMaskKind): TcxMaskEditCustomModeClass;
begin
  case AMaskKind of
    emkStandard:
      Result := TcxMaskEditStandardMode;
    emkRegExpr:
      Result := TcxMaskEditRegExprMode;
    else
      Result := TcxMaskEditRegExprExMode;
  end;
end;

procedure TcxCustomMaskEditProperties.MaxLengthChanged;
begin
  if IsMasked then
  begin
    if FMaxLengthSetting then
      Exit;
    FMaxLengthSetting := True;
    BeginUpdate;
    try
      MaxLength := 0;
    finally
      FMaxLengthSetting := False;
      EndUpdate;
    end;
  end
  else
    inherited MaxLengthChanged;
end;

function TcxCustomMaskEditProperties.SpaceToken(AToken: Char): Boolean;
begin
  Result := IsSpaceChar(AToken);
end;

function TcxCustomMaskEditProperties.GetEmptyString: string;
begin
  Result := FEmptyString;
end;

procedure TcxCustomMaskEditProperties.SetCharCase(Value: TEditCharCase);
begin
  if Value in [ecLowerCase, ecUpperCase] then
    FCaseInsensitive := True;

  inherited SetCharCase(Value);
end;

function TcxCustomMaskEditProperties.TestTempEditMask: Boolean;
begin
  Result := FTempMode.EditMask = EditMask;
end;

function TcxCustomMaskEditProperties.TestTempMaskKind: Boolean;
begin
  Result := False;
  case FMaskKind of
    emkStandard:
      Result := FTempMode is TcxMaskEditStandardMode;
    emkRegExpr:
      Result := FTempMode is TcxMaskEditRegExprMode;
    emkRegExprEx:
      Result := FTempMode is TcxMaskEditRegExprExMode;
  end;
end;

{ TcxCustomMaskEdit }

{$IFDEF CBUILDER10}
constructor TcxCustomMaskEdit.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
end;
{$ENDIF}

destructor TcxCustomMaskEdit.Destroy;
begin
  FreeAndNil(FMode);
  inherited Destroy;
end;

procedure TcxCustomMaskEdit.CutToClipboard;
begin
  if ActiveProperties.IsMasked then
  begin                                                          
    if not Focused or DoEditing then
    begin
      CopyToClipboard;
      if Mode.PressDelete then
        SendMyKeyPress(Char(VK_BACK));
    end
  end
  else
    inherited CutToClipBoard;
end;

class function TcxCustomMaskEdit.GetPropertiesClass: TcxCustomEditPropertiesClass;
begin
  Result := TcxCustomMaskEditProperties;
end;

procedure TcxCustomMaskEdit.SendMyKeyDown(Key: Word; Shift: TShiftState);
begin
  FMyMessage := True;
  try
    SendKeyDown(Self, Key, Shift);
  finally
    FMyMessage := False;
  end;
end;

procedure TcxCustomMaskEdit.SendMyKeyPress(AKey: Char);
begin
  FMyMessage := True;
  try
    SendKeyPress(Self, AKey);
  finally
    FMyMessage := False;
  end;
end;

procedure TcxCustomMaskEdit.ChangeHandler(Sender: TObject);
begin
  FText := FMode.GetUpdatedText(InnerEdit.EditValue);
  
  inherited ChangeHandler(Sender);
end;

procedure TcxCustomMaskEdit.DblClick;
begin
  if ActiveProperties.IsMasked then
    Mode.GotoEnd;

  inherited DblClick;
end;

procedure TcxCustomMaskEdit.DoEnter;
begin
  if ActiveProperties.IsMasked then
    if ActiveProperties.AutoSelect then
      Mode.GotoEnd;

  inherited DoEnter;
end;

procedure TcxCustomMaskEdit.DoEditKeyDown(var Key: Word; Shift: TShiftState);
var
  AAfterKeyDownNeed: Boolean;
begin
  if not ActiveProperties.IsMasked or IsSpecialKey(Key, Shift) then
  begin
    inherited DoEditKeyDown(Key, Shift);
    Exit;
  end;

  if not ValidateKeyDown(Key, Shift) then
  begin
    DoAfterKeyDown(Key, Shift);
    Key := 0;
    Exit;
  end;

  if Key = VK_TAB then
  begin
    inherited DoEditKeyDown(Key, Shift);
    Exit;
  end;

  FShiftOn := ssShift in Shift;

  if ((Key = VK_UP) or (Key = VK_DOWN)) and not HasPopupWindow then
  begin
    DoAfterKeyDown(Key, Shift);
    Key := 0;
  end
  else if Key = VK_LEFT then
  begin
    if ssCtrl in Shift then
    begin
      SendMyKeyDown(VK_HOME, Shift);
      if not Mode.PressHome then
        Key := 0;
    end
    else
    begin
      AAfterKeyDownNeed := IsCursorBegin;
      if not Mode.PressLeft then
      begin
        if AAfterKeyDownNeed then
          DoAfterKeyDown(Key, Shift);
        Key := 0;
      end;
    end;
  end
  else if Key = VK_RIGHT then
  begin
    if ssCtrl in Shift then
    begin
      SendMyKeyDown(VK_END, Shift);
      if not Mode.PressEnd then
        Key := 0;
    end
    else
    begin
      AAfterKeyDownNeed := IsCursorEnd;
      if not Mode.P

⌨️ 快捷键说明

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