⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 snccurrency.pas

📁 一个专门输入现金的控件
💻 PAS
📖 第 1 页 / 共 5 页
字号:
      Canvas.FillRect(Rect(0,0,FWorkCellWidth+FWorkCellOffset,ClientHeight));
      for I:=1 to FDigitalNumber-(Len-FDotLength)-1 do
        Canvas.FillRect(Rect((FWorkCellWidth+FGridLineWidth)*I+FWorkCellOffset,0,(FWorkCellWidth+FGridLineWidth)*I+FWorkCellWidth+FWorkCellOffset,ClientHeight));
    end;
    XOffset := (FWorkCellWidth-Canvas.TextWidth('0')) div 2;
    for I:=1 to Len-FDecimalNumber-FDotLength do
    begin
      TheRect := Rect((FWorkCellWidth+FGridLineWidth)*(FDigitalNumber-(Len-FDotLength)-1+I)+FWorkCellOffset,0,(FWorkCellWidth+FGridLineWidth)*(FDigitalNumber-(Len-FDotLength)-1+I)+FWorkCellWidth+FWorkCellOffset,ClientHeight);
      Canvas.FillRect(TheRect);
      Canvas.TextRect(TheRect,(FWorkCellWidth+FGridLineWidth)*(FDigitalNumber-(Len-FDotLength)-1+I)+XOffset+FWorkCellOffset,YOffset,Text[I]);
    end;
    for I:=1 to FDecimalNumber do
    begin
      TheRect := Rect((FWorkCellWidth+FGridLineWidth)*(FDigitalNumber-FDecimalNumber-1+I)+FWorkCellOffset,0,(FWorkCellWidth+FGridLineWidth)*(FDigitalNumber-FDecimalNumber-1+I)+FWorkCellWidth+FWorkCellOffset,ClientHeight);
      Canvas.FillRect(TheRect);
      Canvas.TextRect(TheRect,(FWorkCellWidth+FGridLineWidth)*(FDigitalNumber-FDecimalNumber-1+I)+XOffset+FWorkCellOffset,YOffset,Text[Len-FDecimalNumber+I]);
    end;
  end;

  Canvas.Brush.Color := OldBrushColor;
  SetCursorState(OldCursorVisible);
end;

{ calculate the cursor pos in first time of get focus}
procedure TsncCustomCurrencyEdit.InitCursorX(X: Integer);
var
  I, Len: Integer;
begin
  FCursorXPos := FDigitalNumber-FDecimalNumber-1;
  Len := Length(FormatFloat(FFormatString, FValue));
  for I:=0 to FDigitalNumber-1 do
    if (X>=(FWorkCellWidth+FGridLineWidth)*I+FWorkCellOffset) and
       (X<=(FWorkCellWidth+FGridLineWidth)*I+FWorkCellWidth-1+FWorkCellOffset) then
      begin
        if (I<FDigitalNumber-(Len-FDotLength)) then
          FCursorXPos := FDigitalNumber-(Len-FDotLength)
        else
          FCursorXPos := I;
        Break;
      end;
end;

{ get the modify state of control}
function TsncCustomCurrencyEdit.Modified: Boolean;
begin
  Result := FModified;
end;

{ fully redraw control }
procedure TsncCustomCurrencyEdit.Paint;
begin
  if (FCellWidth>-1) then
  begin
    ClientWidth := FCellWidth*FDigitalNumber + FGridLineWidth*(FDigitalNumber-1);
    FWorkCellWidth := FCellWidth;
    FWorkCellOffset := 0;
  end
  else begin
    FWorkCellWidth := (ClientWidth-FGridLineWidth*(FDigitalNumber-1)) div FDigitalNumber;
    FWorkCellOffset := ClientWidth-FGridLineWidth*(FDigitalNumber-1) - FWorkCellWidth*FDigitalNumber;
  end;

  DrawGrid;
  DrawText;
  inherited;
end;

{set cursor visible or not}
procedure TsncCustomCurrencyEdit.SetCursorState(Visible: Boolean);
begin
  if (Visible and FCursorVisible) or (not Visible and not FCursorVisible) then
    Exit;
  DrawCursor;
end;

{undo change}
procedure TsncCustomCurrencyEdit.UnDo;
begin
  Value := FOriginValue;
end;

procedure TsncCustomCurrencyEdit.WMChar(var Message: TMessage);
var
  Text: String;
  Len: Integer;
  OldCursorVisible: Boolean;
begin
  with TWMKey(Message) do
    case CharCode of
      Ord('0')..Ord('9'):
        begin
          Text := FormatFloat(FFormatString, FValue);
          Len := Length(Text);
          if not FReadOnly and (Len-FDotLength-FDecimalNumber<FMaxLength) then
          begin
            OldCursorVisible := FCursorVisible;
            SetCursorState(false);
            Text := sncStuff(Text, Chr(CharCode), FCursorXPos-(FDigitalNumber-1-(Len-FDotLength)-1), 0);
            if (FDecimalNumber>0) and (Len+1-Pos('.',Text)>FDecimalNumber) then
              Text := sncStuff(Text, '', Len+1, 1);
            if (FCursorXPos>=FDigitalNumber-FDecimalNumber) and (FCursorXPos<FDigitalNumber-1) then
              FCursorXPos := FCursorXPos+1;
            SetCursorState(OldCursorVisible);
            ChangeValue(StrToFloat(Text)*FNegativeSign);
          end;
        end;
    end;

  inherited;
end;

procedure TsncCustomCurrencyEdit.WMKeyDown(var Message: TMessage);
var
  ShiftState: TShiftState;
  Text: String;
  Len: Integer;
  OldCursorVisible: Boolean;
  IntCharCode: Word;
begin
  with TWMKey(Message) do
  begin
    ShiftState := KeyDataToShiftState(KeyData);
    IntCharCode := CharCode;
    if (ShiftState=[ssShift]) and (CharCode=187) then
      IntCharCode := VK_ADD;
    if (ShiftState=[]) and (CharCode=188) then
      IntCharCode := VK_SEPARATOR;
    if (ShiftState=[]) and (CharCode=189) then
      IntCharCode := VK_SUBTRACT;
    if (ShiftState=[]) and (CharCode=190) then
      IntCharCode := VK_DECIMAL;

    Text := FormatFloat(FFormatString, FValue);
    Len := Length(Text);

    case IntCharCode of
      VK_SUBTRACT:
        if not FReadOnly then
          ChangeValue(-Value);
      VK_ADD:
        if not FReadOnly and (Value<0) then
          ChangeValue(-Value);
      VK_BACK:
        if not FReadOnly then
        begin
          OldCursorVisible := FCursorVisible;
          SetCursorState(false);
          if (FCursorXPos<FDigitalNumber-FDecimalNumber) then
            if (FCursorXPos>FDigitalNumber-(Len-FDotLength)) then
              Text := sncStuff(Text, '', FCursorXPos-(FDigitalNumber-(Len-FDotLength)), 1)
            else begin
              if (FCursorXPos=FDigitalNumber-(Len-FDotLength)) then
                Text := sncStuff(Text, '', FCursorXPos-(FDigitalNumber-(Len-FDotLength)-1), 1);
              if (FCursorXPos<FDigitalNumber-FDecimalNumber-1) then
                FCursorXPos := FCursorXPos+1;
            end
          else begin
            if (FCursorXPos>FDigitalNumber-FDecimalNumber) then
              Text := sncStuff(Text, '', FCursorXPos-(FDigitalNumber-Length(Text)-FDotLength)-1, 1)
            else
              Text := sncStuff(Text, '', FCursorXPos-(FDigitalNumber-Length(Text)-FDotLength), 1);
            if (FCursorXPos>FDigitalNumber-FDecimalNumber) then
              FCursorXPos := FCursorXPos-1;
          end;
          if (Text='') then
            Text := '0';
          SetCursorState(OldCursorVisible);
          ChangeValue(StrToFloat(Text)*FNegativeSign);
        end;
      VK_DELETE:
        if not FReadOnly then
          if (ShiftState=[]) then
          begin
            OldCursorVisible := FCursorVisible;
            SetCursorState(false);
            if (FCursorXPos<FDigitalNumber-FDecimalNumber) then
            begin
              if (FCursorXPos>=FDigitalNumber-(Len-FDotLength)) then
                Text := sncStuff(Text, '', FCursorXPos-(FDigitalNumber-(Len-FDotLength)-1), 1);
              if (FCursorXPos<FDigitalNumber-FDecimalNumber-1) then
                FCursorXPos := FCursorXPos+1;
            end
            else
              Text := sncStuff(Text, '', FCursorXPos-(FDigitalNumber-Length(Text)-FDotLength), 1);
            if (Text='') then
              Text := '0';
            SetCursorState(OldCursorVisible);
            ChangeValue(StrToFloat(Text)*FNegativeSign);
          end
          else
            if (ShiftState=[ssCtrl]) then
            begin
              OldCursorVisible := FCursorVisible;
              SetCursorState(false);
              FCursorXPos := FDigitalNumber-FDecimalNumber-1;
              Text := '0';
              SetCursorState(OldCursorVisible);
              ChangeValue(StrToFloat(Text)*FNegativeSign);
            end;
      VK_DECIMAL:
        if (FDecimalNumber<>0) then
        begin
          SetCursorState(false);
          if (FCursorXPos>=FDigitalNumber-FDecimalNumber) then
            FCursorXPos := FDigitalNumber-FDecimalNumber-1
          else
            FCursorXPos := FDigitalNumber-FDecimalNumber;
          SetCursorState(true);
        end;
    end;
  end;

  inherited;
end;

procedure TsncCustomCurrencyEdit.CNKEYDOWN(var Message: TMessage);
var
  ShiftState: TShiftState;
  Offset, Len: Integer;
  CanMoveOut: Boolean;
begin
  CanMoveOut := false;
  with TWMKey(Message) do
  begin
    ShiftState := KeyDataToShiftState(KeyData);
    Len := Length(FormatFloat(FFormatString, FValue));
    case CharCode of
      VK_LEFT:
        if (ShiftState=[ssCtrl]) then
        begin
          if (FCursorXPos>FDigitalNumber-(Len-FDotLength)-1) then
          begin
            SetCursorState(false);
            if (FCursorXPos<FDigitalNumber-FDecimalNumber) then
            begin
              Offset := FCursorXPos-3+(FDigitalNumber-FDecimalNumber-FCursorXPos-1) mod 3;
              if (Offset>=FDigitalNumber-(Len-FDotLength)-1) then
                FCursorXPos := Offset
              else
                FCursorXPos := FDigitalNumber-(Len-FDotLength)-1;
            end
            else
              if (FCursorXPos=FDigitalNumber-FDecimalNumber) then
                FCursorXPos := FCursorXPos-1
              else begin
                Offset := FCursorXPos-1-(FCursorXPos-1-(FDigitalNumber-FDecimalNumber)) mod 3;
//                if (Offset>=FDigitalNumber-FDecimalNumber) then
                FCursorXPos := Offset;
              end;
            SetCursorState(true);
          end
          else
            CanMoveOut := FMoveOutAllowed;
        end
        else
          if (FCursorXPos>FDigitalNumber-(Len-FDotLength)-1) then begin
            SetCursorState(false);
            FCursorXPos := FCursorXPos-1;
            SetCursorState(true);
          end
          else
            CanMoveOut := FMoveOutAllowed;
      VK_RIGHT:
        if (ShiftState=[ssCtrl]) then
        begin
          if (FCursorXPos<FDigitalNumber-1) then
          begin
            SetCursorState(false);
            if (FCursorXPos<FDigitalNumber-FDecimalNumber-1) then
            begin
              Offset := FCursorXPos+1+(FDigitalNumber-FDecimalNumber-FCursorXPos+1) mod 3;
//              if (Offset<FDigitalNumber-FDecimalNumber) then
               FCursorXPos := Offset;
            end
            else
              if (FCursorXPos=FDigitalNumber-FDecimalNumber-1) then
                FCursorXPos := FCursorXPos+1
              else begin
                Offset := FCursorXPos+3-(FCursorXPos-(FDigitalNumber-FDecimalNumber)) mod 3;
                if (Offset<=FDigitalNumber-1) then
                  FCursorXPos := Offset
                else
                  FCursorXPos := FDigitalNumber-1;
              end;
            SetCursorState(true);
          end
          else
            CanMoveOut := FMoveOutAllowed;
        end
        else
          if (FCursorXPos<FDigitalNumber-1) then
          begin
            SetCursorState(false);
            FCursorXPos := FCursorXPos+1;
            SetCursorState(true);
          end
          else
            CanMoveOut := FMoveOutAllowed;
      VK_UP,
      VK_DOWN:
        CanMoveOut := FMoveOutAllowed;
      VK_HOME:
        begin
          SetCursorState(false);
          FCursorXPos := FDigitalNumber-(Len-FDotLength)-1;
          SetCursorState(true);
        end;
      VK_END:
        begin
          SetCursorState(false);
          FCursorXPos := FDigitalNumber-1;
          SetCursorState(true);
        end;
      else
        begin
          inherited;
          Exit;
        end;
    end;
  end;
  if CanMoveOut then
  begin
    inherited;
    MoveOut(TWMKey(Message).CharCode, ShiftState);
  end;
end;

procedure TsncCustomCurrencyEdit.MoveOut(var Key: Word; Shift: TShiftState);
begin
  if Assigned(FOnMoveOut) then
    FOnMoveOut(Self, Key, Shift);
end;

procedure TsncCustomCurrencyEdit.WMKillFocus(var Message: TMessage);
begin
  inherited;

  FCursorTimer.Enabled := False;
  FCursorTimer.Free;
  FCursorTimer := nil;
  SetCursorState(False);

  Repaint;
end;

procedure TsncCustomCurrencyEdit.WMLButtonDown(var Message: TMessage);
begin
  inherited;

  if not Focused then
  begin
    SetFocus;
    SetCursorState(False);
    InitCursorX(TWMMouse(Message).Pos.X);
    SetCursorState(True);
  end
  else begin
    SetCursorState(False);
    DecodeCursorX(TWMMouse(Message).Pos.X);
    SetCursorState(True);
  end;
end;

procedure TsncCustomCurrencyEdit.WMSetFocus(var Message: TMessage);
begin
  inherited;

  Repaint;

  FCursorTimer := TTimer.Create(nil);
  FCursorTimer.Enabled := False;
  FCursorTimer.interval := 500;
  FCursorTimer.OnTimer := CursorTimerHandle;
  FCursorTimer.Enabled := True;
  FCursorVisible := False;
  SetCursorState(True);
end;

end.

⌨️ 快捷键说明

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