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

Windows Discussion :

Fenetres et ressources partagées


Sujet :

Windows

  1. #1
    Membre éclairé
    Avatar de buzzkaido
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juillet 2004
    Messages
    821
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2004
    Messages : 821
    Points : 734
    Points
    734
    Par défaut Fenetres et ressources partagées
    Bonjour,

    Voila, dans mon appli, je peux ouvrir plusieurs fenetres.

    Toutes ces fenetres sont des instances d'une même classe, et l'utilisateur peut en ouvrir un nombre indeterminé (autant qu'il le souhaite, ou presque)

    Donc, pour economiser la mémoire, j'ai créé une classe "skin" qui contient toutes les images, polices de caractères, etc pour une fenetre.

    Et j'ai déclaré une instance statique de cette classe, qui est utilisée par toutes les fenetres.

    Or, après quelques bugs et un peu d'investigation, je vient de comprendre d'une meme bitmap (par exemple) ne peut etre selectionnée dnas plus d'un DC à la fois.

    Or, il arrive que deux fenetres essaient de se dessiner en même temps avec la même bitmap... donc erreur !


    1/ vu que j'ai environ 3 Mo de données (graphique...) par fenetre, qu'il est prevu dans une uitilisation "normale" d'ouvrir 4-5 fenetres à la fois, est-ce que ça vaut vraiment le coup de partager les ressources pour economiser 12 Mo ?

    2/ comment faire pour partager proprement les ressources ? Y-a-t-il un autre moyen que de proteger les "SelectObject" par des Mutex ou autre ?

  2. #2
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 382
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 382
    Points : 41 590
    Points
    41 590
    Par défaut
    Tu peux toujours partager les DC Mémoire contenant les bitmaps. C'est ce que je conseillerais de faire: Des DC ayant la même durée de vie que les bitmaps eux-mêmes...

  3. #3
    Membre éclairé
    Avatar de buzzkaido
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juillet 2004
    Messages
    821
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2004
    Messages : 821
    Points : 734
    Points
    734
    Par défaut
    Euh, je ne suis pas tres sûr de bien comprendre...

    Actuellement, j'utilise un seul DC (hdcSource) comme source de tous mes BitBlt, quand je veux dessiner une bitmap, je fais :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    SelectObject(hdcSource, hBitmap);
    BitBlt(hdcBackBuffer, hdcSource);
    1/ Tu veux dire que je devrais créer un hdcSource par Bitmap ?
    2/ Ou que je devrais utiliser le même hdcSource pour toutes mes fenetres ?

    Parceque, pour 1 il me semble que ça fait beaucoup de DC à créer, non ?
    Pour 2, le probleme est le même puisque la fenetre 1 peut selectionner une bitmap pour la dessiner et pendant ce temps la fenetre 2 en selectionne une autre...

  4. #4
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 382
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 382
    Points : 41 590
    Points
    41 590
    Par défaut
    Je pense que oui, 1.
    De toute façon, ce qui prend le plus de place dans un MemoryDC, c'est le bitmap...
    N'oublie pas de garder sous la main, pour chaque DC, le handle du bitmap d'origine, car il faut le restaurer avant de détruire le DC. Mais ce bitmap n'est pas encombrant non plus, c'est toujours un bitmap 1x1 monochrome...

    PS: Tu ne devrais pas avoir de problème de "fenêtre qui dessine en même temps qu'une autre" si tes fenêtres sont toutes sur le même thread...

  5. #5
    Membre éclairé
    Avatar de buzzkaido
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juillet 2004
    Messages
    821
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2004
    Messages : 821
    Points : 734
    Points
    734
    Par défaut
    Ok, donc je vais créer un memoryDC pour chaque bitmap qui est chargée.

    PS: Tu ne devrais pas avoir de problème de "fenêtre qui dessine en même temps qu'une autre" si tes fenêtres sont toutes sur le même thread...
    J'avoue que je ne me suis pas trop posé la question...

    Voici comment ça marche :

    Dans mon appli, je fait un CreateWindowEx pour créer la fenetre principale.

    Dans la boucle de messages de cette fenetre, je crée les fenetres "secondaires" avec aussi un CreateWindowEx.

    A aucun moment je ne lance de thread separés.. je suppose danc que toutes mes fenetres sont dans le même thread, non ?

    Si c'est le cas, pourquoi j'ai des soucis de partage des ressources ?

  6. #6
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 382
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 382
    Points : 41 590
    Points
    41 590
    Par défaut
    Pour commencer, j'ai du mal à comprendre comment tu peux te rendre compte qu'un bitmap ne peut être sélectionné dans plusieurs DCs si tu n'en utilises qu'un seul.

    Ensuite, si tu en utilises en vérité un par fenêtre, vérifie que le bitmap n'y est associé que pendant le dessin. Les fenêtres ne dessineront pas en même temps, mais si une association persiste hors du dessin, problème...

    Et surtout, fais gaffe si tu utilises des MessageBox() : Elles ont le défaut de contenir une boucle de messages, qui peut permettre des trucs à des moments où ils ne sont pas censés arriver.

  7. #7
    Membre éclairé
    Avatar de buzzkaido
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juillet 2004
    Messages
    821
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2004
    Messages : 821
    Points : 734
    Points
    734
    Par défaut
    En fait, j'utilise un DC "source" par fenetre.

    Ce DC "source" me sert à selectionner une bitmap dedans pour la "BitBlter" sur l'ecran (un backbuffer en fait).

    J'ai donc bien autant de DC dans lesquels je selectionne les bitmaps que j'ai de fenetres.

    Par contre, je n'utilise aucun MessageBox() ou autre.

    Toutes mes fenetres sont créées avec CreateWindowEx, avec les mêmes parametres et la même classe.

    Et surtout, fais gaffe si tu utilises des MessageBox() : Elles ont le défaut de contenir une boucle de messages, qui peut permettre des trucs à des moments où ils ne sont pas censés arriver.
    Peux-tu préciser ?
    Si elles ont leur propre boucle de messages mais sont executées dans le même thread, il ne peut y avoir qu'un message traité à la fois, non ?

  8. #8
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 382
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 382
    Points : 41 590
    Points
    41 590
    Par défaut
    Le problème des MessageBox(), c'est que si tu en utilises une PENDANT le traitement d'un message, la fenêtre peut recevoir des messages pendant que la MessageBox() est affichée.

    Donc, tu peux recevoir des messages pendant le traitement d'un autre, d'où le haut potentiel pour des problèmes de réentrance. C'est pire que les problèmes de thread-safety.

  9. #9
    Membre éclairé
    Avatar de buzzkaido
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juillet 2004
    Messages
    821
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2004
    Messages : 821
    Points : 734
    Points
    734
    Par défaut
    Ok, je comprend mieux.

    Par contre, si dans une fenetre 1 je crée une nouvelle fenetre 2 avec CreateWindowEx pendant le traitement d'un message, la fenetre 1 peut aussi recevoir des messages pendant que la fenetre 2 est affichée ?

  10. #10
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 382
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 382
    Points : 41 590
    Points
    41 590
    Par défaut
    CreateWindowEx() ne contient pas de boucle de messages, donc aucune fenêtre ne recevra de "message posté" pendant le traitement: Les seuls messages reçus par la fenêtre 1 seront ceux explicitement envoyés avec SendMessage() (dans le traitement des messages WM_CREATE etc. de la fenetre 2) ou d'autres du type WM_PARENTNOTIFY etc.

  11. #11
    Membre éprouvé
    Avatar de NiamorH
    Inscrit en
    Juin 2002
    Messages
    1 309
    Détails du profil
    Informations forums :
    Inscription : Juin 2002
    Messages : 1 309
    Points : 1 051
    Points
    1 051
    Par défaut
    A part ça, ça fonctionne bien le skin de fenetres avec des bitmaps ? Parce que je vais pas tarder à me pencher sur le sujet.

    Pour info, a quel point tu skin ton appli ? tu applique aussi sur les boutons, controls ? Je serais curieux de voir comment tu gère ça.

  12. #12
    Membre éclairé
    Avatar de buzzkaido
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juillet 2004
    Messages
    821
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2004
    Messages : 821
    Points : 734
    Points
    734
    Par défaut
    NiamorH : oui, ça fonctionne bien.

    J'ai juste quelques soucis avec plusieurs fenetres ouvertes à la fois car elles partagent les mêmes ressources.

    Je skin tous les controles de mon application.

    En fait, je n'utilisent que des controles personnalisés.

    Chaque controle integre un parametre "modele" qui est un entier. C'est l'indice dans un tableau de bitmaps.

    En gros ça donne ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    enum
    {
       SKIN_BOUTON FERMER = 0;
       SKIN_BOUTON OK,
       SKIN_BOUTON ANNULER,
       ...
    }
    Dans le constructeur de ma classe cSkin, je charge toutes les bitmap, brosses, polices...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    cSkin::cSkin()
    {
        m_bitmap[SKIN_BOUTON FERMER] = chargeBitmap("uneImage.bmp");
        m_bitmap[SKIN_BOUTON OK] = chargeBitmap("uneImage.bmp");
        m_bitmap[SKIN_BOUTON ANNULER] = chargeBitmap("uneImage.bmp");
        ...
        m_brosse[SKIN_BROSSE_FOND_FENETRE] = CreateSolidBrush(....);
    }
    Et dans les fonctions de dessin des controles, j'utilise, par exemple pSkin->m_bitmap[modele] pour dessiner le bouton.

    Je crée une seule instance de la classe cSkin et tous les controles en connaissent l'adresse.

    La prochaine étape, une fois que tout marchera, sera de changer le constructeur de la classe cSkin pour ne pas charger des noms d'image "en dur" mais des noms lus dans un fichier XML et ainsi pouvoir éditer les skins.

  13. #13
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 382
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 382
    Points : 41 590
    Points
    41 590
    Par défaut
    Tes "contrôles personnalisés", ils ont quand même un HWND ou tu fais du WindowLess ?

    Tu pourrais montrer un screenshot comme exemple ?

    PS: Comme truc skinné en WindowLess, j'avais bien aimé celui-ci:
    http://www.developpez.net/forums/sho...d.php?t=266467
    Mais il était complètement à l'état embryonaire et les appels de fonction ont été un peu dénaturés au cours des tentatives de débogage...

    J'ai aussi pas mal discuté avec Kidpaddle2 au sujet de contrôles WindowLess...

  14. #14
    Membre éclairé
    Avatar de buzzkaido
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juillet 2004
    Messages
    821
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2004
    Messages : 821
    Points : 734
    Points
    734
    Par défaut
    Je fais du "windowless"

    En fait, je crée une fenetre avec un CreateWindowEx.

    Ensuite, dans sa boucle de message, je transforme les differents messages (souris, clavier...) et les envoie avec mon propre système evenementiel.

    Chaque composant dérive d'une classe mère (même la fenetre) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    class cComposant
    {
        void dessiner(cContexteGraphique *pContexteGraphique);
        bool traiterEvenement(cGuiEvenement *pEvenement);
        void majAffichage (cGuiSurface *pSurface=NULL);
        etc...
    }
    Le but étant de pouvoir rendre le code compatible avec du MAC et du LINUX.

    La compatibilité MAC est déjà partielle, LINUX à venir.

    Ma classe cContexteGraphique contient u pointeur vers la skin, un hdc "temporaire" servant de source aux copies de bitmap sur un hdc "backBuffer".

    Voila en substance l'essentiel du truc.

    L'ensembler marche tres bien, j'ai juste un souci au niveau du partage des ressources. Je pense que c'est notamment parceque je ne maitrise pas vraiement les boucles de messages de Windows.

    Vu que tout ça s'integre dans un SDK servant à créer des plugins sous forme de DLL, et qui crée lui-même sa fenetre de façon indépendante de ma volonté, j'ai même parfois du mal à savoir dans quel thread je me trouve vraiement....

    Bref un peu le bordel, mais ça commence à rouler serieusement.

    Pour les screenshot, désolé, mais non, le projet étant tres peu aboutit graphiquement (pour l'instant, c'est essentiellement à base de gros carrés pour vérifier que ça se dessine bien au bon endroit).

    Mais on peut d'ores et déjà configurer toutes les couleurs, polices, brosses de remplissage et bitmap utilisées.

  15. #15
    Membre éclairé
    Avatar de buzzkaido
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juillet 2004
    Messages
    821
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2004
    Messages : 821
    Points : 734
    Points
    734
    Par défaut
    Medinoc : je viens de relire le post que tu as mis en lien.

    C'est du même genre (ce post m'avait aidé à dessiner le titre et les bordures personnalisées)

    Mais en plus complet.

    Y'a des boutons, des onglets, des conteneurs, des boutons 3 états, des saises de textes, des saisies de valeurs numériques, des barres de défilement, des manipulation de courbes graphiques (genre de béziers) des menus déroulants, des listes, des explorateurs de ressources sous forme d'arbre etc...

  16. #16
    Membre éprouvé
    Avatar de NiamorH
    Inscrit en
    Juin 2002
    Messages
    1 309
    Détails du profil
    Informations forums :
    Inscription : Juin 2002
    Messages : 1 309
    Points : 1 051
    Points
    1 051
    Par défaut
    Par windowless, vous voulez dire que seule la fenetre est créée avec createwindow/ex et tous les controls sont créés de maniere 'abstraite' et leur interaction déduite des evenements souris sur la fenetre parente ? J'avais pensé me tourner vers ce genre de solution à l'époque ou je faisait du VB.Net mais les perfs étaient déplorables.
    Si tu me dis que ça marche bien je referais bien l'essai en C++.
    C'est vrai que c'est le mieux pour la portabilité.

  17. #17
    Membre éclairé
    Avatar de buzzkaido
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juillet 2004
    Messages
    821
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2004
    Messages : 821
    Points : 734
    Points
    734
    Par défaut
    Pour ma part, c'est à ce sens là que je l'entend.

    Pour les perfs, ça m'a l'air tout à fait honorable...

    Et avant de me lancer la-dedans, j'ai regardé differentes API en C++, j'en ai trouvé plusieurs qui utilisent ce système...

  18. #18
    Membre éprouvé
    Avatar de NiamorH
    Inscrit en
    Juin 2002
    Messages
    1 309
    Détails du profil
    Informations forums :
    Inscription : Juin 2002
    Messages : 1 309
    Points : 1 051
    Points
    1 051
    Par défaut
    Par curiosité, tu te rapelles lesquelles ?

    (Ca me redonne envie de me lancer dans un framework )

    Par ce que deriver un wmPaint j'avoue que ça me plait pas.

  19. #19
    Membre éclairé
    Avatar de buzzkaido
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juillet 2004
    Messages
    821
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2004
    Messages : 821
    Points : 734
    Points
    734
    Par défaut
    La pluspart concerne les plugins VST :

    VSTGui
    InfinityAPI
    ...

  20. #20
    Membre éprouvé
    Avatar de NiamorH
    Inscrit en
    Juin 2002
    Messages
    1 309
    Détails du profil
    Informations forums :
    Inscription : Juin 2002
    Messages : 1 309
    Points : 1 051
    Points
    1 051
    Par défaut
    Tu touches un peu aux VST aussi ? Moi je les utilise mais j'ai pas encore étudié le SDK.
    Ok ben dès que ton gui commence à prendre forme donne nous des nouvelles et poste quelques screens.

Discussions similaires

  1. Architecture et ressources partagées
    Par Invité dans le forum ASP.NET
    Réponses: 4
    Dernier message: 19/01/2009, 15h44
  2. Threads et ressource partagée !
    Par myryad dans le forum Concurrence et multi-thread
    Réponses: 3
    Dernier message: 19/06/2008, 14h28
  3. Ressources partagées entre projets
    Par fterf dans le forum C#
    Réponses: 3
    Dernier message: 03/01/2008, 12h32
  4. Réponses: 2
    Dernier message: 22/12/2006, 11h38
  5. [Réseau][ressource partagée]Autentification
    Par heid dans le forum API, COM et SDKs
    Réponses: 7
    Dernier message: 12/11/2003, 17h00

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