IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

MFC Discussion :

Problème d'encapsulation des MFCs


Sujet :

MFC

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2010
    Messages
    33
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2010
    Messages : 33
    Par défaut Problème d'encapsulation des MFCs
    Bonjour,

    Dans le cadre d'un de mes projets, je vais être amené à utiliser les MFCs. Je souhaite d'abord les encapsuler dans des classes génériques de ma conception afin de pouvoir proposer proprement et simplement d'autres implémentations avec des APIs différentes si le besoin s'en fait sentir (comme le fait la SFML par exemple pour les différents systèmes qu'elle supporte, une même interface pour les implémentations Win/Mac/Unix).

    Je me demande si les MFCs sont l'idéal pour ça. En effet, il s'agit déjà d'une encapsulation de l'API Win32, et son architecture m'impose de nombreuses contraintes qui les rendent difficiles à implémenter sous une interface générique (à cause des relations entres les diverses classes qui les composent entre autres). Mon plus gros problème est que les MFCs imposent d'utiliser une instance dérivée de la classe CWinAppEx, qui sert alors de point d'entrée au programme. J'ai donc encapsulé cette classe elle aussi, mais ça ne fonctionne pas car pour respecter le schéma usuel des MFCs, il faudrait que je déclare une instance de CWinAppEx dans mon programme, en dehors de mon encapsulation, ce que je ne peux faire. En effet, je ne veux pas qu'il y ait du code MFC dans mon programme, ce code doit impérativement être isolé dans une librairie à part réservée aux MFCs. Si je créé cette instance dans ma libraire MFC, j'ai droit à un "error LNK1561: entry point must be defined" à la compilation, et si j'utilise mon propre main dans le programme principal, je me tape une exception.

    Y a t-il un moyen de contourner ce problème? Ou devrais-je plutôt envisager d'encapsuler l'API Win32 directement au lieu des MFCs?

    Autre petite question qui n'a rien à voir, mais que je me permet de poser quand même car je ne vais pas ouvrir un nouveau topic pour si peu, quel est le nom exact d'une structure de donnée statique de ce genre en c++? N'y a t-il pas un moyen plus propre en C++ d'écrire ce genre de chose?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    struct Param 
    {
    	const std::wstring	section;
    	const std::wstring	entry;
    	const std::wstring	value;
    };
     
    static Param	param_array[] =
    {
    	{ L"Display", L"ResX", L"1680" },
    	{ L"Display", L"ResY", L"1050" },
    	{ L"Display", L"BitDepth", L"32" },
    	{ L"", L"", L"" },
    };
    Merci d'avance.

  2. #2
    Membre éprouvé
    Avatar de TheGzD
    Homme Profil pro
    Ingénieur/ Docteur en Informatique
    Inscrit en
    Avril 2007
    Messages
    1 327
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Ingénieur/ Docteur en Informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 1 327
    Par défaut
    Bonjour,

    Le soucis que tu rencontres doit venir des messages Windows. En effet pour que ton interface fonctionne il faut que ton application soit apte à recevoir les messages du système (transmis aussi par l'UI), or lorsque tu encapsules la classe CWinAppEx tu casses le chainage entre la partie MFC de ton programme et le système. Ceci est lié au fonctionnement de l'API Win32, donc MFC ou pas tu auras à mon humble avis à composer avec si tu veux développer sous Windows. Sauf si tu optes pour une autre API graphique comme Qt qui rajoute une couche d'abstraction supplémentaire. Concernant le fonctionnement des messages sous Windows, tu pourras en savoir plus en consultant la MSDN.

    Pour en revenir à ton problèmes et essayer de t'en sortir je vois 2 possibilités :
    - soit la couche MFC encapsule ton programme, et le chainage des messages est fait pour toi
    - soit tu réimplémentes un pompe à message dans ta classe perso qui les retransmet à la partie MFC encapsulée dans ton programme

    Bon courage

  3. #3
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2010
    Messages
    33
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2010
    Messages : 33
    Par défaut
    Pas de QT pour moi. Ca me faciliterait certes la tâche au plus haut point, mais je tiens à rester au plus bas niveau possible.

    Sinon, je me doutais que j'allais galérer avec les messages, mais malheureusement je n'en étais même pas là. Après relecture de mon premier post, je me rends compte que j'ai été tout sauf clair dans la description de mon problème, et je m'en excuse. Je vous reformule donc ça plus clairement :

    Je suis en train d'encapsuler les MFCs dans une librairie à part, destinée à être linkée à mon projet principal. Le problème c'est que lorsque je déclarais mon main dans ce dernier, il supplantait systématiquement le point d'entrée des MFCs, alors que j'aurais voulu que ce soit le contraire qui se passe, les MFCs ne fonctionnant pas si l'on surplante leur point d'entrée.

    J'utilise l'imparfait parce qu'après une bonne semaine de recherches et tests laborieux, j'ai enfin trouvé une solution qui fonctionne!

    Je vous envoie en pièce jointe ma solution (pour Visual Studio 2010). J'ai édulcoré le projet pour ne garder que le code en rapport avec mon problème, il est donc normal que ça soit très succin. La solution contient trois projets :
    -System_Abstraction : Ce projet (destiné à être compilé en tant que libraire) fourni une classe générique (classe Main) qui sera celle à laquelle on pourra avoir accès publiquement. Il contient en outre une interface (Main_Impl) qui est celle que devront respecter toutes les implémentations spécialisées de cette libraire.
    -System_MFC : Est lui aussi compilé en tant que librairie, et se charge de fournir l'implémentation MFC (classe Main_MFC) à partir de l'interface fournie par System_Abstraction.
    -System_Test : Celui là ne sert juste qu'à tester le bon fonctionnement de ma lib MFC et ne contient qu'un bête main.

    Le schéma suivit ici est directement inspiré de celui employé par la SFML, dont le code source m'aura décidément appris bien des choses.

    Ce qui se passe lors de l'exécution du projet :
    Grâce à la globale un peu particulière définie dans main.h (autostart), la fonction pre_main est appelée avant toute autre fonction (un grand merci à l'auteur de cet article). Elle créé alors une instance de la classe Main_MFC (qui est ma classe dérivée de CWinAppEx), qui sert ensuite de point d'entrée au programme. Après que le programme soit passé par le point d'entrée des MFCs, on à la fonction Run de la classe CWinAppEx que j'ai surchargée pour qu'elle appelle le main défini par l'utilisateur de la librairie. Tout est donc parfait et mes trois objectifs principaux sont remplis : les MFCs sont initialisées correctement et fonctionnent parfaitement, le code accessible à l'extérieur de ma librairie est entièrement générique et ne fait aucune mention aux MFCs, et l'utilisateur de la librairie peut redéfinir son propre main sans problème.

    Quelques point supplémentaires pour justifier ma solution :
    -Les MFCs plantent systématiquement si l'on utilise un point d'entrée personnalisé, il était donc impératif de faire passer le point d'entrée défini par l'utilisateur de la librairie après celui des MFCs.
    -Il n'y a pas moyen de faire instancier ma classe Main_MFC par l'utilisateur de la librairie, car si j'autorise le code de ce dernier à s’exécuter en premier, le programme ne passera jamais par le point d'entrée des MFCs et on en revient au problème décrit juste au dessus.
    -J'aurais pu tout simplement déclarer une instance de Main_MFC dans main.hpp, mais ce serait briser l'encapsulation désirée des MFCs. En effet, main.hpp sera le seul header auquel on aura accès à l'extérieur de la lib, il ne doit donc contenir que du code générique sans rapport aucun avec l'implémentation sous-jacente!
    -Déclarer une instance globale de Main_MFC dans ma librairie System_MFC ne suffit pas, car dans ce cas, le main défini par l'utilisateur de la lib surplante le point d'entrée des MFCs.


    Cependant, je suis persuadé qu'il y a largement moyen de faire ça de manière plus simple et plus propre, j’espère donc que quelqu'un jettera un œil à mon projet afin de m'aider à améliorer mon code.
    Fichiers attachés Fichiers attachés

  4. #4
    Expert confirmé
    Avatar de Mat.M
    Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2006
    Messages
    8 526
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2006
    Messages : 8 526
    Par défaut
    Citation Envoyé par RT222 Voir le message
    Bonjour,

    Dans le cadre d'un de mes projets, je vais être amené à utiliser les MFCs. Je souhaite d'abord les encapsuler dans des classes génériques de ma conception afin de pouvoir proposer proprement et simplement d'autres implémentations avec des APIs différentes si le besoin s'en fait sentir (comme le fait la SFML par exemple pour les différents systèmes qu'elle supporte, une même interface pour les implémentations Win/Mac/Unix).
    pourquoi encapsuler les MFC dans des classes génériques ??
    MFC c'est spécifique à Microsoft, pas portable.
    Par contre tu as le code source
    Ce que tu veux faire c'est interdit parce que tu veux redistribuer les classes.

    Citation Envoyé par RT222 Voir le message
    . Mon plus gros problème est que les MFCs imposent d'utiliser une instance dérivée de la classe CWinAppEx, qui sert alors de point d'entrée au programme. J'ai donc encapsulé cette classe elle aussi, mais ça ne fonctionne pas car pour respecter le schéma usuel des MFCs, i
    la classe de base c'est CObject et non CWinAppEx dans la hiérarchie
    Citation Envoyé par RT222 Voir le message
    l faudrait que je déclare une instance de CWinAppEx dans mon programme, en dehors de mon encapsulation, ce que je ne peux faire. En effet, je ne veux pas qu'il y ait du code MFC dans mon programme, ce code doit impérativement être isolé dans une librairie à part réservée aux MFCs.
    je ne vois intérêt à faire cela;
    les MFC c'est en grande partie pour faire des applis fenêtrées.
    Tu peux très bien faire des classes de fenêtre en win32 ce n'est pas si compliqué que ça..
    Citation Envoyé par RT222 Voir le message
    Y a t-il un moyen de contourner ce problème? Ou devrais-je plutôt envisager d'encapsuler l'API Win32 directement au lieu des MFCs?
    oui et ça sera bien plus simple ; par exemple si tu veux faire une classe de ListBox , tu déclares une classe de ListBox et dans le constructeur tu appelles CreateWindow()
    Par contre c'est vrai que pour la gestion des messages ça risque d'être un peu problématique

Discussions similaires

  1. Problème d'affichage des boutons [MFC]
    Par Kermichou dans le forum MFC
    Réponses: 8
    Dernier message: 11/01/2011, 11h04
  2. Problème de gestion des langues avec MFC
    Par Figaro dans le forum Visual C++
    Réponses: 4
    Dernier message: 20/11/2006, 15h56
  3. Réponses: 3
    Dernier message: 06/10/2005, 16h46
  4. Réponses: 1
    Dernier message: 06/03/2003, 11h57
  5. Problème de compréhension des ensembles
    Par Cornell dans le forum Langage
    Réponses: 6
    Dernier message: 07/02/2003, 22h07

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo