Les fontes

Windows utilise par défaut une fonte appelée SYSTEM_FONT. Cette fonction servant aussi pour l'affichage des menus. Mais ce n'est pas la seule fonte...

Fontes préchargées par le système

Il existe 6 fontes préchargées par le système. Pour les utiliser, il faudra passer par la fonction GetStockObject() en indiquant en paramètre "type de l'objet" la fonte:

Nom Description
ANSI_FIXED_FONT Fonte où tous les caractères ont la même taille. La lettre "i" occupera la même taille que "W" à l'affichage (remarque: dans ce cas, la largeur du caractère et identique en hauteur)
ANSI_VAR_FONT Fonte où les caractères ont une taille variable. La lettre "i" occupera donc moins de place que "W"
DEVICE_DEFAULT_FONT Fonte par défaut qui dépendra du périphérique
DEFAULT_GUI_FONT Fonte utilisée par défaut pour les menus, dialogues, ...
OEM_FIXED_FONT Fonte OEM (Original equipment manufacturer)
SYSTEM_FONT Fonte utilisée pour dessiner les menus, dialogues et text.
SYSTEM_FIXED_FONT Fonte où tous les caractères ont la même taille (l'occupation à l'écran de la lettre "i" sera la même que celle du "W" (remarque: dans ce cas, la largeur du caractère et identique en hauteur). Raison: compatibilité avec Windows 16 bits

Valeur retournée:

Le handle de l'objet ou NULL si erreur.

A partir du moment où le handle est différent de NULL, vous pourrez indiquer à Windows qu'il faut utiliser ce nouvel objet en le sélectionnant via la fonction SelectObject().

En sortie, la fonction retourne le handle de l'objet précédement utilisé. Bien utile pour repositionner la fonte précédente...

 

Pour utiliser une fonte prédéfinie, vous pouvez aussi écrire:

SelectObject(hDC,GetStockOBject(...)); mais c'est peut être moins lisible en maintenance...

 

Lorsque l'objet n'est plus utilisé (et qu'il n'est surtout plus sélectionné pour votre contexte de périphérique !), vous pouvez utiliser la commande DeleteObject() pour détruire cet instance d'objet. (Mais cette commande n'est pas obligatoire car il s'agit d'une fonte système, donc elle occupera toujours de la place).

 

Voici un petit exemple d'utilisation des fonctions:

Image non trouvée !

 

D'autres fontes...

Il existe des fonctions qui vont vous permettre d'énumérer les fontes chargées par des applications et d'avoir des informations concernant ces fontes:

 

Voici un exemple très simple qui va afficher le nom de toutes les fontes actuellement chargées:

Image non trouvée !

 

Maintenant que vous avez la liste des fontes diponibles, vous allez pouvoir les utiliser. Il faudra créer la fonte spécifiée. Ceci peut se faire grâce à la fonction CreateFont().

Cette fonction va permettre de créer une instance de la classe de fonte sélectionnée.

Cette fonction va nous permettre de définir la police, sa taille, son style, ...
HFONT CreateFont(
int nHeight,
int nWidth,
int nEscapement,
int nOrientation,
int fnWeight,
DWORD fdwItalic,
DWORD fdwUnderline,
DWORD fdwStrikeOut,
DWORD fdwCharSet,
DWORD fdwOutputPrecision,
DWORD fdwClipPrecision,
DWORD fdwQuality,
DWORD fdwPitchAndFamily,
LPCTSTR lpszFace
);

nHeight est la taille en hauteur de la fonte.

nWidth définit la largeur de la fonte (géré automatiquement en fonction de la hauteur si la valeur que l'on passe est 0).

nEscapement : de 10° en 10 °

nOrientation : de 10° en 10°

fnWeight correspond à la "grosseur" des lettres. Cette valeur peut varier de 0 à 1000. Microsoft propose des valeurs par défaut:

Nom Valeur
FW_DONTCARE 0
FW_THIN 100
FW_EXTRALIGHT 200
FW_ULTRALIGHT 200
FW_LIGHT 300
FW_NORMAL 400
FW_REGULAR 400
FW_MEDIUM 500
FW_SEMIBOLD 600
FW_DEMIBOLD 600
FW_BOLD 700
FW_EXTRABOLD 800
FW_ULTRABOLD 800
FW_HEAVY 900
FW_BLACK 900

fdwItalic pour avoir un texte en italique ou non (TRUE ou FALSE)

fdwUnderline pour avoir le texte souligné ou non

fdwStrikeOut pour avoir un texte barré ou non

Les 3 prochains paramètres n'ont pas vraiment d'importance...

fdwQuality permet de définir la qualité de rendu de la fonte. En clair utilisation de différentes méthodes anti aliasing:

Vous pourrez utiliser les valeurs suivantes:ANTIALIASED_QUALITY, CLEARTYPE_QUALITY, DEFAULT_QUALITY, DRAFT_QUALITY, NONANTIALIASED_QUALITY, PROOF_QUALITY

lpszFace est un pointeur sur le nom de la fonte à utiliser (attention, ce n'est pas le nom du fichier de la fonte), mais le nom que l'on peut récupérer par exemple par la fonction EnumFonte()

 

Cette fonction retourne un handle sur la nouvelle fonte créée. Vous pourrez (devrez) utiliser ce handle pour afficher un texte avec cette fonte.

 

Pour utiliser cette fonte, il faut ensuite la sélectionner:

hPrevFont = (HFONT)SelectObject(hDC, hFont);

hPrevFont contiendra le handle de la fonte précédemment utilisée. A conserver pour la restaurer lorsque vous en aurez fini avec la votre !!!

Supression qui se fera avec DeleteObject(hFont);

Voici un exemple d'utilisation. Je charge la fonte dans la procédure WinMain afin d'éviter de devoir recréer sans arrêt la fonte. Cela consomme peut-être un peu plus en mémoire, mais on gagne en vitesse ! Normalement, on devrait tout faire dans WM_PAINT...

Image non trouvée !

 

Ajouter de nouvelles fontes

L'ennui dans les exemples précédents, c'est que l'on utilise que les fontes déclarées dans le système. Mais rien ne m'empêche de faire votre propre police et de vouloir l'utiliser ensuite !

Vous pourrez utiliser la fonction AddFontResource() qui va ajouter une nouvelle fonte dans le système.

int AddFontResource(
LPCTSTR lpszFilename // Nom du fichier qui contient la fonte
);

lpszFilename est un pointeur sur une chaîne de caractères terminée par 0 qui contient un nom valide de fichier de fonte.
Les fichiers fontes utilisables doivent avoir comme extension : .fon pour FONt resource file ou:
.fnt,.ttf (true type font),.ttc,.fot,.otf,.mmm,.pfb ou .pfm

En sortie, la fonction retourne 0 si une erreur est constatée. Sinon, il s'agit du numéro de la fonte dans une liste des fontes disponibles.

Cette fonte pourra être utilisée par toutes les applications le demandatnt. Enfin, il faudra d'abord les en informer. Pour cela vous utilisez la commande SendMessage() comme suit:

SendMessage(HWND_BROADCAST, WM_FONTCHANGE, 0, 0); Où HWND_BROADCAST indique que toutes les fenêtres de niveau le plus élevé (et de tous types: popup, visible ou non, ...) devront être informées. Par contre, les fenêtres filles ne le seront pas ainsi....

Image non trouvée ! la fonte ne sera disponible que durant la durée de la session, voire plus court (A cause de la commande qui suit). En aucun cas, la fonte ne sera rechargée au prochain reboot de votre machine !!!

Enfin ne pas oublier de retirer cette fonte à la fin de l'application !

BOOL RemoveFontResource(
LPCTSTR lpFileName // Nom du fichier qui contient la fonte
);

Là aussi, il faudra informer les autres applications du changement dans de la liste des fontes disponibles par SendMessage(HWND_BROADCAST, WM_FONTCHANGE, 0, 0);


Par contre, si vous voulez charger une fonte qui ne sera connue que dans votre application, il faudra utiliser AddFontResourceEx() avec le paramètre FR_PRIVATE comme indiqué ci-dessous:

int AddFontResourceEx(
LPCTSTR lpszFilename, // Nom du fichier qui contient la fonte
DWORD fl, // caractéristique de la fonte
PVOID pdv // réservé
);


On passe le champ pdv qui est réservé et qui doit être NULL.

fl peut prendre 2 valeurs:
FR_PRIVATE qui va indiquer que seule l'application ayant déclenchée le AddFontResourceEx connaîtra la fonte.
FR_NOT_ENUM qui va indiquer qu'une enumération ne retournera comme disponible la fonte aux applications y compris l'application qui a chargée la fonte...

En sortie, on reçoit 0 si une erreur est constatée. Sinon, il s'agit du numéro de la fonte dans la liste.

Bien entendu, on ne fera plus: SendMessage(HWND_BROADCAST, WM_FONTCHANGE, 0, 0);

Pour retirer la fonte, on utilisera RemoveFontResourceEx():

BOOL RemoveFontResourceEx(
LPCTSTR lpFileName,
DWORD fl,
PVOID pdv
);


On voit que les champs sont identiques à AddFontResourceEx(). Et bien leur contenu aussi. Les valeurs doivent en effet être ceux passées à la fonction AddFontResourceEx().

Image non trouvée !Pour pouvoir utiliser ces deux fonctions, il faut que la variable prépro. _WIN32_WINNT soit déclarée:

#define _WIN32_WINNT 0x0500

 

Une autre fonction intéressante:

CreateFonteIndirect:

Cette fonction va permettre de créer une nouvelle fonte à partir d'informations que vous auez pu récupérer d'une autre fonte.

 

Exemple d'utilisation des fonction précédentes:

Utilisation de AddFontResourceEx()

Puis utilisation de la fonction HFONT CreateFont() en passant le nom logique de la fonte (Si vous ne connaissez pas le nom, il faudra utiliser la fonction d'énumération pour le connaître en utilisant par exemple le code donné précédemment: Image non trouvée !En principe, votre fonte sera la derniere fonte listée).

SelectObject() en utilisant le handle récupéré via CreateFont()

Et lorsque vous avez fini, un DeleteObject.

Avant de quitter le programme, ne pas oublier de faire un RemoveFonte().

 

Remarque concernant les fonctions présentées

Une raison d'être obligée d'utiliser ces fonctions de chargement de fontes est due tout simplement au périphérique utilisé:

Le dessin d'un texte peut occuper plus ou moins de place d'un périphérique à un autre. Ce problème va apparaître aussi lors d'un changement de résolution écran avec DirectX par exemple.

Comme la taille d'un caractère peut changer d'un périphérique à un autre, il va falloir s'intéresser à la manière de traiter ce problème. D'où le chapitre suivant qui donne des outils permettant de connaître cette taille.

 

Changer de fonte dans un contrôle

Pour changer de fonte, rien de plus simple, il suffit d'envoyer le message WM_SETFONT

SendMessage ((HWND) hwndEdit, (UINT) WM_SETFONT, (WPARAM) wParam, (LPARAM) lParam);

En entrée:

hwndEdit est le handle du contrôle

wParam handle sur la fonte (HFONT), à NULL, le contrôle utilisera la fonte système par défaut.

lParam la partie basse pourra contenir une information indiquant à TRUE qu'il faut prendre en compte immédiatement la nouvelle fonte, et donc redessiner immédiatement le contrôle.

En sortie:

Rien !