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

📄 jclwideformat.pas

📁 East make Tray Icon in delphi
💻 PAS
📖 第 1 页 / 共 3 页
字号:
    if (Low(CharClassTable) <= C) and (C <= High(CharClassTable)) then
      State := StateTable[State, CharClassTable[C]]
    else
      State := StateTable[State, ccOther];
    case State of
      stError:
        raise FormatSyntaxError(Src); // syntax error at index [Src]
      stBeginAcc:
        begin
          // Begin accumulating characters to copy to Result
          P := @Format[Src];
          CharCount := 1;
        end;
      stAcc:
        Inc(CharCount);
      stPercent:
        begin
          if CharCount > 0 then
          begin
            // Copy accumulated characters into result
            EnsureResultLen(Dest + CharCount - 1, ResultLen);
            MoveWideChar(P^, Result[Dest], CharCount);
            Inc(Dest, CharCount);
            CharCount := 0;
          end;
          // Prepare a new format string
          Width := 0;
          Prec := NoPrecision;
          FormatStart := Src;
          LeftAlign := False;
        end;
      stDigit:
        begin
          // We read into Width, but we might actually be reading the ArgIndex
          // value. If that turns out to be the case, it gets addressed in the
          // stColon state below and Width is reset to its default value, 0.
          Width := Width * 10 + Cardinal(Ord(C) - Ord('0'));
        end;
      stPrecDigit:
        begin
          if Prec = NoPrecision then
            Prec := 0;
          Prec := Prec * 10 + Cardinal(Ord(C) - Ord('0'));
        end;
      stStar, stPrecStar:
        begin
          if ArgIndex > Cardinal(High(Args)) then
            raise FormatNoArgumentError(ArgIndex);
          Arg := @Args[ArgIndex];
          if State = stStar then
            PrecWidth := @Width
          else
            PrecWidth := @Prec;
          // PrecWidth^ := Args[ArgIndex++]
          case Arg^.VType of
            vtInteger:
              PrecWidth^ := Arg^.VInteger;
            {$IFDEF FORMAT_EXTENSIONS}
            vtVariant:
              PrecWidth^ := Arg^.VVariant^;
            vtInt64:
              PrecWidth^ := Arg^.VInt64^;
            {$ENDIF FORMAT_EXTENSIONS}
          else
            raise FormatBadArgumentTypeError(Arg.VType, ArgIndex, AllowedStarTypes);
          end;
          Inc(ArgIndex);
        end;
      stColon:
        begin
          ArgIndex := Width;
          Width := 0;
        end;
      stDash:
        LeftAlign := True;
      stDot: ;
      stFloat, stInt, stPointer, stString:
        begin
          if ArgIndex > Cardinal(High(Args)) then
            raise FormatNoArgumentErrorEx(Format, FormatStart, Src, ArgIndex);
          Arg := @Args[ArgIndex];
          case State of
            stFloat:
              begin
                // The floating-point formats are all similar. The conversion
                // eventually happens in FloatToText.
                case Arg.VType of
                  vtExtended:
                    begin
                      ValueType := fvExtended;
                      FloatVal := Arg.VExtended;
                    end;
                  vtCurrency:
                    begin
                      ValueType := fvCurrency;
                      FloatVal := Arg.VCurrency;
                    end;
                  {$IFDEF FORMAT_EXTENSIONS}
                  vtVariant:
                    begin
                      // We can't give FloatToText a pointer to a Variant, so we
                      // extract the Variant's value and point to a temporary value
                      // instead.
                      if VarType(Arg.VVariant^) and varCurrency <> 0 then
                      begin
                        TempCurr := Arg.VVariant^;
                        FloatVal := @TempCurr;
                        ValueType := fvCurrency;
                      end
                      else
                      begin
                        TempExt := Arg.VVariant^;
                        FloatVal := @TempExt;
                        ValueType := fvExtended;
                      end;
                    end;
                  {$ENDIF FORMAT_EXTENSIONS}
                else
                  raise FormatBadArgumentTypeErrorEx(Format, FormatStart, Src, Arg.VType, ArgIndex, AllowedFloatTypes);
                end; // case Arg.VType
                case C of
                  'e', 'E':
                    FloatFormat := ffExponent;
                  'f', 'F':
                    FloatFormat := ffFixed;
                  'g', 'G':
                    FloatFormat := ffGeneral;
                  'm', 'M':
                    FloatFormat := ffCurrency;
                else {'n', 'N':}
                  FloatFormat := ffNumber;
                end;
                P := @Buffer;
                // Prec is interpeted differently depending on the format.
                if FloatFormat in [ffGeneral, ffExponent] then
                begin
                  if (Prec = NoPrecision) or (Prec > MaxFloatPrecision) then
                    Prec := DefaultGeneralPrecision;
                  AnsiCount := FloatToText(P, FloatVal^, ValueType, FloatFormat, Prec, GeneralDigits);
                end
                else {[ffFixed, ffNumber, ffCurrency]}
                begin
                  if (Prec = NoPrecision) or (Prec > MaxFloatPrecision) then
                  begin
                    if FloatFormat = ffCurrency then
                      Prec := SysUtils.CurrencyDecimals
                    else
                      Prec := DefaultFixedDigits;
                  end;
                  AnsiCount := FloatToText(P, FloatVal^, ValueType, FloatFormat, FixedPrecision, Prec);
                end;
                CharCount := AnsiCount;
                Wide := False;
              end;
            stInt:
              begin
                if (C = 'x') or (C = 'X') then
                  Base := 16
                else
                  Base := 10;
                case Arg^.VType of
                  vtInteger {$IFDEF FORMAT_EXTENSIONS}, vtVariant {$ENDIF}:
                    begin
                      {$IFDEF FORMAT_EXTENSIONS}
                      if Arg^.VType <> vtInteger then
                        Temp32 := Arg^.VVariant^
                      else
                      {$ENDIF FORMAT_EXTENSIONS}
                        Temp32 := Cardinal(Arg^.VInteger);
                      // The value may be signed and negative, but the converter only
                      // interprets unsigned values.
                      Neg := ((C = 'd') or (C = 'D')) and (Integer(Temp32) < 0);
                      if Neg then
                        SafeNegate32(Integer(Temp32));
                      P := @Buffer[High(Buffer)];
                      CharCount := ConvertInt32(Temp32, Base, PWideChar(P));
                    end;
                  vtInt64:
                    begin
                      Temp64 := Arg^.VInt64^;
                      // The value may be signed and negative, but the converter only
                      // interprets unsigned values.
                      Neg := ((C = 'd') or (C = 'D')) and (Temp64 < 0);
                      if Neg then
                        SafeNegate64(Temp64);
                      P := @Buffer[High(Buffer)];
                      CharCount := ConvertInt64(Temp64, Base, PWideChar(P));
                    end;
                else
                  raise FormatBadArgumentTypeErrorEx(Format, FormatStart, Src, Arg.VType, ArgIndex, AllowedIntegerTypes);
                end;
                // If Prec was specified, then we need to see whether any
                // zero-padding is necessary
                if Prec > MaxIntPrecision then
                  Prec := NoPrecision;
                if Prec <> NoPrecision then
                  while Prec > CharCount do
                  begin
                    Dec(PWideChar(P));
                    PWideChar(P)^ := '0';
                    Inc(CharCount);
                  end;
                if Neg then
                begin
                  Dec(PWideChar(P));
                  PWideChar(P)^ := '-';
                  Inc(CharCount);
                end;
                Assert(PWideChar(P) >= @Buffer);
                Wide := True;
              end;
            stPointer:
              begin
                // The workings are similar to the integer-converting code above,
                // but the pointer specifier accepts a few more types that make it
                // worth writing separate code.
                if Arg.VType in AllowedPointerTypes then
                begin
                  P := @Buffer[High(Buffer)];
                  CharCount := ConvertInt32(Cardinal(Arg.VInteger), 16, PWideChar(P));
                end
                else
                  raise FormatBadArgumentTypeErrorEx(Format, FormatStart, Src, Arg.VType, ArgIndex, AllowedPointerTypes);
                // Prec is ignored. Alternatively, it is assumed to be 8
                while (2 * SizeOf(Pointer)) > CharCount do
                begin
                  Dec(PWideChar(P));
                  PWideChar(P)^ := '0';
                  Inc(CharCount);
                end;
                Assert(PWideChar(P) >= @Buffer);
                Wide := True;
              end; // stPointer case
          else {stString:}
            begin
              Wide := Arg^.VType in [vtWideChar, vtPWideChar, vtBoolean, vtVariant, vtWideString];
              case Arg^.VType of
                vtChar, vtWideChar:
                  begin
                    Assert(@Arg^.VChar = @Arg^.VWideChar);
                    P := @Arg^.VChar;
                    CharCount := 1;
                  end;
                vtString:
                  begin
                    CharCount := Length(Arg^.VString^);
                    P := @Arg^.VString^[1];
                  end;
                vtPChar, vtPWideChar:
                  begin
                    P := Arg^.VPChar;
                    if Wide then
                      CharCount := StrLenW(P)
                    else
                      CharCount := StrLen(P);
                  end;
                vtVariant{$IFDEF FORMAT_EXTENSIONS}, vtBoolean{$ENDIF}:
                  begin
                    {$IFDEF FORMAT_EXTENSIONS}
                    if Arg^.VType = vtBoolean then
                      TempWS := BooleanToStr(Arg^.VBoolean)
                    else
                    {$ENDIF FORMAT_EXTENSIONS}
                      TempWS := Arg^.VVariant^;
                    CharCount := Length(TempWS);
                    P := Pointer(TempWS);
                  end;
                {$IFDEF FORMAT_EXTENSIONS}
                vtClass:
                  begin
                    P := GetPClassName(Arg^.VClass);

⌨️ 快捷键说明

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