I am changing FormatSettings inside my application. Let's say computer's local currency is set to $ and I would like to use € in my app. I can change it using the following code.
FormatSettings.CurrencyString := '€';
However, if i go to regional settings and change it there, my FormatSettings revert back. I believe there should be a way to keep it safe. Do you know any solution to this?
You can deal with this by avoiding the global shared format settings variable, FormatSettings
, that has been deprecated for years now.
Instead create and populate a local variable of type TFormatSettings
. Pass that to all functions that rely on format settings. It's only the global format settings variable that is updated when the user makes changes.
var
fs: TFormatSettings;
....
fs := TFormatSettings.Create;
fs.CurrencyString := '€';
You might prefer to make this a global variable which you set up at startup and then never modify, if it really never should change.
Ok here is what i did to solve my own problem. What i wanted to do is simply to change FormatSettings.CurrencyString
and FormatSettings.CurrencyFormat
application wide and save them safe. I can do this easily but when i go to Regional settings and edit Currency, my app reverts it back. I have found 2 solutions:
1.Set Application.UpdateFormatSettings := False;
However, you won't get any other changes either. I mean nothing will be updated.
2.This one solved my problem. Just listen WM_WININICHANGE
and use PostMessage
to queue your own update. You can find the full code below:
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs;
const
CM_CHANGEFORMAT = WM_USER + 101;
type
TForm1 = class(TForm)
private
{ Private declarations }
procedure ChangeFormatSettings(var Msg: TMessage); message CM_CHANGEFORMAT;
procedure WinIniChange(var Msg: TMessage); message WM_WININICHANGE;
public
{ Public declarations }
end;
var
Form1: TForm1;
MyCurrencyString: string = '€';
MyCurrencyFormat: byte = 3;
implementation
{$R *.dfm}
procedure TForm1.ChangeFormatSettings(var Msg: TMessage);
begin
FormatSettings.CurrencyString := MyCurrencyString;
FormatSettings.CurrencyFormat := MyCurrencyFormat;
end;
procedure TForm1.WinIniChange(var Msg: TMessage);
begin
{
You will receive WM_WININICHANGE when you change regional settings.
Just use PostMessage to update your own settings because your
formatsettings will change after this message.
}
PostMessage(Self.Handle, CM_CHANGEFORMAT, 0, 0);
end;
end.
Thanks to everyone who tried to help me. I appreciate it.
FormatSettings
is a global variable. To have a specific interpretation of CurrencyString
, use your own FormatSettings variable and the overloads that takes this variable during conversion.
See here for an example, TFormatSettings .
To convert a currency to a string, utilizing your special FormatSetting variable and the overloaded CurrToStr
function:
currStr := CurrToStr(Value,MyFormatSettings); // <-- Note the overload
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.