Is there a way to use the JVCL's TJvXxxAppStorage to store float values as strings (e.g. "10.152") rather than hex dumps and also control the decimal separator that is being used?
Is there a way to use the JVCL's TJvXxxAppStorage to store float values as strings (e.g. "10.152") rather than hex dumps and also control the decimal separator that is being used?
I know that I can set
AppStorage.StorageOptions.FloatAsString := True;
But then it will use the currently active DecimalSeparator when I store a float property, e.g. "10,152" for standard German settings.
It internally calls
procedure TJvCustomAppStorage.WriteFloatInt(const Path: string; Value: Extended);
begin
if StorageOptions.FloatAsString then
DoWriteString(Path, EncryptPropertyValue(FloatToStr(Value)))
else
DoWriteFloat(Path, Value);
end;
Which calls FloatToStr which uses the DecimalSeparator. Providing an OnEncryptPropertyValue handler won't solve that problem either because then the result will be mime encoded.
(I think it cannot be done without changing the WriteFloatInt code. But I would like a confirmation for that.)
I know that I can set
AppStorage.StorageOptions.FloatAsString := True;
But then it will use the currently active DecimalSeparator when I store a float property, e.g. "10,152" for standard German settings.
It internally calls
procedure TJvCustomAppStorage.WriteFloatInt(const Path: string; Value: Extended);
begin
if StorageOptions.FloatAsString then
DoWriteString(Path, EncryptPropertyValue(FloatToStr(Value)))
else
DoWriteFloat(Path, Value);
end;
Which calls FloatToStr which uses the DecimalSeparator. Providing an OnEncryptPropertyValue handler won't solve that problem either because then the result will be mime encoded.
(I think it cannot be done without changing the WriteFloatInt code. But I would like a confirmation for that.)
You can temporarily change global defaults, that FloatToStr uses.
ReplyDeleteYes that would work. But might have undesired side effects, especially in multi threaded programs.
ReplyDeleteI think I'd rather change the JVCL code. But yes, in a single threaded program this would likely work. It just smells.
ReplyDeletefunction TOpenSCADController.FormatDec(Val :Double):string;
ReplyDeletevar fs :TFormatSettings;
begin
fs := TFormatSettings.Create;
fs.DecimalSeparator:= '.';
fs.ThousandSeparator:= ',';
Result := FormatFloat('#0.00', Val, fs);
end;
I use this function to avoid localization.
As "fs" is a local instance of the record, this only affects the code inside the method.
Juan C. Cilleruelo doesn't solve the problem, though. I'd still need to change the JVCL code.
ReplyDeleteSorry!
ReplyDeleteMaybe you can use a helper class to override this method, even if it is private.
stackoverflow.com - How I can patch a private method of a delphi class?
I don't check it. It's only an idea.
/sub
ReplyDeleteSince we are talking about open source library, so the best idea will be to modify it's sources and send your patch to upstream developers.
ReplyDeleteThomas Mueller You may try this:
ReplyDeletetype
TMyStorage = class(TJvAppRegistryStorage)
protected
procedure DoWriteFloat(const Path: string; Value: Extended); override;
end;
TJvAppRegistryStorage = class(TMyStorage);
...
Implementation
{ TMyStorage }
procedure TMyStorage.DoWriteFloat(const Path: String; Value: Extended);
var
SValue : string;
FS : TFormatSettings;
begin
FS := TFormatSettings.Create;
FS.DecimalSeparator := '.';
FS.ThousandSeparator := #0;
SValue := FloatToStr(Value, FS);
DoWriteString(Path, SValue);
end;
And you need to set
StorageOptions.FloatAsString := False;
Микола Петрівський
ReplyDeleteBefore they moved to GitHub, I had write access to the svn repository on sf.net, so I could have simply committed a change. I was not the most active contributor but used to fix bugs once in a while.
Unfortunately nowadays I'd need a GitHub account (I think I actually have got one) and knowledge about git and pull requests. I remember trying that before and the change being rejected. And since I don't regularly use git / GitHub, I keep forgetting how to do that. Given the required effort, I can't be bothered any longer.
Achim Kalwa Yes, that worked. I used a descendant of TJvAppIniFileStorage though.
ReplyDeleteThomas Mueller get me the fix and I will do that for you.
ReplyDelete