Windows & police

Non je ne relance pas un débat sur le piratage de ce cher système d'exploitation mais je vais plutôt vous présenter un problème que j'ai rencontré.

Sous Windows, lorsque vous développez une application, il existe 2 méthodes pour créer des fenêtres et contrôles pour votre application:

  • des appels à l'API Win32 en C ;
  • une déclaration de vos fenêtres et contrôles en ressource (utilisé par MFC).

La première solution, assez complexe, possède aussi un inconvénient majeure, c'est que la police avec laquelle les contrôles seront créés est une vieille police (assez laide) qui n'est plus utilisé aujourd'hui.

La seconde solution, bien plus simple, permet de créer des contrôles avec la police système. Enfin c'est ce que je croyais. Puisque je viens de découvrir que finalement non, cette méthode possèdes les mêmes problèmes que la première puisque la police est spécifiée en dur dans les ressources, et les préférences de l'utilisateur ne sont jamais consultées. Cela ne se voyait pas jusqu'à l'arrivée de Windows XP qui amène un lissage des polices au sous-pixels (ClearType) qui ne sera pas disponible sur vottre application MFC, tout simplement parce que celle-ci utilise encore sa bonne vielle police non lissable au sous-pixels spécifiée dans les ressources.

Mais comment faire ? - me direz-vous.

Et bien il suffit de re-paramétrer une par une toutes les fenêtres de votre application pour leur spécifier d'utiliser la fonte configuré par l'utilisateur. Et comme je suis vachement gentil, je vous donne même le code ;) :

void SetWindowFontToDefaultSystemFont(HWND hWnd)
{
	NONCLIENTMETRICS ncm;
	ncm.cbSize = sizeof(ncm);
	SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(ncm), &ncm, 0);

	static HFONT hFont = NULL;
	if( hFont == NULL )
	{
		// Création de la police système
		hFont = CreateFontIndirect(&ncm.lfMessageFont);
	}

	// Modification de la police
	WPARAM wParam = WPARAM(hFont); // Handle to font
	LPARAM lParam = FALSE; // Redraw parameter
	SendMessage(hWnd, WM_SETFONT, wParam, lParam);

	///////////////////////////////////////////////////
	// Appel récursif sur les enfants

	HWND hWndFirstChild = GetWindow(hWnd, GW_CHILD);
	if( hWndFirstChild == NULL )
	{
		// Pas d'enfants
		return;
	}

	HWND hWndChild = hWndFirstChild;
	do
	{
		// Appel sur le fils
		SetWindowFontToDefaultSystemFont(hWndChild);

		hWndChild = GetWindow(hWndChild, GW_HWNDNEXT);
	}
	while(hWndChild != NULL );
}

(Mmmh, dommage que je n'ai pas une fonction de coloration syntaxique comme Darken)

Haut de page