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:
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:
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...
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....
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().
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: 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 !