简体   繁体   中英

Delphi XE5 and FormatSettings

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM