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 :

Faire dessiner un contrôle par son container


Sujet :

MFC

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    20
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Janvier 2005
    Messages : 20
    Points : 16
    Points
    16
    Par défaut Faire dessiner un contrôle par son container
    Bonjour!

    J'ai des centaines de petits contrôles que j'aimerais dessiner à travers un memDC, au moment où je dessine leur container.

    Pour cela, je crée le memDC dans le container et j'appelle le OnDraw de chaque contrôle.

    Cependant, le OnPaint de mes contrôles est toujours actifs! J'ai essayé de ne pas trapper l'événement, mais c'est le OnPaint de CWnd qui doit être appelé. J'ai aussi essayé de faire une fonction vide, mais à ce moment là je perds mes timers. J'ai ensuite essayé de mettre SetRedraw(false), mais ça bloque la fenêtre et je n'ai plus les événements qui y sont liés.

    Si je crée un CPaintDC, ou si j'appelle BeginPaint et EndPaint dans le OnPaint, ça fonctionne, mais c'est au moins 3 fois plus lent (et déjà qu'en optimisant, ça prend tout près de 5 secondes par affichage...)

    Est-ce qu'il y a un moyen plus rapide de faire cela? Peut-être je ne suis même pas dans la bonne direction, je n'ai pas trop l'habitude...

    Merci de m'éclairer un brin sur la chose!

  2. #2
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    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 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Tu peux essayer d'utiliser ValidateRect() sur tes contrôles pour empêcher qu'ils se redessinent
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    20
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Janvier 2005
    Messages : 20
    Points : 16
    Points
    16
    Par défaut
    Je cherchais en effet un truc comme ça (pourquoi ils n'ont pas appelé ça SetUpdateRect ?? ou ils auraient au moins pu mettre un lien de GetUpdateRect à ValidateRect... en tout cas, c'est pas ici qu'on va régler ça )

    Malheureusement, j'obtiens le même résultat qu'avec SetRedraw(false).

  4. #4
    Membre à l'essai
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    20
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Janvier 2005
    Messages : 20
    Points : 16
    Points
    16
    Par défaut
    Finalement, après plus ample observation, ça fonctionne...
    Il faut être patient par contre, car le OnMouseMove est "dégelé" après tout près de 10 secondes...

    D'autres idées qui pourraient faire avancer le problème un peu plus près de la solution?

  5. #5
    Rédacteur
    Avatar de farscape
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2003
    Messages
    9 055
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

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

    Informations forums :
    Inscription : Novembre 2003
    Messages : 9 055
    Points : 17 323
    Points
    17 323
    Par défaut
    il vaudrait mieux que ce soit le controle qui gere son affichage en memoire pour un repaint plus rapide.
    si c'est ça le sujet bien sur...

  6. #6
    Membre à l'essai
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    20
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Janvier 2005
    Messages : 20
    Points : 16
    Points
    16
    Par défaut
    Le fait est qu'il y a énormément de contrôles et que, lorsqu'on les laisse se dessiner par eux même, ils apparaissent un à la fois, c'est long et c'est visuellement un peu étrange.

    D'où l'idée d'utiliser le container (qui est en soi un autre contrôle) comme "super contrôle" et de concentrer tout le boulot dedans. Le memDC sert à accélérer l'affichage, puisqu'on n'a pas besoin d'afficher réellement chaque contrôle un à un.

    En fait, ce sont les contrôles qui se dessinent eux-même, mais pas par le OnPaint, mais plutôt par le OnDraw (pour utiliser le même DC que le contrôle parent)

    Il doit bien y avoir un moyen pour faire ça efficacement, non?

  7. #7
    Rédacteur
    Avatar de farscape
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2003
    Messages
    9 055
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

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

    Informations forums :
    Inscription : Novembre 2003
    Messages : 9 055
    Points : 17 323
    Points
    17 323
    Par défaut
    mais (peut etre ) que ton interface n'est pas adaptée ...
    autant de controle me semble suspect pour une ihm.
    des fois il y a d'autres alternatives ...

  8. #8
    Membre à l'essai
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    20
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Janvier 2005
    Messages : 20
    Points : 16
    Points
    16
    Par défaut
    Dans le meilleur des mondes, je devrais probablement créer mon super contrôle de façon à ce qu'il n'ait pas besoin d'instancier tout ces petits contrôles, mais c'était une façon plus simple de faire les choses.

    Comme le cas que je teste présentement est un cas un peu extrême, j'avoue que l'interface ne semble pas appropriée, mais j'ai réellement besoin de toutes ces zones réactives, que ce soit sous forme d'un super contrôle ou de centaines de petits contrôles. En temps normal, j'ai probablement une moyenne qui joue entre 10 et 20 petits contrôles pour un super contrôle, ce qui rend les choses pas mal plus simples.

    Parfois la vie nous porte à faire d'étranges choses

  9. #9
    Rédacteur
    Avatar de farscape
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2003
    Messages
    9 055
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

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

    Informations forums :
    Inscription : Novembre 2003
    Messages : 9 055
    Points : 17 323
    Points
    17 323
    Par défaut
    quelle est la nature des contrôles utilisés ?

  10. #10
    Membre à l'essai
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    20
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Janvier 2005
    Messages : 20
    Points : 16
    Points
    16
    Par défaut
    Simplement un contrôle dérivé d'un CWnd, une bande rectangulaire, de longueur variable (très petit dans mon cas extrême), qui est coloré d'une certaine couleur et affiche un titre. Lorsque la souris passe au dessus, on affiche de l'information relative à ce qu'elle représente, selon le cas. On peut aussi effectuer un clique droit sur certaine d'entre elles pour accéder à d'autres options (ouvre un menu contextuel)

    C'est principalement à cause des deux derniers points que j'utilise des contrôles distincts, c'est plus facile à manipuler quand on en a beaucoup, du moins ça l'était

  11. #11
    Rédacteur
    Avatar de farscape
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2003
    Messages
    9 055
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

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

    Informations forums :
    Inscription : Novembre 2003
    Messages : 9 055
    Points : 17 323
    Points
    17 323
    Par défaut
    hum a mon avis un grid pourrait faire l'affaire...
    regard ça :
    http://www.codeproject.com/miscctrl/gridctrl.asp

  12. #12
    Membre à l'essai
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    20
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Janvier 2005
    Messages : 20
    Points : 16
    Points
    16
    Par défaut
    Non, parce qu'un grid, comme son nom l'indique, est une grille.
    Moi j'ai des contrôles qui se retrouvent aligner sur des lignes, c'est vrai, mais pas sur des colonnes...
    Je vais cependant jeter un coup d'oeil sur la façon qu'il s'y prend pour travailler avec les cellules.
    Je vous tiens au courant aussitôt que j'ai trouvé le temps pour analyser tout ça.

    Merci.

  13. #13
    Rédacteur
    Avatar de farscape
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2003
    Messages
    9 055
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

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

    Informations forums :
    Inscription : Novembre 2003
    Messages : 9 055
    Points : 17 323
    Points
    17 323
    Par défaut
    si je peux permettre une suggestion,
    peut etre que tu devrais gerer ça comme des dessins uniquement et pas des controles.
    tu fait une classe de dessin qui connait ses coordonnées .
    tu rajoutes la méthode de dessin couleur etc sur la region de la dialogue.
    un methode hittest qui recoit des coordonnées souris pour savoir si l'objet contient le point.
    et tu maintiens le tout dans une collection style CArray ou vector.
    en gros ça change pas grand chose au reste sauf que ce n'est pas un controle...
    le dessin de l'ensemble se faisant dans ondraw en cas de repaint ,ou a la demande pour un controle ou l'ensemble..


  14. #14
    Membre à l'essai
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    20
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Janvier 2005
    Messages : 20
    Points : 16
    Points
    16
    Par défaut
    J'ai finalement réglé mon problème. C'était tout bête en fait: puisque je faisais dessiner mes contrôles à l'extérieur de l'utilisation du CPaintDC des contrôles, il y avait tout un tas de WM_ON_PAINT qui étaient envoyés, ce qui créait un embouteillage dans la file de messages.

    J'ai simplement désactivé le redraw (SetRedraw) pendant que je redessinait le contrôle (ce qui l'empêche d'envoyer un paquet de WM_ON_PAINT) et validé le contrôle (pour sauver un autre message au moment ou je réactive le redraw).

    Résultat: près de 6000 contrôles dessinés en moins de 10 secondes (et il y a du processing à l'intérieur) Quand les contrôles se dessinaient par eux-même, ça prenait plus du double.

    Considérant que c'est un cas limite, je pense bien que ce sera suffisant.

    Cependant, je considère tout de même faire une refonte de l'application avec des régions qui seraient en fait des CRect plutôt que des CWnd, mais il faut quand même que je vérifie si ce sera efficace avec 6000 éléments. J'y avais déjà songé pour éviter de dépasser la limite de handles disponibles, puis j'avais mis l'idée de côté en apprenant que la limite passait à 65536 sur Win64. Comme ça demande pas mal de changements et que l'affichage n'était pas prioritaire, on verra ça en temps et lieu.

    Merci bien pour le coup de main!

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [Lazarus] Faire passer un contrôle par une procédure
    Par Ardely dans le forum Lazarus
    Réponses: 2
    Dernier message: 17/06/2011, 16h10
  2. remplir la scene par son container principal
    Par wadison dans le forum JavaFX
    Réponses: 6
    Dernier message: 23/08/2010, 17h52
  3. [C#] Comment accéder à un contrôle par son nom ?
    Par km3l3on dans le forum Windows Forms
    Réponses: 4
    Dernier message: 01/06/2010, 19h34
  4. Réponses: 4
    Dernier message: 16/10/2006, 14h12

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