IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Delphi Discussion :

DecimalSeparator et Application.UpdateFormatSettings


Sujet :

Delphi

  1. #1
    Membre habitué
    Homme Profil pro
    Owner
    Inscrit en
    Décembre 2004
    Messages
    466
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Owner
    Secteur : Santé

    Informations forums :
    Inscription : Décembre 2004
    Messages : 466
    Points : 137
    Points
    137
    Par défaut DecimalSeparator et Application.UpdateFormatSettings
    Bonjour,
    J'utilise la séquence
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    DecimalSeparator := '.';
    Application.UpdateFormatSettings := false;
    au lancement de mon application de manière à forcer le séparateur décimal en point. (même si la machine utilise la virgule)
    Il semble que cela ne soit pas infaillible.
    Je reçois sur un client le message <'' n'est pas une valeur en virgule flottante correcte>.
    J'ai des difficultés à cerner ce problème intermittent.
    Que ce passe-t'il par exemple si l'application est localisée sur un disque partagé? (voire sur une clé USB)
    Aussi des cas de figure comme par exemple:
    L'application charge des données à partir de tableurs xls.
    Que ce passe t'il si on ouvre excel sur la machine? (sans bien sûr ouvrir les fichiers sources en question)
    Merci pour vos suggestions

  2. #2
    Expert confirmé
    Avatar de anapurna
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2002
    Messages
    3 419
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Mai 2002
    Messages : 3 419
    Points : 5 818
    Points
    5 818
    Par défaut
    salut

    le problème est simple c'est une autre application qui prend le dessus et donc change aussi les paramètre
    le plus simple est de récupérer ces élément et transformer les chiffre selon le format en vigueur et pas l'inverse
    Nous souhaitons la vérité et nous trouvons qu'incertitude. [...]
    Nous sommes incapables de ne pas souhaiter la vérité et le bonheur, et sommes incapables ni de certitude ni de bonheur.
    Blaise Pascal
    PS : n'oubliez pas le tag

  3. #3
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 042
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 67
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 042
    Points : 40 955
    Points
    40 955
    Billets dans le blog
    62
    Par défaut
    Bonjour,

    tout d'abord DecimalSeparator := '.'; c'est pour l'application et seulement pour elle, je ne vois pas l'intérêt de Application.UpdateFormatSettings := false;ensuite

    L'application charge des données à partir de tableurs xls.
    Que ce passe t'il si on ouvre excel sur la machine? (sans bien sûr ouvrir les fichiers sources en question)
    là ça se complique car excel ou openoffice contient son propre formatage du séparateur décimal donc l'API fourni selon ce séparateur

    s'il n'y a pas de séparateur de milliers, une transformation de "," en decimalseparator peut encore fonctionner sinon ... il faut aller à la pêche aux informations de format de la cellule (si je sais le faire avec OpenOffice ce n'est pas le cas avec MSOffice désolé)

    Que ce passe-t'il par exemple si l'application est localisée sur un disque partagé? (voire sur une clé USB)
    là je comprend pas très bien : localisée veut dire traduite dans une autre langue ou simplement située sur ?
    quoique dans les deux cas c'est l'application qui récupère les informations sur le poste où s'exécute le programme
    MVP Embarcadero
    Delphi installés : D3,D7,D2010,XE4,XE7,D10 (Rio, Sidney), D11 (Alexandria), D12 (Athènes)
    SGBD : Firebird 2.5, 3, SQLite
    générateurs États : FastReport, Rave, QuickReport
    OS : Window Vista, Windows 10, Windows 11, Ubuntu, Androïd

  4. #4
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 693
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 693
    Points : 13 128
    Points
    13 128
    Par défaut
    On ne devrait jamais forcer l'utilisation d'une certaine localisation plutôt qu'une autre pour le visuel d'une application mais uniquement pour la sauvegarde/chargement ou l'échange de données.
    Premièrement, ce n'est pas sympa pour l'utilisateur qui a ses habitudes et deuxièmement pour prévenir au maximum les problèmes de conversion que tu rencontres.

    Pour moi, il y a une erreur de conception de ton application.

    Si ton problème est d'assurer l'intégrité d'un fichier (sa lecture sur différentes machines de locale différente), utilise FloatToStr/StrToFloat (ou d'autres fonctions de conversion) en spécifiant un FormatSettings modifié. Le fichier aura ainsi un format fixe connu mais l'application restera localisée.

    Application.UpdateFormatSettings := FALSE assure que l'application ne réagira pas (ne s'adaptera pas) aux changements de paramètres régionaux du système qui surviendraient après son lancement

  5. #5
    Expert confirmé
    Avatar de anapurna
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2002
    Messages
    3 419
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Mai 2002
    Messages : 3 419
    Points : 5 818
    Points
    5 818
    Par défaut
    salut

    voila ce que j'utilise pour récupérer le séparateur d'ecxel
    jusqu’à maintenant je n'ai eu aucun soucis

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    Function GetSeparateur : Char;
    var
     MyReg : TRegistry;
    begin
      MyReg:=TRegistry.Create;
      MyReg.RootKey := HKEY_CURRENT_USER;
      MyReg.OpenKey('Control Panel\International', False);
      Result := strtoChar(MyReg.ReadString('sDecimal'),'.');
      MyReg.CloseKey;
      MyReg.Free;
    end;
    Nous souhaitons la vérité et nous trouvons qu'incertitude. [...]
    Nous sommes incapables de ne pas souhaiter la vérité et le bonheur, et sommes incapables ni de certitude ni de bonheur.
    Blaise Pascal
    PS : n'oubliez pas le tag

  6. #6
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 445
    Points
    28 445
    Par défaut
    personnellement j'ai découvert l'existence de Application.UpdateFormatSettings il y a deux jours

    donc en effet FormatSettings.DecimalSeparator est mis à jour sur le message WM_WININI_CHANGE qui se produit ... je ne sais pas trop quand, mais en tout cas peut se produire.

    dans mon application qui permet simplement d'afficher périodiquement des données JSON d'un site web, je n'avais pas besoin de la virgule, donc au lieu de créer mon propre TFormatSettings j'ai utilisé celui existant...et je me chopais l'erreur de virgule de temps en temps. Depuis que je force Application.UpdateFormatSettings à False je n'ai plus de problème.
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  7. #7
    Membre habitué
    Homme Profil pro
    Owner
    Inscrit en
    Décembre 2004
    Messages
    466
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Owner
    Secteur : Santé

    Informations forums :
    Inscription : Décembre 2004
    Messages : 466
    Points : 137
    Points
    137
    Par défaut
    Ben oui mais si Application.UpdateFormatSettings ça devrait être bon.
    Faut-il que l'appli soit lancée en niveau administrateur?
    Aussi quelle est la différence entre Application.UpdateFormatSettings et Application.UpdateMetricSettings
    Pour Application.UpdateMetricSettings je n'ai pas trouvé grand chose...
    Merci pour vos commentaires...

  8. #8
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 693
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 693
    Points : 13 128
    Points
    13 128
    Par défaut
    Citation Envoyé par PhilLU Voir le message
    Faut-il que l'appli soit lancée en niveau administrateur?
    Quel rapport

    Citation Envoyé par PhilLU Voir le message
    Aussi quelle est la différence entre Application.UpdateFormatSettings et Application.UpdateMetricSettings
    UpdateFormatSettings concerne la mise en forme du contenu : format de la date, séparateur décimal, etc.
    UpdateMetricSettings concerne le rendu des fenêtres : police de la barre de titre, taille des barres de défilement et des bordures, etc.

    Les deux dépendent de la réception du message WM_SETTINGCHANGE généré par SystemParametersInfo. C'est donc l'application qui appelle SystemParametersInfo qui choisit de broadcast-er ou non le changement.

    Un exemple. Admettons que nous voulions élargir les barres de défilement sur une tablette pour une utilisation tactile plus aisée (toutes les fenêtres sont concernées) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    //Récupère les réglages courants...
    SystemParametersInfo(SPI_GETNONCLIENTMETRICS, SizeOf(Metrics), @Metrics, 0);
    //...les modifie...
    Metrics.iScrollWidth := 50;
    //...et les applique en notifiant toutes les fenêtres qui vont automatiquement s'adapter
    SystemParametersInfo(SPI_SETNONCLIENTMETRICS, SizeOf(Metrics), @Metrics, SPIF_SENDCHANGE);
    Un autre exemple : un lecteur d'écran. Au lancement, il va s'annoncer "présent" par SystemParametersInfo(SPI_SETSCREENREADER, 1, nil, SPIF_SENDCHANGE);. Les applications intégrant une gestion de l'accessibilité (souvent assez lourde) ne pourront ainsi la démarrer que sur demande, lorsqu'un lecteur est réellement présent.

    WM_SETTINGCHANGE peut aussi survenir lorsqu'une policy est modifiée, voire simplement lorsqu'une tablette est posée sur/retirée de sa station d'accueil.

  9. #9
    Membre habitué
    Homme Profil pro
    Owner
    Inscrit en
    Décembre 2004
    Messages
    466
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Owner
    Secteur : Santé

    Informations forums :
    Inscription : Décembre 2004
    Messages : 466
    Points : 137
    Points
    137
    Par défaut
    Je me dit que peut-être sans avoir les droits Administrateur, le Application.UpdateFormatSettings := FALSE est remis en question par WM_WININI_CHANGE qui lui est administrateur???

  10. #10
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 693
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 693
    Points : 13 128
    Points
    13 128
    Par défaut
    Citation Envoyé par PhilLU Voir le message
    Je me dit que peut-être sans avoir les droits Administrateur, le Application.UpdateFormatSettings := FALSE est remis en question par WM_WININI_CHANGE qui lui est administrateur???
    Un message n'est pas utilisateur ou administrateur...

    La question ne se pose jamais si un message est envoyé par une application de privilèges supérieurs. A l'inverse, si un programme de privilèges inférieurs en envoie un, les applications "supérieures" ne le recevront que si elles l'ont expressément accepté par ChangeWindowMessageFilter (si UAC activé bien sûr). Cela dit, tous les messages ne sont pas filtrés (ex. WM_CLOSE) et il n'y a aucune chance que WM_SETTINGCHANGE (équivalent à WM_WININICHANGE) le soit.

  11. #11
    Membre habitué
    Homme Profil pro
    Owner
    Inscrit en
    Décembre 2004
    Messages
    466
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Owner
    Secteur : Santé

    Informations forums :
    Inscription : Décembre 2004
    Messages : 466
    Points : 137
    Points
    137
    Par défaut
    Autre chose d'étrange, les utilisateurs remarquent des erreurs de plus en plus fréquentes avec le temps, au point d'avoir des erreurs systématiques en final???
    Un anti-virus peut-il en être la cause?
    Je commence à manquer d'espoir à trouver une solution
    Aussi, je commence à douter de la fiabilité de w7 pour gérer ça
    Peut-être l’explication se trouve dans ceci : http://www.copsmodels.com/gpcommapnt.htm
    Merci pour vos avis, je sêche…

  12. #12
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 445
    Points
    28 445
    Par défaut
    euh...le message d'erreur est bien '' n'est pas une valeur en virgule flottante correcte, car je confirme : '' n'est pas une valeur en virgule flottante correcte, et ce n'est pas un problème de séparateur décimal.
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  13. #13
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 042
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 67
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 042
    Points : 40 955
    Points
    40 955
    Billets dans le blog
    62
    Par défaut
    Bonjour,
    bien vu @Paul

    et s'il s'agit d'une conversion StrToFloat pourquoi ne pas utiliser StrToFloatDef et encore mieux sa version surchargée avec un TFormatSettings ?

    i.e.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
     
    S: String;
    F : Double;
    FS : TFormatSettings;
    ...
     
    S:='';
    try
      F:=StrToFloat(S); 
    except 
      F:=0;
    end;
    // Avantageusement remplacé par
    f:=StrTofloatDef(S,0);
     
    // remplacement de decimal separator de l'application  
    //  DecimalSeparator:='.';
    // Application.UpdateFormatSettings := false;
    // par  
    FS.DecimalSeparator:='.';
    S:='12.24';
    f:=StrToFloatDef(S,0.00,FS); -> résultat 12,24
    S:='';
    f:=StrToFloatDef(S,0.00,FS); -> résultat 0,00
    MVP Embarcadero
    Delphi installés : D3,D7,D2010,XE4,XE7,D10 (Rio, Sidney), D11 (Alexandria), D12 (Athènes)
    SGBD : Firebird 2.5, 3, SQLite
    générateurs États : FastReport, Rave, QuickReport
    OS : Window Vista, Windows 10, Windows 11, Ubuntu, Androïd

  14. #14
    Membre habitué
    Homme Profil pro
    Owner
    Inscrit en
    Décembre 2004
    Messages
    466
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Owner
    Secteur : Santé

    Informations forums :
    Inscription : Décembre 2004
    Messages : 466
    Points : 137
    Points
    137
    Par défaut
    Je suppose que je dois lire:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    FS.DecimalSeparator:='.';
    S:='12.24';
    f:=StrToFloatDef(S,0.00,FS); -> résultat 12.24
    S:='';
    f:=StrToFloatDef(S,0.00,FS); -> résultat 0.00

  15. #15
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 042
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 67
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 042
    Points : 40 955
    Points
    40 955
    Billets dans le blog
    62
    Par défaut
    Citation Envoyé par PhilLU Voir le message
    Je suppose que je dois lire:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    FS.DecimalSeparator:='.';
    S:='12.24';
    f:=StrToFloatDef(S,0.00,FS); -> résultat 12.24
    S:='';
    f:=StrToFloatDef(S,0.00,FS); -> résultat 0.00
    ben oui/non NON car si tu fais un FloatToStr(f) tu obtiens le résultat avec le séparateur décimal défini par le poste (en l'occurrence la virgule), OUI si l'on parle de la valeur de f
    c'est vrai que sur le coup c'est pas forcément explicite
    l'important est surtout l'utilisation du StrToFloatDef et de sa surcharge avec un TFormatsettings
    MVP Embarcadero
    Delphi installés : D3,D7,D2010,XE4,XE7,D10 (Rio, Sidney), D11 (Alexandria), D12 (Athènes)
    SGBD : Firebird 2.5, 3, SQLite
    générateurs États : FastReport, Rave, QuickReport
    OS : Window Vista, Windows 10, Windows 11, Ubuntu, Androïd

Discussions similaires

  1. WPF : Xaml StringFormat Decimal Separator
    Par BenoitM dans le forum Windows Presentation Foundation
    Réponses: 2
    Dernier message: 21/03/2013, 15h35
  2. Accepter tout type de decimal separator
    Par zicos dans le forum C#
    Réponses: 8
    Dernier message: 23/07/2009, 13h38
  3. XML decimal separator
    Par zicos dans le forum C#
    Réponses: 0
    Dernier message: 16/07/2009, 12h01
  4. decimal separator dans un stringgrid
    Par winow dans le forum C++Builder
    Réponses: 1
    Dernier message: 31/01/2008, 21h37
  5. Réponses: 2
    Dernier message: 15/04/2002, 12h56

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo