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 :

Dessiner un rectangle de fond transparent (2 pb)


Sujet :

MFC

  1. #1
    Membre éclairé
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    759
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 759
    Par défaut Dessiner un rectangle de fond transparent (2 pb)
    Bonjour,

    Bon, j'en peux plus, j'y arrive pas!
    J'ai une image affichée par OnDraw dans la vue et je veux dessiner par dessus un rectangle de sélection (il se crée en pointillés et au relachement de la souris passe en trais pleins).

    1°/ Je cherche dans la doc depuis un bon moment mais je ne trouve pas de moyen de créér un pinceau transparent pour le fond.

    2°/ Si je dessine le rectangle dans OnDraw, je ne vois pas le style de crayon que j'ai demandé (j'avais avant dessiné le rectangle dans OnMouseMove en créant/sélectionnant le crayon , dessinant le rectangle, et déselectionnat/détruisant le crayon, ce qui a mon avis était pas génial).



    Et voilà le 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
    void CMyProjectView::OnLButtonDown(UINT nFlags, CPoint point)
    {
    	if(!m_ImgView)
    		return;
     
    	m_StartPoint = point;
     
    	m_hpNew = CreatePen(PS_DOT, 1, RGB(0,255,0));
    	m_hpOld = (HPEN)SelectObject(GetDC()->m_hDC,m_hpNew);
    	//m_hbrNew = CreateSolidBrush(!!!!!!!!Transparent!!!!!!!!); //pour l'instant il est blanc, ça me va pas
    	//m_hbrOld =(HBRUSH)SelectObject(hDC,m_hbrNew);
     
    	m_bDrawRect = true;
     
    	CView::OnLButtonDown(nFlags, point);
    }
    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
    void CMyProjectView::OnMouseMove(UINT nFlags, CPoint point)
    {
    	if(!m_ImgView)
    		return;
     
    	//** Position de la souris
    	int xCursor = point.x;
    	int yCursor = point.y;
     
    	//** Si le bouton est enfoncé, on change le point final du rectangle.
    	if((GetAsyncKeyState(VK_LBUTTON) & 0x8000) != 0)
    	{
    		m_EndPoint.x = xCursor;
    		m_EndPoint.y = yCursor;
     
    		//** Redessine l'image avec le nouveau rectangle
    		OnDraw(GetDC());			
    	}
     
    	CView::OnMouseMove(nFlags, point);
    }

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    void CMyProjectView::OnDraw(CDC* pDC)
    {
    	//...
     
    	if(m_bDrawRect)
    			Rectangle(pDC->m_hDC, m_StartPoint.x, m_StartPoint.y, m_EndPoint.x, m_EndPoint.y);	
    }

    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
    void CMyProjectView::OnLButtonUp(UINT nFlags, CPoint point)
    {
    	m_EndPoint = point;
     
    	CDC* pDC = GetDC();
    	HDC hDC = GetDC()->m_hDC;
     
    	//** Changement de style de crayon (plein et épais)
        SelectObject(hDC,m_hpOld);
    	DeleteObject(m_hpNew);
    	m_hpNew = CreatePen(PS_SOLID, 2, RGB(0,255,0));
    	m_hpOld = (HPEN)SelectObject(hDC,m_hpNew);
     
    	OnDraw(pDC);
     
    	//** On se débarasse visuellement du rectangle en cliquant sans déplacer
    	if(m_EndPoint==m_StartPoint)
    	{
    		//SelectObject(hDC,m_m_hbrOld);
    		//DeleteObject(m_hbrNew);
    		SelectObject(hDC,m_hpOld);
    		DeleteObject(m_hpNew);
    		m_bDrawRect = false;
    	}
     
    	CView::OnLButtonUp(nFlags, point);
    }

  2. #2
    Expert confirmé

    Homme Profil pro
    pdg
    Inscrit en
    Juin 2003
    Messages
    5 756
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : pdg

    Informations forums :
    Inscription : Juin 2003
    Messages : 5 756
    Billets dans le blog
    3
    Par défaut
    Si c'est juste les contours du rectangle, tu peux utiliser FrameRect, voire DrawFocusRect pour les pointillés.

  3. #3
    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,
    et un conseil si tu fais des MFC utilises les fonctions de la classe CDC .
    au lieu d'utiliser les api32 avec les HDC et compagnie .
    ça simplifie le code et ça t'evite des erreurs de liberation etc..

  4. #4
    Membre éclairé
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    759
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 759
    Par défaut
    Citation Envoyé par Aurelien.Regat-Barrel
    Si c'est juste les contours du rectangle, tu peux utiliser FrameRect, voire DrawFocusRect pour les pointillés.
    DrawFocusRect ne me convient pas (c'est à peine si on voit les traits, et il n'y a pas de paramètre pour les changer).

    FrameRect est pas mal...mais encore une fois, ça ne me permet pas de tout contrôler (je peux pas avoir de pointillés car elle ne prend comme argument qu'un HBRUSH où on peut juste choisir sa couleur).

    Donc c'est pas exactement ce que je cherche.

    Y a-t-il autre chose, sachant que le top du top, ça serait :
    1°/ choisir la couleur, l'épaisseur et le style du contour (donc un CPen)
    2°/ choisir la transparence pour l'intérieur (ce que je ne sais pas faire) et même le top du top du top, un intérieur presque transparent mais qui modifie un peu la couleur de la zone.




    Citation Envoyé par Farscape
    si tu fais des MFC utilises les fonctions de la classe CDC .
    au lieu d'utiliser les api32 avec les HDC et compagnie
    Ah mais tu sais, j'utilise tout ce que je trouve moi; n'hésite pas à modifier mon code avec le style que tu veux (MFC, API, WIN32...je sais même pas ce que j'utilise, lol)

  5. #5
    Membre éclairé
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    759
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 759
    Par défaut
    :

  6. #6
    Expert confirmé

    Homme Profil pro
    pdg
    Inscrit en
    Juin 2003
    Messages
    5 756
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : pdg

    Informations forums :
    Inscription : Juin 2003
    Messages : 5 756
    Billets dans le blog
    3
    Par défaut
    Et ça donne quoi d'utiliser comme brosse GetStockObject( HOLLOW_BRUSH ) ?

  7. #7
    Membre éclairé
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    759
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 759
    Par défaut
    Citation Envoyé par Aurelien.Regat-Barrel
    Et ça donne quoi d'utiliser comme brosse GetStockObject( HOLLOW_BRUSH ) ?
    Ca donne !

    Donc problème 1 résolu.

    Maintenant, pouvez-vous m'aider à gérer mes sélection, destruction et tout car je ne vois pas trop comment faire ça proprement.
    En effet, si je fais :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    m_hpNew = CreatePen(PS_DOT, 1, RGB(0,0,255));
    m_hpOld = (HPEN)SelectObject(pDC->m_hDC,m_hpNew);
    m_hbrNew = (HBRUSH)GetStockObject(HOLLOW_BRUSH );
    m_hbrOld =(HBRUSH)SelectObject(pDC->m_hDC,m_hbrNew);
    dans OnLButtonDown, et que je fais seulement Rectangle(...) dans OnDraw, il ne prend pas en compte mon crayon et pinceau.
    Pour que ça marche, je dois faire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    m_hpOld = (HPEN)SelectObject(pDC->m_hDC,m_hpNew);
    m_hbrOld =(HBRUSH)SelectObject(pDC->m_hDC,m_hbrNew);
    Rectangle(............);
    Je ne comprend pas car je les avais sélectionnés déjà!

    Ensuite, quand je veux changer de crayon, je fais :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    m_hpNew = CreatePen(PS_DOT, 2, RGB(255,0,0));
    m_hpOld = (HPEN)SelectObject(pDC->m_hDC,m_hpNew);
    Ca va où j'aurais du détruite le crayon avant de refaire un Create?


    Enfin quand je ne veux plus dessiner le rectangle, je fais:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SelectObject(hDC, m_hbrOld);
    DeleteObject(m_hbrNew);
    SelectObject(hDC,m_hpOld);
    DeleteObject(m_hpNew);
    parce que je crois avoir vu que ça se fait comme ça, mais moi j'aurais pensé qu'on ait 4 éléments à détruire et pas 2 (les crayons New et Old et les pinceaux Nex et Old).


    Puis-je savoir exactement quelle est la manière parfaite de procéder?

  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
    si tu utilisais les classes tu ne te poserais ce genre de question ...
    voir classes CDC ,CPen ,CBrush ...

  9. #9
    Membre éclairé
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    759
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 759
    Par défaut
    Citation Envoyé par farscape
    si tu utilisais les classes tu ne te poserais ce genre de question ...
    voir classes CDC ,CPen ,CBrush ...
    Pas de problème, il suffit de me le dire et je change ça.
    Donc CPen *pOldPen, *pNewPen;
    CBrush *pOldBrush, *pNewBrush;

    et quand je veux plus dessiner de rectangle, je fais quoi?
    delete pour les 4?

    Et pour les histoires de sélection, pourquoi j'ai du le refaire dans OnDraw alors que j'avais terminé par un SelectObjetc à la fin de mon OnLButtonDown.

    Je maîtrise mal la compréhension des jongleries entre les éléments Old et New : pourquoi on ne se sert pas d'un seul?

  10. #10
    Membre éclairé
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    759
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 759
    Par défaut
    Bon, au final, tout se résume à ça :

    dans OnLButtonDown et OnLButtonUp, je ne fais que changer les paramètres du stylo et du pinceau.

    Et dans OnDraw, je ne fais que :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    CPen NewPen;
    NewPen.CreatePen(m_iPenStyle, m_iPenSize, m_colorPen);
    pDC->SelectObject(&NewPen);
     
    CBrush NewBrush;
    NewBrush.CreateStockObject(m_iBrushStyle);
    pDC->SelectObject(&NewBrush);
     
    Rectangle(....................);

    1°/ Ca va ou pas? Ca me paraît stupide de recréer les objets de dessin à chaque passage dans OnDraw, ce qui arrive un paquet de fois puisqu'à chaque passage dans OnMouseMove mais impossible de faire autrement.
    De plus, il n'y a pas d'histoire de libération des objets; il faut le faire? Comment?


    2°/ Question bonus (pour le fun) : et si je veux que l'intérieur du rectangle ne soit pas totalement transparent mais qu'il apporte une légère coloration à l'image du dessous, on fait comment?

  11. #11
    Expert confirmé

    Homme Profil pro
    pdg
    Inscrit en
    Juin 2003
    Messages
    5 756
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : pdg

    Informations forums :
    Inscription : Juin 2003
    Messages : 5 756
    Billets dans le blog
    3
    Par défaut
    2/ Je pense qu'il faut créer un bitmap en mémoire d'une couleur donnée (bleu par exemple) et le bliter de manière transparente avec AlphaBlend.
    http://msdn.microsoft.com/library/en-us/gdi/bitmaps_2b00.asp

  12. #12
    Membre éclairé
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    759
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 759
    Par défaut
    Citation Envoyé par Aurelien.Regat-Barrel
    2/ Je pense qu'il faut créer un bitmap en mémoire d'une couleur donnée (bleu par exemple) et le bliter de manière transparente avec AlphaBlend.
    Mince alors, et moi qui aurait souhaité une réponse du genre NewBrush = Brush1&Brush2 où l'une est transparente et l'autre colorée, ou un truc dans le genre.
    Quoi qu'il en soit, merci pour la piste car j'ai recopié le code tel quel et effectivement, j'ai des rectangle de couleur transparents (et dégradés et tout au besoin).

    Reste la question1 (est-ce oui ou non bien ou mal ma méthode), et puis toute suggestion plus simple pour le problème 2 est la bienvenue! lol

  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
    Par défaut
    oui ça va ,
    Le seul reproche tu ne stockes pas les objets précédents sur le selectobjet
    pour les restituer après usage...
    mais tu peux aussi creer tes objets avant:
    en tant que données membre de la classe ,initialisés dans OnInitialUpdate,
    et les utiliser directement dans tes fonctions .
    ils seront alors detruits sur le destructeur de la classe parent ...


  14. #14
    Membre éclairé
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    759
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 759
    Par défaut
    Citation Envoyé par farscape
    Le seul reproche tu ne stockes pas les objets précédents sur le selectobjet
    pour les restituer après usage...
    Tu veux dire :
    Rectangle(.....)
    et terminer par :
    pDC->SelectObject(&NewPen);
    pDC->SelectObject(&NewBrush);

    C'est justement ce genre de chose que j'ai vu écrit ailleurs et je ne voyais pas à quoi ça servait : ça veut dire quoi "restituer après usage" : restituer à qui pour quoi faire puisque si on veut s'en servir on doit refaire un SelectObjet avant le tracé de toutes façons?


    Citation Envoyé par farscape
    mais tu peux aussi creer tes objets avant:
    en tant que données membre de la classe ,initialisés dans OnInitialUpdate,
    et les utiliser directement dans tes fonctions .
    ils seront alors detruits sur le destructeur de la classe parent ...
    Alors là, je ne comprend pas du tout en code ce que ça veut dire parce que les seules fois où j'ai voulu mettre des pointeurs sur mes objets en variavle de ma classe, ça n'a jamais marché (si tu parles bien de variables m_pNewPen et m_pNewBrush à détruire dans le destructeur de ma vue).

  15. #15
    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
    si tes couleurs sont fixes tu peux tres bien avoir ça:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    // CBrush m_NewBrush;
    // CPen m_NewPen; definit dans la classe parent.
     
    // OnInitialUpdate : initialisation
    m_NewPen.CreatePen(m_iPenStyle, m_iPenSize, m_colorPen);        
    m_NewBrush.CreateStockObject(m_iBrushStyle);
    utilisation avec restitution des valeurs dans le dc:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    CPen *pOldPen=pDC->SelectObject(&m_NewPen); 
    CBrush *pOldBrush=pDC->SelectObject(&m_NewBrush); 
    //........
    pDC->SelectObject(pOldPen);
    pDC->SelectObject(pOldBrush);

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

Discussions similaires

  1. Dessiner un rectangle au fond degrade
    Par kacedda dans le forum Flex
    Réponses: 1
    Dernier message: 12/12/2008, 11h09
  2. Dessiner un rectangle de font transparent
    Par The_Duck dans le forum MFC
    Réponses: 4
    Dernier message: 12/06/2006, 15h59
  3. Image GIF a fond transparent dans un formulaire ?
    Par Coquelicot dans le forum IHM
    Réponses: 4
    Dernier message: 25/10/2004, 12h08
  4. [JButton] avec un fond transparent
    Par Tiercel dans le forum Composants
    Réponses: 6
    Dernier message: 23/09/2004, 09h19
  5. Dessiner un rectangle avec bords et texte ...
    Par Djedjeridoo dans le forum Composants VCL
    Réponses: 3
    Dernier message: 16/06/2003, 17h17

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