Office Fluent UI en C++ natif

Publié dans: 

Vous avez probablement lu cet article rédigé par mon collègue et dont un extrait a paru dans le magazine français PROgrammez (Version PDF). Savez vous par contre qu’on peut produire des interfaces aussi charmantes en C++ natif ?

Même si l’orientation des éditeurs vers des architectures basées sur les frameworks Java ou Micorosft .NET s’explique essentiellement par la facilité apportée par ces derniers en termes de gestion de complexité, on ne peut nier les effets de mode et les efforts marketing des éditeurs et des communautés de ces produits.

J’estime par ailleurs qu’il est judicieux d’inclure le langage C++ comme une des alternatives pour le développement des nouveaux produits.

On ne peut pas imaginer par exemple, un système qui devra interagir avec du hardware ou bien effectuer de gros volumes de calcul algorithmique sans que l’on pense à envisager C++ comme langage de programmation.

Une autre approche consiste à considérer ce langage pour le développement de quelques briques logicielles et les intégrer par la suite à des modules développés sous Java, MS.NET ou autre. Cependant, l’effort de bridging dépensé peut s’avérer parfois beaucoup plus important que tout faire en C++.

Je ne suis pas le seul à promouvoir C++ comme architecture logicielle pour les applicatifs de bureau : il vous suffit de considérer ces deux produits:

  • Nefsis : Application de vidéoconférences entourée d’une architecture distribuée pour le streaming et le codage adaptatif.
  • Mindmanager : Application de mind-mapping et de brainstorming. Je la connais depuis deux ans mais ce n’est que récemment que j’ai découvert que tout était basé sur C++.

Ces deux applications implémentent Office Fluent UI dans leurs interfaces. Vous pouvez les tester pour croire vos yeux !

Plusieurs éditeurs travaillent aujourd’hui sur l’implémentent de ce type d’interfaces pour les offrir sous formes de classes C++ (codejoke.com, bcgsoft.com, prof-uis.com, etc.). D’autre part, une implémentation C++ en tant qu’extension à MFC a été aussi rendue publique par Microsoft.

Pour illustrer l’implémentation des FUI en C++, on reprendra des bouts de code de « Easy Profiler ». Easy Profiler est un profiler C/C++ composé d’un Collector et d’un Observer. Le collector est une bibliothèque de routines qui sert à générer un fichier XML que l’Observer permet d’illustrer d’une manière intuitive. Ces deux composants ainsi que leur documentation sont téléchargeables sur notre portail Labs.

L’Observer est développé avec MFC 9.0 et fait appel aux nouvelles classes implémentant Office 2007 Fluent UI. L’application permet le changement de thème :

Easy Profiler, disponible sous l’espace LABS, lui, est développé en utilisant MFC 9.0 et les nouvelles classes implémentant Office 2007 Fluent UI :

Ainsi l’application supporte le changement de thème :

En utilisant le thème Office 2007 Blue Luna, l’effet est :

Avec l’effet Aqua :

Plus techniquement, cette fonctionnalité est pilotée par une instance dérivée de CMFCVisualManager. Ainsi, les classes visuelles de MFC délèguent la plupart de leur code de dessin, à l’instance active en cours. L’appel à CMFCVisualManager::SetDefaultManager permet de sélectionner cette instance.

Le bouton-menu affiché dans l’image 1 est attaché à un menu avec des items dont les ID se trouvent dans l’intervalle [ID_VIEW_APPLOOK_WIN_2000, ID_VIEW_APPLOOK_OFF_2007_AQUA].

Un handler acceptant un UINT est déclaré dans le Message_MAP de la fenêtre principale dont le bouton-menu est un fils, pour gérer cette liste d’ID: ON_COMMAND_RANGE(ID_VIEW_APPLOOK_WIN_2000, ID_VIEW_APPLOOK_OFF_2007_AQUA, &CMainFrame::OnApplicationLook).

Dans le corps de la fonction OnApplicationLook on n’a qu’à sélectionner le VisulaManager en passant une instance dérivée de CMFCVisualManager :

void CMainFrame::OnApplicationLook(UINT id)
{
	CWaitCursor wait;  

	theApp.m_nAppLook = id;  

	switch (theApp.m_nAppLook)
	{
	case ID_VIEW_APPLOOK_WIN_2000:
		CMFCVisualManager::SetDefaultManager(RUNTIME_CLASS(CMFCVisualManager));
		break;  

	case ID_VIEW_APPLOOK_OFF_XP:
		CMFCVisualManager::SetDefaultManager(RUNTIME_CLASS(CMFCVisualManagerOfficeXP));
		break;  

	case ID_VIEW_APPLOOK_WIN_XP:
		CMFCVisualManagerWindows::m_b3DTabsXPTheme = TRUE;
		CMFCVisualManager::SetDefaultManager(RUNTIME_CLASS(CMFCVisualManagerWindows));
		break;  

	case ID_VIEW_APPLOOK_OFF_2003:
		CMFCVisualManager::SetDefaultManager(RUNTIME_CLASS(CMFCVisualManagerOffice2003));
		CDockingManager::SetDockingMode(DT_SMART);
		break;  

...

Avant de retourner (return !), il est nécessaire de diffuser un message aux fenêtres filles pour mettre à jour leurs surfaces.

RedrawWindow(NULL, NULL, RDW_ALLCHILDREN | RDW_INVALIDATE | RDW_UPDATENOW | RDW_FRAME | RDW_ERASE);  

Vous voyez que finalement, avec C++ on peut imaginer des interfaces moins sombres que celle sous l’invite de commandes et plus conviviales que celles développées avec les anciennes versions de MFC.