États du module d'une DLL normale liée de manière dynamique aux MFC
La possibilité de lier de manière dynamique une DLL normale à la DLL MFC permet quelques configurations qui sont très complexes. Par exemple, une DLL normale et l'exécutable qui l'utilise peuvent tous deux être liés de manière dynamique à la DLL MFC et à toute DLL d'extension.
Cette configuration pose un problème en ce qui concerne les données globales MFC (par exemple le pointeur désignant l'objet CWinApp en cours et les tables de handles).
Avant la version 4.0 des MFC, ces données globales résidaient dans la DLL MFC elle-même et étaient partagées par tous les modules du processus. Comme chaque processus utilisant une DLL Win32 obtient sa propre copie des données des DLL, cette méthode fournissait un moyen aisé de suivre les données processus par processus. En outre, comme le modèle AFXDLL supposait la présence d'un seul objet CWinApp et d'un seul jeu de tables de handles dans le processus, ces éléments pouvaient être suivis dans la DLL MFC proprement dite.
Mais avec la possibilité de lier de manière dynamique une DLL normale à la DLL MFC, il est maintenant acceptable d'avoir deux ou plusieurs objets CWinApp dans un processus — et également deux ou plusieurs jeux de tables de handles. Comment la bibliothèque MFC assure-t-elle le suivi des éléments qu'elle doit utiliser ?
La solution consiste à remettre à chaque module (application ou DLL normale) sa propre copie de ces informations sur l'état global. Ainsi, un appel à AfxGetApp dans la DLL normale retourne un pointeur désignant l'objet CWinApp dans la DLL, et non celui dans l'exécutable. Cette copie par module des données globales des MFC est appelée « état du module » et est décrite dans MFC Technical Note 58.
La procédure de fenêtre commune des MFC bascule automatiquement vers l'état du module approprié, ce qui fait que vous n'avez pas besoin de vous en inquiéter dans les gestionnaires de messages éventuellement implémentés dans la DLL normale. Mais quand l'exécutable appelle la DLL normale, vous devez définir de manière explicite l'état du module en cours en tant que celui de la DLL. Pour ce faire, utilisez la macro AFX_MANAGE_STATE dans chaque fonction exportée à partir de la DLL. Pour cela, ajoutez la ligne de code suivante au début des fonctions exportées à partir de la DLL :
AFX_MANAGE_STATE(AfxGetStaticModuleState( ))