1

Hello,

En me confrontant à un problème tout con, je me rends compte que je n'ai pas la moindre idée du fonctionnement des contrôles Windows vis à vis des encodages. Il me semble avoir remarqué qu'en .NET, tout fonctionne en UTF-8 (le libellé des composants, le texte qu'on tape dans une TextBox, etc...). J'ai bien tenté de trouver la confirmation sur google, mais dès qu'on tape "UTF-8" ou "charset" dans une requête on trouve tout sauf ce que je cherche.

D'où mes deux questions :

- Qu'est-ce qui détermine, sous Windows, l'encodage utilisé par un composant ?
- Existe-t-il un moyen de le changer au runtime, ou au moins de saisir un texte en ISO-8859-1 dans un composant qui attend de l'UTF-8 ? (j'ai un soft en UTF-8 qui me propose une boite de saisie et qui envoie le texte tapé à un serveur, mais le serveur s'attend à recevoir de l'ISO-8859-1, du coup ça foire)

Merci si vous avez des liens ou des explications ^^
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

2

Es-tu sûr que ce n'est pas l'UTF-16 qui est utilisé en interne (comme en Java, Qt et pour les APIs *W du W32) et l'UTF-8 seulement quand tu convertis en une séquence d'octets?
avatar
Mes news pour calculatrices TI: Ti-Gen
Mes projets PC pour calculatrices TI: TIGCC, CalcForge (CalcForgeLP, Emu-TIGCC)
Mes chans IRC: #tigcc et #inspired sur irc.freequest.net (UTF-8)

Liberté, Égalité, Fraternité

3

on s'en tamponne le coquillard de le savoir ou pas.

Zephyr, est ce qu'on a accès aux fonctions windows MultiByteToWideChar et consors en dot net? c'est ça qui transforme les encodages en unicode, et l'inverse. Donc faudrait décoder utf8->unicode puis réencoder unicode->ISO. enfin c'est ce que je ferais.

ah tiens d'après wikipedia y'a http://msdn.microsoft.com/en-us/library/system.text.encoding.convert%28VS.71%29.aspx qui est fait pour dotnet.

et sinon y'a iconv (une usine à gaz gnu cross platform) mais c'est pas ce que tu veux je pense.

4

Nan mais je ne veux pas transcoder des chaines, y'a des tas de fonctions pour faire ça et là n'est pas le problème.

Mon objectif est de comprendre comment sont gérés les encodages au niveau des composants (peut-être que Kevin a raison et que c'est de l'UTF-16, à vrai dire je ne sais pas trop comment le vérifier) au moment de la saisie et de la récupération, dans le but de forcer l'envoi d'une chaine en ISO-8859-1 alors qu'actuellement c'est de l'UTF-8 qui est envoyé.
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

5

Windows travaille en UTF16 en interne, ça c'est sur. Il y a des fonction en C/C++ pour convertir de l'UTF16 <-> ASCII "classique" faut que je me souvienne desquels par contre sorry

Par contre si le composant en question est fait pour envoyer de l'UTF8 mais qu'il n'y a aucune parametre pour changer ça, c'est mort, tu pourras pas changer le comportement...

Juste pour etre sur, le composant en question te donne la chaine et c'est toi qui l'envoi, ou tu lui donne une chaine et c'est lui qui l'envoi ?


Et c'est quel "composant" ?

Et c'est du .Net ou du Win32 ?

Si c'est du Win32 il faut utiliser les version postfixé "A" de l'API pour utiliser en mode "ASCII" si on utlise les fonction postfixé "W" (Wide) ce sont les version UTF-16.

En tout cas dur de t'aider sans savoir de quel composant tu parles..
avatar
Proud to be CAKE©®™


GCC4TI importe qui a problème en Autriche, pour l'UE plus et une encore de correspours nucléaire, ce n'est pas ytre d'instérier. L'état très même contraire, toujours reconstruire un pouvoir une choyer d'aucrée de compris le plus mite de genre, ce n'est pas moins)
Stalin est l'élection de la langie.

6

Godzil (./5) :
Par contre si le composant en question est fait pour envoyer de l'UTF8 mais qu'il n'y a aucune parametre pour changer ça, c'est mort, tu pourras pas changer le comportement...

Pas sûr, c'est l'objectif de ce topic. Peut-être qu'il y a moyen de forcer le buffer interne avec je ne sais quel appel bas-niveau et d'y mettre une chaine ISO-8859-1 (invalide pour de l'UTF-8 mais on s'en fout s'il n'y a pas de vérification de validité), qui sera restituée telle quelle ensuite.
Juste pour etre sur, le composant en question te donne la chaine et c'est toi qui l'envoi, ou tu lui donne une chaine et c'est lui qui l'envoi ?

Je saisis une chaine dans une TextBox (aucune idée du charset utilisé ici), puis je valide, et c'est une chaine en UTF-8 qui est envoyée au serveur.
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

7

Donc j'en conclus que c'est du .Net
avatar
Proud to be CAKE©®™


GCC4TI importe qui a problème en Autriche, pour l'UE plus et une encore de correspours nucléaire, ce n'est pas ytre d'instérier. L'état très même contraire, toujours reconstruire un pouvoir une choyer d'aucrée de compris le plus mite de genre, ce n'est pas moins)
Stalin est l'élection de la langie.

8

Je pense pas, mais peut-être...
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

9

si t'as pas de controle sur le composant il te faudrait une fonction setencoding pour changer l'encodage par défaut, en priant pour que le composant n'override pas. C'est bien ça? et pas moyen de capturer la sortie du composant pour la convertir?

10

en gros c'est ça, oui.

- soit il y a un moyen de changer le "charset d'un composant" (je ne sais même pas si cette notion existe sous win)
- soit il faudrait que j'arrive à passer outre les conversions automatiques en utilisant une fonction très bas niveau
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

11

Et comment veux-tu qu'on t'aide sans savoir de quel "composant" tu parles ?
avatar
Proud to be CAKE©®™


GCC4TI importe qui a problème en Autriche, pour l'UE plus et une encore de correspours nucléaire, ce n'est pas ytre d'instérier. L'état très même contraire, toujours reconstruire un pouvoir une choyer d'aucrée de compris le plus mite de genre, ce n'est pas moins)
Stalin est l'élection de la langie.

12

je t'ai répondu au ./6, c'est une TextBox, mais c'est la réponse en général qui m'intéresse, pas le cas particulier d'un seul composant (encore qu'ils fonctionnement probablement tous pareil donc je ne vois pas trop ce que ça change)
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

13

Ha pardon ok, je croyait que tu parlais d'un composant reseau qui envoie des donnée vers un serveur, et non d'un control windows
avatar
Proud to be CAKE©®™


GCC4TI importe qui a problème en Autriche, pour l'UE plus et une encore de correspours nucléaire, ce n'est pas ytre d'instérier. L'état très même contraire, toujours reconstruire un pouvoir une choyer d'aucrée de compris le plus mite de genre, ce n'est pas moins)
Stalin est l'élection de la langie.

14

Non non, il y a peut-être (probablement) des conversions effectuées entre la saisie dans la TextBox et le moment où l'appli communique la chaine avec le serveur, mais n'ayant pas le code source je n'ai pas la main sur ces étapes. La seule chose que je peux peut-être essayer de faire, c'est de trafiquer la chaine au moment où elle est saisie dans la TextBox, avec l'espoir que les éventuelles conversions successives ne la rendent pas corrompue avant la fin.
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

15

Zephyr : je pige pas trop pourquoi tu veux pas donner les infos précises dont a discuté hier, mais bon cheeky
Ou alors c'est que tu veux une réponse plus générale ?
avatar
Zeroblog

« Tout homme porte sur l'épaule gauche un singe et, sur l'épaule droite, un perroquet. » — Jean Cocteau
« Moi je cherche plus de logique non plus. C'est surement pour cela que j'apprécie les Ataris, ils sont aussi logiques que moi ! » — GT Turbo

16

c'est quoi les infos précises que tu as demandé hier ? (parcequ'effectivement si la réponse n'est valable que pour ce cas précis ça ne m'intéresse pas, du coup je vois pas ce que tu peux vouloir de plus comme infos, mais s'il te les faut vraiment demande ^^)
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

17

Zephyr (./14) :
La seule chose que je peux peut-être essayer de faire, c'est de trafiquer la chaine au moment où elle est saisie dans la TextBox, avec l'espoir que les éventuelles conversions successives ne la rendent pas corrompue avant la fin.

C'est pas plus simple de faire un listener réseau, pour le coup ? Enfin, ça ne répond pas du tout à ta problématique d'ordre général, c'est clair (et j'avoue que je ne m'étais jamais posé ce genre de questions, mais c'est vrai que c'est bien chiant en fait).
avatar

18

Zephyr : non tu m'as mal compris, ce que je veux dire c'est que sur IRC tu avais expliqué quel était le contexte et le soft concerné, alors que la question que tu as posée ici est assez générale (à la lecture de ton premier post, je pensais pas du tout à la situation que tu as évoquée hier par exemple).

Bon après tu veux peut-être aussi savoir comment ça fonctionne dans le cas général, je sais pas cheeky
avatar
Zeroblog

« Tout homme porte sur l'épaule gauche un singe et, sur l'épaule droite, un perroquet. » — Jean Cocteau
« Moi je cherche plus de logique non plus. C'est surement pour cela que j'apprécie les Ataris, ils sont aussi logiques que moi ! » — GT Turbo

19

bah oui, je veux savoir comment ça fonctionne dans le cas général, à la limite le problème précis sur lequel je suis tombé hier ne m'intéresse pas plus que ça ^^ (sinon c'est lui que j'aurais mis en avant en ./1)
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

20

OK.

Bon pour résumer (si j'ai bien compris), Zephyr cherche grosso modo à copier un tableau d'octets dans le buffer interne d'une zone de texte, pour qu'à la lecture de cette dernière le programme se récupère le tableau tel quel. Ici c'est pour forcer un programme qui envoie en UTF-8 à transmettre une chaîne en ISO-8859-1, mais à la limite c'est pas la question.

Alors comme je le disais hier (et confirmé par d'autres personnes plus haut) :

- en interne, Windows fonctionne soit en ANSI (Windows-1252), soit en UTF16. Les fonctions de l'API qui gèrent des chaînes sont suffixés par A et W, respectivement.

- on peut lire le contenu en UTF16 d'une zone de texte avec GetWindowTextW() et le définir avec SetWindowTextW(), mais je ne suis pas sûr du tout qu'il n'y ait pas de conversion/vérification effectuée pour voir si la chaîne passée est de l'UTF16 valide. En d'autres termes c'est pas sûr que ça corresponde directement à l'état du buffer interne de la zone de texte.

- comme les zones de texte ne gèrent pas directement l'UTF8, il y a forcément une conversion UTF16->UTF8 avant que le soft envoie le buffer. Donc définir le buffer avec les octets bruts qu'on veut envoyer ne marchera pas, il faut tenir compte de cette conversion (là aussi, possibilité que ça coince si il y a vérification de la validité de la chaîne).
avatar
Zeroblog

« Tout homme porte sur l'épaule gauche un singe et, sur l'épaule droite, un perroquet. » — Jean Cocteau
« Moi je cherche plus de logique non plus. C'est surement pour cela que j'apprécie les Ataris, ils sont aussi logiques que moi ! » — GT Turbo

21

je sais qu'il y a une fonction de win32 qui sert à ce que tu veux je pense, d'ailleurs elle foire sur windows mobile, ou est incomplète, chais plus:

voila, ce serait pas ça des fois?

http://msdn.microsoft.com/en-us/library/x99tb11d%28VS.71%29.aspx

22

./20 : D'après les points n°2 et n°3, je peux prendre la chaine que je veux envoyer en ISO-8859-1, appliquer une transformation "UTF8 -> UTF16" puis la passer à SetWindowTextW(). Le problème c'est que ma chaine n'étant pas valide au sens UTF8, la convertir en UTF16 ne sera peut-être pas possible (si ça consiste simplement en une manipulation d'octets ça ira, mais s'il y a une étape de vérification ça va coincer).

Si ça marche, au moment d'envoyer la chaine au serveur le programme devrait donc aller la chercher en UTF16 et appliquer sa transformation "UTF16 -> UTF8", ce qui pourrait me redonner ma chaine ISO-8859-1 initiale.

C'est très théorique et si personne n'a testé avant, la réponse attendra que je trouve le temps de faire un petit outil pour vérifier smile
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

23

En meme temps, tu ne sais aps ce que fait l'application entre le champs texte et l'envoi des donnée. Rien ne prouve qu'il n'y a pas un traitement (quel qu'il soit) sur la chaine
avatar
Proud to be CAKE©®™


GCC4TI importe qui a problème en Autriche, pour l'UE plus et une encore de correspours nucléaire, ce n'est pas ytre d'instérier. L'état très même contraire, toujours reconstruire un pouvoir une choyer d'aucrée de compris le plus mite de genre, ce n'est pas moins)
Stalin est l'élection de la langie.

24

25

./23 : oui, c'est une évidence. Mais encore une fois c'est la théorie derrière qui m'intéresse.

./24 : aucune idée, pour moi la locale c'est ce qui permet de déterminer le format des dates, le séparateur des nombres décimaux & co, je ne sais même pas si ça a un quelconque rapport avec des histoires d'encodage.
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

26

bah si justement, regarde le meuseudeuneu:

locale :: "lang[_country_region[.code_page]]" 
            | ".code_page"
            | ""
            | NULL

27

Zephyr (./22) :
Le problème c'est que ma chaine n'étant pas valide au sens UTF8, la convertir en UTF16 ne sera peut-être pas possible (si ça consiste simplement en une manipulation d'octets ça ira, mais s'il y a une étape de vérification ça va coincer).

Pire, si la chaîne n'est pas de l'UTF-8 valide, elle ne peut même pas être convertie en UTF-16 étant donné que seules les chaînes valides ont une représentation UTF-16 qui permet de retrouver l'UTF-8 d'origine. (Les chaînes non valides n'ont soit aucune représentation UTF-16 (le cas le plus courant), soit elles sont de longueur non-minimale et donc si tu essaies de les convertir en UTF-16, puis reconvertir en UTF-8, tu auras la chaîne de longueur minimale correspondante, pas celle de laquelle tu es parti.)
Si ça marche, au moment d'envoyer la chaine au serveur le programme devrait donc aller la chercher en UTF16 et appliquer sa transformation "UTF16 -> UTF8", ce qui pourrait me redonner ma chaine ISO-8859-1 initiale.

Ça ne marche pas, cf. ci-dessus.
avatar
Mes news pour calculatrices TI: Ti-Gen
Mes projets PC pour calculatrices TI: TIGCC, CalcForge (CalcForgeLP, Emu-TIGCC)
Mes chans IRC: #tigcc et #inspired sur irc.freequest.net (UTF-8)

Liberté, Égalité, Fraternité

28

Ben je pense qu'il n'y a pas, et n'auras jamais de solution universelle. Tu as deux boite noire différentes, mais qui semblent faire la meme chose, ou tu as une entrée et une sortie, tu peut tenter de tweaker l'entrée pour la premiere pour lui faire sortir ce que tu veux (mais qui n'est pas prévu a la base), mais rien ne prouve que ça marchera sur la seconde.

Ie, sans savoir ce que le code entre la textbox et la socket fait, c'est impossible de déterminer comment et quand faire la modif. Rien ne prouve que c'est bien la textbox qui formate la chaine, ça peut etre du code au milieu, ça peut etre le wrapper autour de la socket, la socket elle meme etc...

avatar
Proud to be CAKE©®™


GCC4TI importe qui a problème en Autriche, pour l'UE plus et une encore de correspours nucléaire, ce n'est pas ytre d'instérier. L'état très même contraire, toujours reconstruire un pouvoir une choyer d'aucrée de compris le plus mite de genre, ce n'est pas moins)
Stalin est l'élection de la langie.

29

Kevin Kofler (./27) :
Pire, si la chaîne n'est pas de l'UTF-8 valide, elle ne peut même pas être convertie en UTF-16 étant donné que seules les chaînes valides ont une représentation UTF-16 qui permet de retrouver l'UTF-8 d'origine. (Les chaînes non valides n'ont soit aucune représentation UTF-16 (le cas le plus courant), soit elles sont de longueur non-minimale et donc si tu essaies de les convertir en UTF-16, puis reconvertir en UTF-8, tu auras la chaîne de longueur minimale correspondante, pas celle de laquelle tu es parti.)

Merde, je pensais que les conversions UTF-8 <-> UTF-16 n'étaient que de simples manipulations de bits. Pour le coup ça fout mes idées en l'air grin

Merci pour les infos smile

./28 : Je sais, mais je ne m'intéresse qu'aux transformations liées à l'interface (les conversions in/out lors de saisie dans les composants Windows), pas au reste.
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

30

Toutes les fonctions Windows fonctionnent en UTF-16 (ou ANSI mais c'est obsolète, sans déconner), et le framework .NET ne fait pas exception. Un char en C# (System.Char) est un caractère Unicode sur 16 bits (donc des fois il en faut 2 pour certains caractères particuliers), une chaîne (System.String) en .NET est une chaîne de caractères (System.Char) 16 bits. Tout en interne est toujours encodé en UTF-16LE (sur CPU intel au moins). Le seul endroit où tes données peuvent changer de format, et, traditionnellement, en changent, c'est lors du passage par un flux (fichier, mémoire, réseau, ... Et plus précisément, c'est fait par les classes dérivées de TextWriter ou BinaryWriter) qui va utiliser System.Text.Encoding pour convertir une chaîne en série d'octets, et utiliser par défaut System.Text.UTF8Encoding (souvent avec BOM, mais parfois sans, ça m'a surpris très récemment)

Je vois un moyen relativement simple de résoudre ton problème si c'est vraiment du .NET comme tu l'explique ^^
Normalement, tu peux héberger au sein de ton processus l'autre application (en gros, tu devrais créer un genre de lanceur/surcouche), et si tu as les autorisations de réflexion, tu peux bidouiller méchamment le fonctionnement interne de l'application (changer le comportement des composants, ou même les remplacer). En l'occurrence ce qui te pose problème doit avoir lieu au moment de la validation, donc tu peux par exemple détecter ça (en te déclarant receveur d'évènements là où il faut) et agir en conséquences. Pour le "agir en conséquences" par contre, ça dépend vraiment de comment l'application est codée en interne. Ça peut très bien être extrêmement complexe à réaliser, et donc pas du tout une bonne idée.

Quand à l'encodage inverse ANSI--[transfo UTF8->UTF16]-->UTF-16, ça n'a effectivement quasi aucune chance de fonctionner. Il y a des bits de redondance, aussi bien en UTF-8 qu'en UTF-16 (bon, UTF-16 est largement différent car ça dépend des "surrogate pairs", mais bref tongue), qui te permettent de savoir qu'un caractère est le début d'une séquence, et que le suivant fait bien partie de la séquence... En gros, seuls certains caractères "ASCII étendu" peuvent démarrer une séquence UTF-8, et seuls certains ("ASCII étendus" toujours) peuvent la continuer. Un caractère ASCII banal brise ta séquence, et il y a même quelques caractères interdits... bref ^^

(PS: désolé pour le cross, j'ai posté après ./22 tongue)
avatar
Le scénario de notre univers a été rédigée par un bataillon de singes savants. Tout s'explique enfin.
T'as un problème ? Tu veux un bonbon ?
[CrystalMPQ] C# MPQ Library/Tools - [CrystalBoy] C# GB Emulator - [Monoxide] C# OSX library - M68k Opcodes