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 :

[MFC] Animation dans une vue


Sujet :

MFC

  1. #1
    Membre confirmé Avatar de Philippe320
    Profil pro
    Inscrit en
    Novembre 2005
    Messages
    179
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2005
    Messages : 179
    Par défaut [MFC] Animation dans une vue
    Bonjour,

    voici schématiquement ce que je veux réaliser :

    j'ai mon appli avec ma vue CMaVue, qui contient une variable BOOL fondFige, initialisée depuis l'extérieur, et une surcharge de OnDraw :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    CMaVue::OnDraw(CDC* dc) {
     
    if (!fondFige) { AffichageFondVue(dc);
                          SauvegardeVue(dc);
    } //if
    else { RestaurationVue(dc);
              AffichageSprite(dc);
    } //else
     
     
    } //OnDraw
    Je veux animer un genre de sprite (souvenirs, souvenirs, comme sur Amiga) grace à AffichageSprite(dc), mais comme AffichageFondVue(dc) est long et complexe, je ne veux pas tout redessiner à chaque vue:

    donc je mets fondFige à TRUE pour n'avoir qu'à plaquer le fond de la vue, précédemment sauvegardée par SauvegardeVue(dc) et réaffichée par RestaurationVue(dc), et pour n'appeler ensuite que AffichageSprite.

    J'espère que je suis à peu près clair ...

    Ma question est :
    que mettre dans SauvegardeVue(dc) et RestaurationVue(dc) ?

    merci d'avance de m'aider, le fonctionnement du CDC n'est pas clair pour moi ...
    Philippe

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 394
    Par défaut
    Pour moi, tu dois créer un DC et un bitmap compatibles avec le DC passé en paramètre (et le bitmap doit avoir la bonne taille), et recopier le tout avec BitBlt().

    Et évidemment, DC et Bitmap doivent être persistants...
    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 confirmé Avatar de Philippe320
    Profil pro
    Inscrit en
    Novembre 2005
    Messages
    179
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2005
    Messages : 179
    Par défaut
    Bonsoir,

    je vois en gros de quoi tu veux parler (fonctions CreateCompatibleDC et CreateCompatibleBitmap), mais de là à les utiliser correctement ...

    je continue à chercher, mais une aide plus précise m'aiderait beaucoup

    merci d'avance
    Philippe

  4. #4
    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
    Par défaut
    salut,
    tu as un exemple d'utilisation dans la faq:
    http://c.developpez.com/faq/vc/?page...TreeCtrlCustom
    ici on laisse le controle se dessiner dans un bitmap en memoire .
    puis on modifie le dessin et enfin on projette sur l'écran le bitmap (bitblt).


  5. #5
    Membre confirmé Avatar de Philippe320
    Profil pro
    Inscrit en
    Novembre 2005
    Messages
    179
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2005
    Messages : 179
    Par défaut
    Salut,

    alors, j'ai étudié ce code, et voilà ce que j'ai fait :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
     
     
    // variable globale de la vue (dans CMaVue.h)
    CDC memDC2;              // c'est le CDC de sauvegarde
    CRect rcClient;
     
    CMaVue::OnDraw(CDC* dc) {
    CDC memDC;
     
    // creation d'un DC en memoire .
    memDC.CreateCompatibleDC( dc );
    GetClientRect(&rcClient);
    CBitmap bitmap;
    bitmap.CreateCompatibleBitmap( dc, rcClient.Width(), rcClient.Height() );
     
     
    if (!fondFige) { AffichageFondVue(&memDC);
                          SauvegardeImageFond(&memDC);
                          RestaurerImageFond(dc);
    } //if
    else { RestaurationImageFond(dc);
              AffichageSpriteMobile(dc);
     
    } //else
     
    } //OnDraw
     
    //_____________________________________________________________________________
    void CMaVue::SauvegarderImageFond(CDC *memDC) {
     
    memcpy(&memDC2,memDC,sizeof(CDC) );
     
    } //proc
     
    //_____________________________________________________________________________
    void CMaVue::RestaurerImageFond(CDC *pDC) {
     
    pDC->BitBlt( rcClient.left, rcClient.top, rcClient.Width(), 
               rcClient.Height(), &memDC2, 0,0, SRCCOPY );
     
    } //proc
    1er cas: fondFige = FALSE;
    tout fonctionne : l'image de fond se dessine grace à AffichageFondVue dans le memDC, et s'affiche en une fois depuis le memDC2 (DC de sauvegarde) car SauvegarderImageFond a fait une copie de memDC dans memDC2 (donc le principe de sauvegarde du memDC fonctionne) ; mon sprite se déplace à l'écran (pour mémoire, certes ça fonctionne, mais comme AffichageFondVue est complexe, je voulais ne réafficher que le sprite sur un fond sauvegardé)

    2ème cas: fondFige = TRUE:
    j'ai l'image de fond (identique à la précédente) et mon sprite qui s'affiche EN LAISSANT DES TRACES (c'est ce que je veux pas !). Or, je devrais avoir l'image de fond et un seul sprite mobile, car j'ai restauré le memDC2 (image de fond sauvegardée, vierge en quelque sorte) sur laquelle j'ai affiché le sprite à sa nouvelle position.

    Moi y'en a rien comprendre du tout
    Qu'en penses tu ?

    Philippe

  6. #6
    mat.M
    Invité(e)
    Par défaut
    Citation Envoyé par Philippe320
    Moi y'en a rien comprendre du tout
    Qu'en penses tu ?

    Philippe
    Par analogie avec les surfaces de Direct Draw( composante de Direct X) il vaut mieux dessiner chaque éléments en "calques" séparés les calques étant des HDC en mémoire..
    Plutot que de déclarer un CDC memDC on fait une "pile" de CDC :

    CArray <CDC,CDC> m_tabCDC;
    Ou bien avec CObArray, COblist

    Dans le OnDraw il suffit de copier les "calques" les uns sur les autres.
    Regarde l'aide sur CArray dans le MSDN
    Sinon tu peux prendre aussi les conteneurs de la STL std::vector , std::list...

    Pour de meilleurs performances je suggérrais SDL bien que parfois avec le GDI c'est aussi rapide que SDL...

  7. #7
    Membre confirmé Avatar de Philippe320
    Profil pro
    Inscrit en
    Novembre 2005
    Messages
    179
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2005
    Messages : 179
    Par défaut
    Bonjour,

    d'accord pour le principe des piles de CDC avec CArray:
    ça, j'y arrive car pour 1 comme pour 10, je sais écrire dans un CDC et ensuite l'afficher sur le CDC "courant" (c'est ce que je fais avec memDC dans mon code précédent): avec un tableau de memDC, ce serait pareil.

    Mais mon problème est en fait : une fois que j'ai tout plaqué (Bitblt) sur le CDC de la vue, comment sauvegarder cette "image" pour pouvoir simplement la "re-plaquer" lors d'un prochain affiichage ?

    Dans le code précédent, j'ai copié (memcpy) le CDC dans un CDC de sauvegarde (memDC2), mais ça ne fonctionne pas.

    J'ai tenté de sauvegarder bitmap dans un CBitmap bitmap2; en variable globale à la vue (histoire de ne pas le perdre), mais sans succès ...

    comment faire alors ?
    merci d'avance
    Philippe

  8. #8
    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
    Par défaut
    et bien il suffit de garder le bitmap en memoire en tant que donnée membre de la classe...
    globalement:
    pour le fond:
    dans un cas (la creation ou la mise a jour) tu constitus le bitmap puis le projette.
    dans les autres tu le projette directement..


  9. #9
    Membre confirmé Avatar de Philippe320
    Profil pro
    Inscrit en
    Novembre 2005
    Messages
    179
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2005
    Messages : 179
    Par défaut
    Bonjour Farscape,

    et bien il suffit de garder le bitmap en memoire en tant que donnée membre de la classe...
    ouais... mais si je met bitmap en variable globale de la classe, il me jette car il veut une variable locale pour exécuter le
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    bitmap.CreateCompatibleBitmap( dc, rcClient.Width(), rcClient.Height() );
    donc j'ai un CBitmap bitmap2; en globale et je fais un
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    memcpy(&bitmap2,&bitmap,sizeof(CBitmap) );
    pour "garder" le bitmap comme tu dis.

    Est-ce très orthodoxe de pratiquer comme ça ?

    Ensuite, en espérant que le bitmap2 contiennent bien une image du fond,
    comment le plaquer sur le DC courant ?
    j'ai essayé un
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    	memDC.SelectObject(&bitmap2);
    	dc->BitBlt( rcClient.left, rcClient.top, rcClient.Width(), 
               rcClient.Height(), &memDC, 0,0, SRCCOPY );
    mais ça ne fonctionne pas ...

    Comme tu vois, j'essaie d'y mettre du mien, mais je galère vraiment ...
    Philippe

  10. #10
    Membre confirmé Avatar de Philippe320
    Profil pro
    Inscrit en
    Novembre 2005
    Messages
    179
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2005
    Messages : 179
    Par défaut
    pour être plus clair, voici où j'en suis de mon code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
     
     
    // variable globale de la vue (dans CMaVue.h)
    CBitmap bitmap2;              // c'est le bitmap de sauvegarde
    CRect rcClient;
     
    CMaVue::OnDraw(CDC* dc) {
    CDC memDC;
     
    // creation d'un DC en memoire .
    memDC.CreateCompatibleDC( dc );
    GetClientRect(&rcClient);
    CBitmap bitmap;
    bitmap.CreateCompatibleBitmap( dc, rcClient.Width(), rcClient.Height() );
    memDC.SelectObject(&bitmap);
     
    if (!fondFige) { AffichageFondVue(&memDC);
                         //Afficher le memDC
                        dc->BitBlt( rcClient.left, rcClient.top, rcClient.Width(), 
                                      rcClient.Height(), &memDC, 0,0, SRCCOPY );
                        // Sauvegarde du bitmap de fond
                          memcpy(&bitmap2,bitmap,sizeof(CDC) ); 
     
     
    } //if
    else { 
     // Restauration du bitmap de fond
    	memDC.SelectObject(&bitmap2);
    	dc->BitBlt( rcClient.left, rcClient.top, rcClient.Width(), 
               rcClient.Height(), &memDC, 0,0, SRCCOPY );
     
              AffichageSpriteMobile(dc);
     
    } //else
     
    } //OnDraw

  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
    Par défaut
    salut,
    ouch ,pas de memcpy sur des objets !
    pour cette ligne
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    bitmap.CreateCompatibleBitmap( dc, rcClient.Width(), rcClient.Height() );
    il suffit de tester que le bitmap n'est pas créé :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    if(!static_cast<HBITMAP>(m_bitmap))
         m_bitmap.CreateCompatibleBitmap( dc, rcClient.Width(), rcClient.Height() );
    si le bitmap est deja créé pas besoin de createCompatibleBitmap....

  12. #12
    Membre confirmé Avatar de Philippe320
    Profil pro
    Inscrit en
    Novembre 2005
    Messages
    179
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2005
    Messages : 179
    Par défaut
    CA MARCHE !!!

    qu'est ce que j'aurai galéré sur ce bout de code !!
    Encore merci Farscape

    Philippe

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

Discussions similaires

  1. Réponses: 6
    Dernier message: 14/12/2004, 02h47
  2. Insérer dans une Vue ordonnée
    Par biroule dans le forum MS SQL Server
    Réponses: 3
    Dernier message: 27/09/2004, 15h27
  3. [mfc] affichage dans une boite de dialog
    Par chronos dans le forum MFC
    Réponses: 3
    Dernier message: 14/06/2004, 15h12
  4. [MFC] Dialog dans une boucle while
    Par oxor3 dans le forum MFC
    Réponses: 5
    Dernier message: 23/04/2004, 22h51
  5. [MFC] CPropertySheet dans une CFormView ???
    Par Lofwyr dans le forum MFC
    Réponses: 2
    Dernier message: 30/07/2003, 16h49

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