Étape 2: Comment ça marche...
Sélection de polices
LaserCAD utilise la librairie GDI + de Microsoft pour la gestion des polices. Lorsque vous sélectionnez une police dans le menu déroulant sur la zone de texte modifier une liste des polices disponibles s’affiche. Après avoir entrer du texte et cliquez sur Ok, LaserCAD copie le nom de famille de polices dans la liste déroulante et passe à GDI + à l’aide de code qui ressemble à quelque chose comme ceci :
PwzFontFamily Voici la chaîne de texte tirée de la ComboBox de polices. fSize est un flotteur avec la taille de la police taille déroulante et iStyle a drapeaux pour gras, italique et soulignement (etc..)
Lorsque ce constructeur est appelé, le code de Microsoft (source est disponible) appelle GdipCreateFont() en passant des informations similaires. Si une police correspondante ne peut pas être trouvée et code d’erreur et le code de Microsoft passera ensuite à une police San Serif générique comme indiqué ci-dessous :
Tel que mentionné précédemment, afin d’obtenir la police correcte de LaserCAD comme-est, il faut savoir si la police que vous avez sélectionné doit souligner en gras, italique ou (rare) inclus dans la liste style passée à GdipCreateFont. Une police comme Monotype Corsiva par exemple n’existe que comme un italique. Si Gdiplus::FontStyle::FontStyleRegular est passée à GdipCreateFont, comme le sera le cas si un des boutons gras, italique ou souligné n’est pas coché, GdipCreateFont échoue à trouver le Monotype Corsiva italique uniquement et la police de San Serif générique sera utilisée.
Le correctif de sélection de polices
Pour résoudre ce problème, que nous allons utiliser le code suivant à si la police sélectionnée prend en charge les gras, italique, souligné ou normale :
Une fois que nous savons quels styles le support des polices nous pouvons désactiver les boutons qui ne s’appliquent pas. Si la police ne prend pas en charge les FontStyle::FontStyleRegular mais prend en charge les gras ou italique, l’un d'entre eux sera vérifié. Si seulement on est pris en charge il est également désactivé afin qu’il ne peut pas être coupée.
Pour être capable de faire cela, j’ai intercepter rappel DialogProc l’éditer texte du dialogue. Cela pourrait se faire par l’intermédiaire de sous-classement, mais une technique différente a été utilisée ici qui déborde le cadre de cet article. Le code d’origine pourrait être fixé en altérant la DialogProc existant pour faire la même chose.
Saisie de texte et rendu
Le bogue avec la saisie de texte non-ANSI (non anglophones) se produit car la DialogProc lit le texte dans le contrôle d’édition à l’aide d’une fonction ANSI, comme GetDlgItemTextA. La fenêtre elle-même (comme avec la plupart des contrôles RichEdit) est capable de retenir le texte Unicode, mais l’appel à GetDlgItemTextA ne sera pas en mesure de représenter les caractères correctement et les remplacera avec points d’interrogation ou autres caractères de remplacement.
Pour résoudre ce problème, étant donné que je ne peux pas changer facilement le code existant, j’ai placé un crochet sur la EndDialog d’API Windows. Ma fonction de raccordement est illustrée ci-dessous :
Il fonctionne en lisant le texte du contrôle d’édition avant la fermeture de la boîte de dialogue et de stocker ce texte dans une variable globale : g_wstrLastKnownText.
L’étape finale consiste à accrocher la fonction GDI + qui est utilisée pour restituer le texte : GdipAddPathString. Lorsqu’il est appelé, j’ai remplacer tout simplement le texte qui lui est passé avec la chaîne que j’ai sauvé depuis le contrôle d’édition. Malheureusement, le texte qui a été passé à GdipAddPathString par LaserCAD devait être reconvertie en une chaîne Unicode avant il pouvait être envoyé à GdipAddPathString, mais, le mal avait déjà été fait. Voici mon remplacement pour GdipAddPathString :
Cela fait, il est maintenant possible de saisir du texte non-ANSI du contrôle d’édition et l’ai rendu correctement pour Laser découpe / gravure !
Le correctif nécessaire
Le code de LaserCAD pourrait être fixé par la simple utilisation de Unicode (wchar_t) au lieu de tampons caractère ANSI (char) lors de la lecture de la chaîne du contrôle d’édition. Tant qu’il est jamais converti en une chaîne ANSI il rendra correctement lorsqu’il est passé à GdipAddPathString.