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 :

BitBlit/Stretchblit pour une boite de dialogue?


Sujet :

MFC

Vue hybride

Message pr�c�dent Message pr�c�dent   Message suivant Message suivant
  1. #1
    Membre confirm�
    Inscrit en
    Juin 2004
    Messages
    79
    D�tails du profil
    Informations forums :
    Inscription : Juin 2004
    Messages : 79
    Par d�faut BitBlit/Stretchblit pour une boite de dialogue?
    Bonjour � tous,

    Je dessine sur une boite de dialogue simple. Et en rafraichissant la boite, j'obtiens un effet de scintillement. Dans le cas d'une CView, j'utilisais ce qu'on appelle je crois le double buffer: dessiner dans un DC compatible avec le DC de la cview puis faire un StrechBlt ou un BitBlt.

    J'ai donc naturellement voulu appliquer le m�me principe dans le cas de dessins dans ma boite de dialogue...mais cela ne fonctionne pas

    Mon code est le suivant:
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    CDC* pDC;
    CDC DC;
    CRect myRect;
     
    pDC=this->GetDC();
    this->GetClientRect(&myRect);
    DC.CreateCompatibleDC(pDC);
     
    DC.MoveTo(10,10);
    DC.LineTo(20,20);
     
    pDC->BitBlt(0,0,myRect.Width(),myRect.Height(),&DC,0,0,SRCCOPY);
    Que je mette ce code dans le OnPaint, Dans le BN_CLICK d'un bouton, rien n'y fait, je n'ai rien � l'�cran...

    Qqn aurait-il une suggestion?
    Merci d'avance!

  2. #2
    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,
    le bouton doit etre owner draw et la methode de dessin dans drawitem,
    comme cet exemple de la faq:
    http://c.developpez.com/faq/vc/?page...awBitmapInCtrl

  3. #3
    Membre confirm�
    Inscrit en
    Juin 2004
    Messages
    79
    D�tails du profil
    Informations forums :
    Inscription : Juin 2004
    Messages : 79
    Par d�faut
    Citation Envoy� par farscape
    salut,
    le bouton doit etre owner draw et la methode de dessin dans drawitem,
    comme cet exemple de la faq:
    http://c.developpez.com/faq/vc/?page...awBitmapInCtrl
    D�sol�, mais je ne comprends pas le lien avec mon probl�me... Peux-tu me donner un exemple?
    DrawItem ne permet-il pas de dessiner � l'int�rieur d'un contr�le ?
    Ce que je voudrai faire c'est dessiner directement dans la boite de dialogue... avec un getDC(), je peux r�cup�rer le DC de la boite et dessiner... mais j'ai un probl�me quand je souhaite utiliser StretchBlt...

    Pour en dire un peu plus, en fait, j'affiche dans une boite de dialogue un diagramme (Y=f(X)) et la courbe doit �voluer � travers le temps, du coup � chaque fois le OnPaint() r�affiche TOUTE la boite, et (en particulier), les axes clignotent...
    J'ai essay� de chercher du cot� du OnEraseBckground mais l�, si je fais un return FALSE � l'int�rieur de cette m�thode, j'ai dans la boite de dialogue les courbes successives qui s'affichent...

    Si qqn a une solution...
    Merci d'avance

  4. #4
    Membre confirm�
    Profil pro
    Inscrit en
    Juin 2004
    Messages
    196
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2004
    Messages : 196
    Par d�faut
    Salut TigreRouge

    Si tu veux simplement dessiner un rectangle dans ta fen�tre tu peux amplement te passer d'un device context jouant le r�le de buffer et d'un appel � la m�thode Bitblt(....).

    fait simplement, dans OnDraw(CDC* pDC):

    void OnDraw(CDC* pDC){
    pDC->Rectangle(x,y, x1,y1);
    }

    Si tu veux placer ton code graphique autre part que dans OnDraw(),
    fait:
    ex: ta fonction xxx appartient � l'objet par d�faut CView cr�� par MFC

    void fonction_perso(){
    CDC* DC_Ecran = GetDC();
    DC_Ecran->Rectangle(x,y, x1,y1);
    }

    ATTENTION: quand tu fait "GetDC()" le DC que tu re�oit est temporaire !!!!!!
    A la prochaine boucle, c'est un autre DC toujours de la fenetre principale que tu va recevoir dans une variable de ton choix, donc �vite ABSOLUMENT ce cas l�:

    (tu peux tester ca cas, ca va faire n'importe quoi et le r�sultat est logique car le 2�me appel � GetDC() remet tout � ZERO. Donc, ton MoveTo est annul� et le d�part de ta droite se situe � {0,0} par d�faut)
    void fonction_xxx(){
    GetDC()->MoveTo(x,y);
    GetDC()->LineTo(x1,y1);
    }

    Adopte plut�t celui-ci:

    void fonction_xxx(){
    TempDC = GetDC();
    TempDC->MoveTo(x,y);
    TempDC->LineTo(x1,y1);
    }

    PS: la m�thode BitBlt est bien choisie si tu doit traiter un nombre astronomique de rectangle et de ligne.
    Proc�de alors comme tu as fait : d�ssine tout dans un DC "de stockage" et remplie le contenu dans le DC �cran.

    J'esp�re que cela va t'aiter et r�pond � ton probl�me....
    S�b.

  5. #5
    Membre confirm�
    Inscrit en
    Juin 2004
    Messages
    79
    D�tails du profil
    Informations forums :
    Inscription : Juin 2004
    Messages : 79
    Par d�faut
    Bonsoir Cyber_N,

    Merci pour ton aide.
    Cependant, j'essaye de passer par BitBlit car je r�affiche souvent ma boite de dialogue (car courbe successive dans mon diagramme Y=f(X)) et � chaque fois, cela me fait un effet de flash, scintillement d�sagr�able. Lorsque je dessine dans une CView, je dessine dans un CDC compatible et je bitblit... mais mon probl�me est qu'avec une boite de dialogue simple, le bitblit entre un CDC m�moire et le DC r�cup�r� de la boite de dialogue ne semble pas fonctionner...

    S'il y a une autre solution pour �viter le "scintillement" que de passer par un bitblit (que je n'arrive pas � faire marcher), je suis �videmment preneur...

  6. #6
    Membre confirm�
    Profil pro
    Inscrit en
    Juin 2004
    Messages
    196
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2004
    Messages : 196
    Par d�faut
    Ok! Je vois.

    Pour essayer de comprendre et cerner ton probl�me:
    Pour faire plus simple, envoie moi juste les phrases qui suivent avec un signe OK ou NON ou OUI, .....
    est ce que:

    -> TOUT ton code graphique est dans OnDraw()
    -> tu utilises la fonction InvalidateRect(true); pour nettoyer l'�cran
    -> tu utilises Invalidate()
    -> tu utilises un bitmap vierge de stockage associ� � ton CDC.

    Ce que j'essaie de comprendre, c'est COMMENT TU EFFACES l'�cran pour redessiner ensuite.... sinon je crois que j'ai compris. mais il me faut ces indications pour pouvoir te r�pondre.

    a++;

  7. #7
    Membre confirm�
    Inscrit en
    Juin 2004
    Messages
    79
    D�tails du profil
    Informations forums :
    Inscription : Juin 2004
    Messages : 79
    Par d�faut
    Citation Envoy� par cyber_N
    ->TOUT ton code graphique est dans OnDraw()
    Non. Je n'ai pas de m�thode OnDraw() mais une m�thode OnPaint() dans lequel en effet, j'ai mon code graphique.

    Citation Envoy� par cyber_N
    -> tu utilises la fonction InvalidateRect(true); pour nettoyer l'�cran
    Non.
    Citation Envoy� par cyber_N
    -> tu utilises Invalidate()
    Oui. En fait, j'ai un �v�nement OnMouseMove qui rep�re les mouvements de la souris et dans cette �v�nement, j'ai un this->Invalidate(). Si j'ai bien compris, cela apelle le code dans le OnPaint() qui appelle automatiquement OnEraseBkgnd(CDC* pDC) qui, lui, par d�faut "peint" la boite avec un CBrush par d�faut.
    Citation Envoy� par cyber_N
    -> tu utilises un bitmap vierge de stockage associ� � ton CDC.
    : : Pas compris la question...

    Citation Envoy� par cyber_N
    Ce que j'essaie de comprendre, c'est COMMENT TU EFFACES l'�cran pour redessiner ensuite....
    J'imagine que c'est le OnPaint() qui automatiquement appelle OnEraseBkgnd()... Corrigez moi si je me trompe...

  8. #8
    Membre confirm�
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    38
    D�tails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2005
    Messages : 38
    Par d�faut
    Bonjour,

    Est-ce que tu as le m�me r�sultat de clignotement si tu utilises l'objet CPaintDC dans ta m�thode OnPaint.

    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
     
    void CMaDlg::OnPaint()
    {
       CPaintDC DC(this);
       CDC DCMem; 
       CRect myRect; 
     
       this->GetClientRect(&myRect); 
       DCMem.CreateCompatibleDC(&DC); 
     
       DCMem.MoveTo(10,10); 
       DCMem.LineTo(20,20); 
     
       DC.BitBlt(0,0,myRect.Width(),myRect.Height(),&DCMem,0,0,SRCCOPY);
    }

  9. #9
    Membre confirm�
    Inscrit en
    Juin 2004
    Messages
    79
    D�tails du profil
    Informations forums :
    Inscription : Juin 2004
    Messages : 79
    Par d�faut
    Citation Envoy� par Madeiras
    Bonjour,

    Est-ce que tu as le m�me r�sultat de clignotement si tu utilises l'objet CPaintDC dans ta m�thode OnPaint.

    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
     
    void CMaDlg::OnPaint()
    {
       CPaintDC DC(this);
       CDC DCMem; 
       CRect myRect; 
     
       this->GetClientRect(&myRect); 
       DCMem.CreateCompatibleDC(&DC); 
     
       DCMem.MoveTo(10,10); 
       DCMem.LineTo(20,20); 
     
       DC.BitBlt(0,0,myRect.Width(),myRect.Height(),&DCMem,0,0,SRCCOPY);
    }
    Ce code malheureusement ne m'affiche pas le trait...
    Mais quand je remplace
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
       DCMem.MoveTo(10,10); 
       DCMem.LineTo(20,20);
    par
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    DC.MoveTo(10,10); 
     DC.LineTo(20,20);
    , cad quand j'affiche directement sur le DC de la boite, l�, ca marche...Ce qui me fait penser que le bitblit ne fonctionne pas correctement
    C'est d'autant plus �trange que je ne trouve aucun probl�me de ce type en cherchant sur le net... je vais craquer...

  10. #10
    Membre confirm�
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    38
    D�tails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2005
    Messages : 38
    Par d�faut
    Autre solution possible,

    Tu ajoutes un contr�le CStatic dans ta bo�te de dialogue, tu peux par programmation t'arranger pour que ce contr�le s'adapte � la taille de la zone cliente de la dlg.

    Ensuite, tu dessines dans le DC du CStatic, avec tes instructions de double buffer, et avec l'espoir d'effacer l'effet de scintillement lors de l'affichage. (Il ne faut plus dessiner dans le DC de la dlg).

    Je me rappel qu'en DOS, lorsque je dessinais du graphique, j'utilisais la technique du wait retrace afin d'attendre le balayage de l'�cran pour dessiner sans effet de clignotement, mais je ne sais pas si c'est toujours d'actualit� sous Windows. Et si oui, je ne sais pas si les instructions assembler que j'utilisais pourraient encore fonctionner.

  11. #11
    Membre confirm�
    Inscrit en
    Juin 2004
    Messages
    79
    D�tails du profil
    Informations forums :
    Inscription : Juin 2004
    Messages : 79
    Par d�faut
    Citation Envoy� par Madeiras
    Autre solution possible,

    Tu ajoutes un contr�le CStatic dans ta bo�te de dialogue, tu peux par programmation t'arranger pour que ce contr�le s'adapte � la taille de la zone cliente de la dlg.

    Ensuite, tu dessines dans le DC du CStatic, avec tes instructions de double buffer, et avec l'espoir d'effacer l'effet de scintillement lors de l'affichage. (Il ne faut plus dessiner dans le DC de la dlg).

    Je me rappel qu'en DOS, lorsque je dessinais du graphique, j'utilisais la technique du wait retrace afin d'attendre le balayage de l'�cran pour dessiner sans effet de clignotement, mais je ne sais pas si c'est toujours d'actualit� sous Windows. Et si oui, je ne sais pas si les instructions assembler que j'utilisais pourraient encore fonctionner.
    Oui, m�me si la solution CStatic fait un peu bricolage, je vais quand m�me l'essayer demain vu que je suis dans l'impasse pour le moment. Merci pour ton aide Madeiras
    Sinon, je continue � essayer de chercher de la doc mais apparemment le double buffering devrait fonctionner sur une CDialog (il y a des exemples sur le net avec des bitmap qu'on affiche sur la boite..mais pourquoi une pauvre ligne refuse de s'afficher... T_T )

  12. #12
    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,
    aucun probleme pourtant !
    rapidement :
    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
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
     
    #if !defined(AFX_MYBUTTON_H__0EFA9690_5DE5_4E5F_B0ED_F2AEF9E652F5__INCLUDED_)
    #define AFX_MYBUTTON_H__0EFA9690_5DE5_4E5F_B0ED_F2AEF9E652F5__INCLUDED_
     
    #if _MSC_VER > 1000
    #pragma once
    #endif // _MSC_VER > 1000
    // Mybutton.h : header file
    //
    /////////////////////////////////////////////////////////////////////////////
    // CMybutton window
     
    class CMybutton : public CButton
    {
    // Construction
    public:
    	CMybutton();
     
    // Attributes
    public:
     
    // Operations
    public:
     
    // Overrides
    	// ClassWizard generated virtual function overrides
    	//{{AFX_VIRTUAL(CMybutton)
    	public:
    	virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);
    	protected:	
    	virtual void PreSubclassWindow();
    	//}}AFX_VIRTUAL
     
    // Implementation
    public:
    	virtual ~CMybutton();
     
    	// Generated message map functions
    protected:
    	//{{AFX_MSG(CMybutton)
     
    	//}}AFX_MSG
     
    	DECLARE_MESSAGE_MAP()
    };
    /////////////////////////////////////////////////////////////////////////////
    //{{AFX_INSERT_LOCATION}}
    // Microsoft Visual C++ will insert additional declarations immediately before the previous line.
    #endif // !defined(AFX_MYBUTTON_H__0EFA9690_5DE5_4E5F_B0ED_F2AEF9E652F5__INCLUDED_)
     
    // .cpp
    #include "Mybutton.h"
     
    #ifdef _DEBUG
    #define new DEBUG_NEW
    #undef THIS_FILE
    static char THIS_FILE[] = __FILE__;
    #endif
     
    /////////////////////////////////////////////////////////////////////////////
    // CMybutton
     
    CMybutton::CMybutton()
    {
    }
     
    CMybutton::~CMybutton()
    {
    }
     
     
    BEGIN_MESSAGE_MAP(CMybutton, CButton)
    	//{{AFX_MSG_MAP(CMybutton)
     
    	//}}AFX_MSG_MAP
    END_MESSAGE_MAP()
     
    /////////////////////////////////////////////////////////////////////////////
    // CMybutton message handlers
    void CMybutton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) 
    {
    	// TODO: Add your code to draw the specified item
        ASSERT(lpDrawItemStruct != NULL);
        CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC);
        //UINT nState = lpDrawItemStruct->itemState;
        CRect itemRect = lpDrawItemStruct->rcItem;
     
        CDC MemDC;
        MemDC.CreateCompatibleDC(pDC);
        CBitmap bmp;
        bmp.CreateCompatibleBitmap(&MemDC,itemRect.Width(),itemRect.Height());  
        CBitmap *pOldBitmap =MemDC.SelectObject (&bmp);
     
        MemDC.PatBlt(0,0,itemRect.Width(),itemRect.Height(),WHITENESS);
     
        MemDC.MoveTo(10,10);
        MemDC.LineTo(20,20);
     
     
        pDC->BitBlt(0,0,itemRect.Width(),itemRect.Height(),&MemDC,0,0,SRCCOPY);
     
        MemDC.SelectObject (pOldBitmap);
    }
     
    void CMybutton::PreSubclassWindow() 
    {
    	// TODO: Add your specialized code here and/or call the base class
    	// Switch to owner-draw
        ModifyStyle(SS_TYPEMASK, BS_OWNERDRAW, SWP_FRAMECHANGED);
    	CButton::PreSubclassWindow();
    }

  13. #13
    Membre confirm�
    Profil pro
    Inscrit en
    Juin 2004
    Messages
    196
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2004
    Messages : 196
    Par d�faut
    Bonjour � tous et toi TigreRouge.

    Voici pourquoi ton bitblt() ne marche pas ainsi que quelques conseils:

    CDC* pDC; // moi je mettrais: CDC* pDC = GetDC();
    CDC DC; // Ok !
    CRect myRect;

    pDC=this->GetDC(); // Ok ! tu n'a pas besoin de mettre this, � part si cela simplifie ta lecture....

    this->GetClientRect(&myRect);
    DC.CreateCompatibleDC(pDC); // Ok !


    // C'EST ICI QU'IL TE MANQUE UN TRUC INDISPENSABLE:
    // quand tu dessine dans ton CDC pour le d�verser dans ton DC �cran,
    // en fait tu dessine dans le vide! il faut une "planche � dessin" associ� � // ton CDC temporaire, un HBITMAP vierge (blanc). (voir plus bas)


    DC.MoveTo(10,10); // Ok !
    DC.LineTo(20,20); // Ok !

    // essaie ici de mettre des valeurs fixes � la place de myRect
    // (je dit �a parce que j'ai eu des probl�mes avec GetClientRect, mais si // tu es s�re des valeurs alors....ok)
    pDC->BitBlt(0,0,myRect.Width(),myRect.Height(),&DC,0,0,SRCCOPY);
    Voici ce qu'il te manque avant tout op�rations graphique....
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
     
    DC.CreateCompatibleDC( pDC );
    hBufferBitmap = CreateCompatibleBitmap(pDC, ecran_x, ecran_y);
    DC.SelectObject(hBufferBitmap);
    PS (pour le code ci-dessus): si "CreateCompatibleBitmap" te demande un HDC et non CDC comme type de variable, donne lui ca : "pDC->m_hDC".

    autre PS (pour Invalidate et le redessin � l'�cran): ne place pas Invalidate() dans ton mousemove() mais appelle Invalidate() gr�ce � un timer. Si tu travailles avec les MFC cr�e avec ClassWisard un "OnTimer()" du message WM_TIMER et place un Invalidate() dans cette fonction OnTimer():

    #define NUM_TIMER 0
    void OnTimer(){
    Invalidate();
    SetTimer(NUM_TIMER, 25, NULL);
    }
    Lorsque tu demarres juste ton application fait SetTimer(NUM_TIMER, 25, NULL);

    Et voil� !
    [/quote]

Discussions similaires

  1. [D�butant] Ouvrir une boite de dialogue pour enregistrer un fichier
    Par pompier21 dans le forum Interfaces Graphiques
    R�ponses: 2
    Dernier message: 09/10/2008, 10h09
  2. R�ponses: 6
    Dernier message: 15/11/2007, 23h11
  3. R�ponses: 3
    Dernier message: 02/10/2006, 16h45
  4. R�ponses: 4
    Dernier message: 21/07/2006, 11h00
  5. R�ponses: 6
    Dernier message: 14/06/2006, 08h56

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