Blog d'un EPSIen Epsylon

Informatique & co

Blog


18/07/2006 - 09:58 - Programmation - Aucun commentaire

Internationalisation d'un site & ASP .NET 2.0


Je dois développer une solution Intranet multi-langue, de ce fait des équipes françaises et anglophones seront ammener à utiliser ce site. Certe on pourrait créer ce site uniquement en anglais vu que c'est la langue la plus parlé mais il a été définis dans le cahier des charges que l'utilisateur doit avoir le choix entre deux langues que sont l'anglais et le français. Il fallait donc trouver un moyen efficace de pouvoir changer le contenu des labels selon la langue sélectionné.

La première solution qui pourrait venir à l'esprit c'est d'effectuer le chargement du contenu des labels de la page à la main, sur le :

protected void Page_Load(object sender, EventArgs e)


Il suffirait de tester le langage que l'utilisateur a sélectionné (on le sauvegarder dans une variable de Session) et remplir en conséquence.
C'est quand même assez moche comme solution non ?

En surfant sur le net j'ai trouvé une solution simple et éfficace que j'ai adapté et légèrement modifié. En fait la méthode la plus raisonnable est bien évidemment l'utilisation de fichier de ressources contenant le texte. Il y aurait donc un fichier de ressource pour chaque langue multiplié par le nombre de pages du site. Pour créer ces fichiers de ressources, Visual Studio 2005 propose une fonction bien sympathique il faut le dire. Il suffit d'aller dans Tools > Generate Local Ressource (uniquement lorsqu'on est en mode Design), et un nouveau fichier de ressource est généré par rapport au contenu de votre page (Label, Button, DetailView? etc...). Le fichier généré est celui qui sera utilisé par défaut si on ne définit pas la Culture de la page. Ces fichiers sont sous la forme : NomPage?.aspx.resx.
Il faut toujours avoir un fichier de ressource par defaut sous cette forme, ensuite c'est à nous de créer un fichier ressource pour chaque langue. J'ai donc créée deux autres fichiers pour chaque page : NomPage?.aspx.fr-FR.resx et NomPage?.aspx.en-US.resx. Cette notation est trés importante, si les fichiers ne sont pas nommés de cette façon, les fichiers ressources ne pourront pas être chargés dynamiquement par l'application. Il existe bien évidemment de nombreux autres codes : de-CH pour la Suisse par exemple, etc...

Une fois ces fichiers créés il ne reste plus qu'à indiquer à l'application si on souhaite utiliser le français (fr-FR) ou l'anglais (en-US).
Pour cela il suffit de surcharger une méthode de la classe System.Web.UI.Page :
protected override void InitializeCulture()

C'est ici que la mise en place de la culture choisie sera éffectuée. J'ai choisis de sauvegarder le code de la langue sélectionnée dans une variable de session (Session["Language"]). Le code de cette surcharge sera donc :

protected override void InitializeCulture()
{
        if (HttpContext.Current.Session["Language"] != null)
        {
                String selectedLanguage = HttpContext.Current.Session["Language"].ToString();

                UICulture = selectedLanguage;
                Culture = selectedLanguage;

                Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture(selectedLanguage);
                Thread.CurrentThread.CurrentUICulture = new CultureInfo(selectedLanguage);
         }

          base.InitializeCulture();
}


Grace à ce code, le fichier ressource correspondant à la valeur de Session["Language"] (fr-FR ou en-US) sera automatiquement chargé dans la page. Nous n'aurons pas à attribuer la valeur des labels et autres composants à la main !
Cependant c'est quand même assez pénible de devoir coller ce code pour chaque page de notre site, c'est pour cela que j'ai créé une nouvelle classe héritant elle même de System.Web.UI.Page qui surcharge la méthode InitializeCulture?(). De ce fait, toutes mes pages héritent maintenant de cette nouvelle classe et non plus de System.Web.UI.Page, grace à cela nous n'avons pas à copier-coller de partout notre méthode surchargée. C'est quand même plus propre non ? =)

30/11/2005 - 14:05 - Programmation - Aucun commentaire

Developpez.com


Fight Club
J'ai commencé à rédiger une série d'articles pour www.developpez.com. Ces tutoriaux porteront sur l'API Allegro. La plus part des possibilités d'Allegro seront couvertes : Affichage graphique, animation de sprite, gestion de l'animation à travers les timers, gestion des fichiers de données compréssés, interfaces graphiques, gestion du clavier et du son, fonctions de "configuration" à travers les fichier .ini etc...

Allegro est une librairie de développement de jeux vidéo pour développeurs C/C++ distribuée gratuitement, supportant les plates-formes DOS, Unix (Linux, FreeBSD?, Irix, Solaris, Darwin), Windows, QNX, BeOS? et MacOS? X. Elle fournit de nombreuses fonctions graphiques et sonores, gère le clavier, la souris, le joystick et des timers haute résolution. Elle dispose également de fonctions mathématiques 3d et en point fixe, de fonctions de gestion de fichiers de données compressés et d'une interface graphique.

Site web officiel : http://alleg.sourceforge.net/

Site developpez.com : http://kaiser-edouard.developpez.com/tutoriels/allegro/

24/10/2005 - 15:34 - Programmation - Aucun commentaire

Flat Model, Multi-segment model...


J'essaye depuis le début de créer un OS basé sur un modèle qu'on appelle "Multi-Segment" par rapport au spécificité de l'architecture Intel et de sa fameuse segmentation. J'avais trouvé le concept attirant et surtout je dois avouer que je n'avais vraiment pas envis de plonger mes mains dans la pagination.
Au début je voyais dans la GDT 4 descripteurs de base (NULL, CodeNoyau?, Data Noyau, Stack Noyau).
Ensuite le reste de la GDT sera dédié aux segments utilisateurs.

Par quoi serait caractérisé un processus utilisateur ?

Que ferait le noyau de son cote ?
Le noyau possèderait un tableau statique qui contiendrait dans chacune de ses cases une structure caractérisant un processus pour l'OS (PID, état, priorité, TSS, LDT etc...).
A travers l'IRQ0 dont l'entrée dans l'IDT pointera vers une fonction de scheduling, le noyau s'occupera d'elire un processus (mise en place de son TSS, on fait pointer les registres vers ses descripteurs) et de mettre à jour son tableau.

Nous avons donc une limite en terme de nombre de processus qui est égale a peu pret au nombre d'entrée dans la GDT / 2. Car un processus occupe 2 entrées dans la GDT : Une pour son TSS et l'autre pour sa LDT.

Tout semblait bien et cohérent, mais arriva le chapitre sur l'allocation dynamique...
Aie Aie, tout se complique, nous travaillons donc avec des segments !

Un segment possède une taille fixe et décrit donc une zone précise de la mémoire.
Lorsque je crée un processus je lui donne un emplacement en mémoire contigue, de la taille dont ont besoins ses données et son code.
Si ce processus souhaite allouer de la mémoire, plusieurs choses :
Problème : nous avons donc un nouveau segment de données.
Comment faire pour que le processus puisse utiliser ce segment ? Cela implique un changement du registre DS, enfin cette solution me semblait irréalisable, je ne saurai meme pas comment la gérer, mais me semblait la plus propre.

Comme me le faisait remarqué David Decotigny (SOS) la solution la plus propre est bien sur la deuxième mais avec gcc ce n'était pas evident : il repose tres tres peu sur un modele multi-segments et ne gere pas tout seul le passage d'un segment a l'autre : il faut l'aider.

En fait nous nous sommes trés vite rendus compte que le problème venait des outils et non du modèle : La plus part des compilateurs actuels sont basés sur un Flat modèle et non une multi segmentation.

J'ai donc décidé d'utiliser la pagination moi qui ne voulait surtout pas l'utiliser... Bien sur je pourrais m'en passer, mais je vois mal un OS incapable d'allouer dynamiquement de la mémoire.

La pagination permet donc a un processus de lui faire croire qu'il possède un espace contigue et linéaire alors qu'en fait toutes la mémoire dont il dispose n'est que trés rarement physiquement contigue. C'est toute la puissance de la pagination : Associé à une adresse physique : une adresse virtuelle !