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

Lazarus Pascal Discussion :

Encodage de caractères pour OO Automation [Lazarus]


Sujet :

Lazarus Pascal

  1. #1
    Membre habitué
    Profil pro
    Inscrit en
    Juin 2005
    Messages
    138
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2005
    Messages : 138
    Points : 172
    Points
    172
    Par défaut Encodage de caractères pour OO Automation
    Bonjour.

    J'ai toujours trouvé très compliqués et pénibles à gérer les problèmes d'encodage de caractères (gestion des caractères accentués, ...).
    Aujourd'hui, j'y suis à nouveau confronté dans le cadre d'un essai d' "automation" de OpenOffice writer. Quand je cherche par exemple à insérer 'Première ligne de texte', le è n'est pas bien affiché, cela donne "è" à la place.

    Cela fait un moment que je tourne en rond en lisant tout ce que je trouve sur le sujet (UTF8, Ansi, widestring, ....) mais rien n'y fait.
    Si quelqu'un a la solution ...

    Christian

  2. #2
    Expert éminent
    Avatar de jurassic pork
    Homme Profil pro
    Bidouilleur
    Inscrit en
    Décembre 2008
    Messages
    3 954
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Bidouilleur
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2008
    Messages : 3 954
    Points : 9 284
    Points
    9 284
    Par défaut
    hello,
    essaie un truc du genre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
      // S : String;  xText := Document.GetText;
     
     
      xTextCursor := xText.CreateTextCursor;
      S :=  'Première ligne de texte';
      xText.InsertString(xTextCursor, WideString(UTf8toAnsi(S)) , False);
    Ami calmant, J.P
    Jurassic computer : Sinclair ZX81 - Zilog Z80A à 3,25 MHz - RAM 1 Ko - ROM 8 Ko

  3. #3
    Membre habitué
    Profil pro
    Inscrit en
    Juin 2005
    Messages
    138
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2005
    Messages : 138
    Points : 172
    Points
    172
    Par défaut
    Bonjour.

    J'avais essayé les 2 (UTf8toAnsi et widestring) mais je n'avais pas pensé à les "enchaîner". Et ça marche !
    Merci.

    Mais j'aimerais bien comprendre ... Sais-tu s'il y a quelque part un dossier clair expliquant tous les problèmes liés à l'encodage ?

    Christian

  4. #4
    Membre confirmé

    Homme Profil pro
    Autre
    Inscrit en
    Novembre 2015
    Messages
    145
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Autre

    Informations forums :
    Inscription : Novembre 2015
    Messages : 145
    Points : 625
    Points
    625
    Par défaut
    Bonjour,

    "... tous les problèmes liés à l'encodage ...", j'en doute, compte tenu de l'ampleur du sujet.

    Par contre, il existe toute une série de règles et de conventions, qui fait que l'on peut en général facilement déterminer ce qu'il est nécessaire de faire; si tant est qu'il faille faire quelque chose.

    Dans votre cas:
    - toutes les API COM/OLE de Windows utilisent des strings de type Unicode uniquement (i.e. UTF16, enfin presque) ,
    - la LCL de Lazarus utilise des strings de type UTF8 par défaut.

    Il faut donc convertir les types de string pour passer de l'un à l'autre.

    Ceci étant, cela doit normalement se faire de façon assez simple, surtout depuis l'ajout du support amélioré de l'Unicode dans Free Pascal (i.e. compilateur FPC 3.x). Donc, théoriquement dans votre cas:
    - LCL ---> OLE: WideString(MyLCLString)
    - OLE ---> LCL: String(MyOLEString) (ou éventuellement UTF8String(MyOLEString)).

    En fait, même sans cela le compilateur effectue bien souvent (mais pas toujours) la conversation lui-même automatiquement si vous l'oubliez, avec alors un warning lors de la compilation.


    Donc "normalement", pour reprendre l'exemple de jurassic pork, ceci "aurait" du fonctionner (le transcodage à partir du code page UTF8 se fait en effet automatiquement sans aucun problème):
    Code PASCAL : Sélectionner tout - Visualiser dans une fenêtre à part
    xText.InsertString(xTextCursor, WideString(S) , False);


    Je suis donc très surpris que cela n'ait pas fonctionné. Question (qui concerne d'ailleurs tout autant jurassic pork): pourquoi ?


    Je précise cependant que cela concerne uniquement le cas: LCL et OLE. J'ai en effet supposé que vous utilisiez la LCL, puisque vous avez posté dans le forum Lazarus (et pas le forum Free Pascal).

    Si votre programme est de type "FPC sans LCL" et que utilisez l'EDI Lazarus par exemple, alors dans ce cas les choses "se compliquent" et la nécessité du transcodage manuel est effective (ou bien alors il faut changer le type d'encodage du code source).

  5. #5
    Membre éprouvé
    Homme Profil pro
    Chef de projets retraité
    Inscrit en
    Juillet 2011
    Messages
    420
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Cher (Centre)

    Informations professionnelles :
    Activité : Chef de projets retraité
    Secteur : Transports

    Informations forums :
    Inscription : Juillet 2011
    Messages : 420
    Points : 1 102
    Points
    1 102
    Par défaut
    Bonjour,

    Donc "normalement", pour reprendre l'exemple de jurassic pork, ceci "aurait" du fonctionner (le transcodage à partir du code page UTF8 se fait en effet automatiquement sans aucun problème):
    Tout dépend de la version de Lazarus/freepascal (non indiquée dans par le PO) depuis la lazarus 1.6 (en fait FPC 3.0) (je crois) ansitoutf8 n'a aucun effet mais avant comme lazarus était UTF8 et Freepascal en ANSI, il fallait cette fonction pour passer de UTF8 vers ANSI.

    Cordialement

  6. #6
    Membre habitué
    Profil pro
    Inscrit en
    Juin 2005
    Messages
    138
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2005
    Messages : 138
    Points : 172
    Points
    172
    Par défaut Précisions
    Bonjour.

    J'utilise Lazarus 1.8.0 avec FPC 3.0.4
    et je crée une application graphique (Nouveau/Projet/Application)

    Avec :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    myText.InsertString(myCursor, 'Première ligne de texte', false);
    le è n'est pas bien affiché, cela donne "è" à la place.

    Avec :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    myText.InsertString(myCursor, widestring('Première ligne de texte'), false);
    idem

    Avec :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    myText.InsertString(myCursor, UTf8toAnsi('Première ligne de texte'), false);
    la ligne ne s'affiche pas dans writer (aucun caractère)

    Avec la solution de jurassic pork :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    myText.InsertString(myCursor, widestring(UTf8toAnsi('Première ligne de texte')), false);
    cela fonctionne ! La ligne s'affiche correctement.

    Je ne sais pas si je dois mettre le sujet en "Résolu" puisque j'ai la réponse à mon problème ... mais je n'ai pas vraiment compris pourquoi il faut faire cela !

    Merci à tous.

  7. #7
    Membre confirmé

    Homme Profil pro
    Autre
    Inscrit en
    Novembre 2015
    Messages
    145
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Autre

    Informations forums :
    Inscription : Novembre 2015
    Messages : 145
    Points : 625
    Points
    625
    Par défaut
    @acaumes
    J'avais en effet pré-supposé que thewolf utilisait une version récente de FPC/Lazarus (ce qui a bien été confirmé, mais uniquement dans son post suivant).


    @ thewolf
    Ah, oui, je vois.

    Mais il faut alors remarquer que vous n'utilisez pas tout à fait le même type d'exemple que jurassic pork:
    Code PASCAL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    xText.InsertString(xTextCursor, WideString(UTf8toAnsi(S)) , False);
     
        vs
     
    Text.InsertString(myCursor, widestring('Première ligne de texte'), false);

    En effet, si vous utilisez du texte constant dans votre code à ce niveau, le texte est en UTF8 mais le compilateur ne le sait pas; et le transcodage n'a alors pas lieu.

    Pour corriger cela:
    - soit vous indiquez au compilateur que votre code source est en UTF8 par défaut: directive {$codepage utf8} à ajouter dans l'unité concernée,
    - soit (solution que je trouve beaucoup plus simple et pragmatique) vous passez par une variable de type chaîne de caractères (cf. exemple de jurassic pork):
    Code PASCAL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    var S: string;
    ...
    S := 'Première ligne de texte';
    myText.InsertString(myCursor, WideString(S), false);

    Et cela devrait alors fonctionner. Enfin, en théorie ...

  8. #8
    Membre habitué
    Profil pro
    Inscrit en
    Juin 2005
    Messages
    138
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2005
    Messages : 138
    Points : 172
    Points
    172
    Par défaut
    Effectivement, en passant par une variable de type chaîne de caractères (S),

    il suffit de mettre widestring(S)

  9. #9
    Expert éminent
    Avatar de jurassic pork
    Homme Profil pro
    Bidouilleur
    Inscrit en
    Décembre 2008
    Messages
    3 954
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Bidouilleur
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2008
    Messages : 3 954
    Points : 9 284
    Points
    9 284
    Par défaut
    hello,
    bon j'y vois plus clair maintenant :
    cette ligne de code fonctionne ( affichage correct des accents ) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     xText.InsertString(xTextCursor, WideString('Première ligne de texte - '), False);
    1 - si le fichier source est en Ansi.
    2 - si le fichier source est en Utf8 (défaut pour Lazarus) et que la directive {$codepage utf8} est incluse dedans.

    Ami calmant, J.P
    Jurassic computer : Sinclair ZX81 - Zilog Z80A à 3,25 MHz - RAM 1 Ko - ROM 8 Ko

  10. #10
    Membre confirmé

    Homme Profil pro
    Autre
    Inscrit en
    Novembre 2015
    Messages
    145
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Autre

    Informations forums :
    Inscription : Novembre 2015
    Messages : 145
    Points : 625
    Points
    625
    Par défaut
    Oui, le fait qu'il y ait un "décalage" au niveau des codes page entre le code source (UTF8 par défaut dans Lazarus) et le compilateur (code page Windows de l'ordinateur ayant fait la compilation par défaut) peut parfois provoquer des problèmes.

    Tout va bien tant que la "cuisine" reste interne à la LCL (ce qui est la grande majorité des cas): mais si cela concerne DIRECTEMENT autre chose (i.e. appels aux API Windows, OLE, etc.), ces problèmes apparaissent.


    Par pure curiosité, je me demande cependant ce qui se passe si l'on cross-compile depuis Linux vers du code Windows: car théoriquement le code page par défaut des ordinateurs sous Linux est l'UTF8, non ? Si c'est le cas, cela devrait alors fonctionner sans conversion supplémentaire (mais cela reste de toute façon un cas d'école).


    Juste une remarque concernant la première option: i.e. sauvegarde du code source en Ansi. Je la déconseille personnellement: tout au moins pour les programmes utilisant la LCL, et pour les personnes n'ayant pas une vision très précise des aboutissants de cette solution.

    Car là c'est la LCL qui ne retrouve plus ses petits par défaut. Et des choses aussi simples que ce qui suit ne fonctionne alors par exemple plus pour l'unité concernée:

    Code PASCAL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
     ShowMessage('Essai avec accents: éàè');
    ... 
     Label1.Caption := 'Essai avec accents: éàè';

  11. #11
    Membre confirmé

    Homme Profil pro
    Autre
    Inscrit en
    Novembre 2015
    Messages
    145
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Autre

    Informations forums :
    Inscription : Novembre 2015
    Messages : 145
    Points : 625
    Points
    625
    Par défaut
    Après relecture, il m'apparaît que je n'ai peut-être pas été très clair dans mes explications.


    Concernant la "solution qui fonctionne" :
    Code PASCAL : Sélectionner tout - Visualiser dans une fenêtre à part
    ... widestring(UTf8toAnsi('Première ligne de texte')) ...
    Il ne faudrait pas croire que c'est la fonction Utf8ToAnsi qui est à l'origine de la "correction" du problème. Car cette fonction ne fait plus rien.


    Car c'est en fait l'appel à une fonction qui renvoie une chaîne de caractères comme résultat qui permet cette "correction". Une variable "temporaire" de type string est alors en effet créée en retour de la fonction Utf8ToAnsi, et l'on se retrouve alors dans le cas de figure que j'avais proposé, à savoir:
    Code PASCAL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    var S: string;
    ...  widestring(S) ....

    Pour s'en convaincre, il suffit d'utiliser en lieu et place n'importe qu'elle autre fonction du même type, avec un résultat toujours correct. Exemples:
    Code PASCAL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    ... Widestring(Trim('Première ligne de texte')) ...
    ... Widestring(Copy('Première ligne de texte',1,1000)) ...
    ... Widestring(StringReplace('Première ligne de texte','pasgloppasglop','glopglop',[rfReplaceAll, rfIgnoreCase])) ...
    ou même:
    Code PASCAL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    function DoNothing(Const S: string): string;
    begin
      result := S;
    end;
     
    ... Widestring(DoNothing('Première ligne de texte')) ...

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [Drupal] L'encodage des caractères est "coupé" pour les résumés
    Par Samy-DT dans le forum EDI, CMS, Outils, Scripts et API
    Réponses: 5
    Dernier message: 30/12/2015, 11h05
  2. [Mail] Encodage des caractères pour les mails
    Par Cr@zyDeep dans le forum Langage
    Réponses: 2
    Dernier message: 29/03/2007, 20h11
  3. result: chaine de caractère pour une DLL
    Par Sephiroth Lune dans le forum Langage
    Réponses: 7
    Dernier message: 27/07/2004, 23h05
  4. Réponses: 9
    Dernier message: 30/06/2004, 23h19

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