-
This one seems to pass compatibility, but you have to be careful.
function Format(Format: KolString; const Args: array of const): KolString;
type
TVAList = array[0..$FFFF] of Pointer;
var
VA:TVAList;
I: integer;
begin
Result :='';
If length(Args) > 0 then
begin
SetLength(Result,1024);
for I := Low(Args) to High(Args) do
with Args[I] do
case VType of
vtInteger: VA[I] := Pointer(VInteger);
vtPChar,
vtAnsiString:VA[i]:=PKolChar(VPCHAR);
vtPWideChar,
vtWideString:VA[i]:=PKolChar(VPWIDECHAR);
else
VA[i] := nil;
end;
end;
SetLength(Result, wvsprintf(PKolChar(Result), PKolChar(Format), @VA));
end;
If your code compiles and works in Delphi, this will also compile and work in Freepascal 32/64. Nothing more is promised!
-
not so good decision coz result text can be longer than 1024 symbols
-
No! See MSDN. The limit is 1024 symbols. Even on 64 bit platforms.
-
pity. then better to use custom implementation without limits :(
-
Do you need it? Then change it! Pointer array is big enough.... ;)
-
But wsprintf will fail....
-
i made surrogate functions for me which works with text (%s only) and text with integers (%s, %d and %u substitutes) and replace it "by hands". And trying to use these functions where possible. (first part calculates length of final text, second makes replaces)
-
You can also use this trick from Andreas Hausladen:
function _FormatC(const Format: string): string; cdecl; const StackSlotSize = SizeOf(Pointer); var Args: va_list; Buffer: array[0..1024] of Char; begin // va_start(Args, Format) Args := va_list(PAnsiChar(@Format) + ((SizeOf(Format) + StackSlotSize - 1) and not (StackSlotSize - 1))); SetString(Result, Buffer, wvsprintf(Buffer, PChar(Format), Args)); end;
const // allows us to use "varargs" in Delphi FormatC: function(const Format: string): string; cdecl varargs = _FormatC;
procedure TForm1.Button1Click(Sender: TObject); begin MsgOk(FormatC('%s %03d', 'Hallo', 3)); end;
-
procedure TForm1.Button1Click(Sender: PObj); // <smile> begin MsgOk(FormatC('%s %03d', 'Hallo', 3)); end;
-
I used Format ONLY because it is already present in Windows API (wsprintf), so calling it is cheaper then creating several formatting functions. It is useful to make some number-to-string conversions like %.03d (gives 002, not 2). In any other case it is cheaper to create several small functions like function Int2Z(i, digits): String;
begin
Result := Int2Str(Abs(i));
while Length(Result) < digits do
Result := '0' + Result;
if i < 0 then Result := '-' + Result;
end;
|