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

Langage C++ Discussion :

Problème d'affichage de controles statics personnalisés lors du redimensionnement de la fenêtre


Sujet :

Langage C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    44
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2008
    Messages : 44
    Par défaut Problème d'affichage de controles statics personnalisés lors du redimensionnement de la fenêtre
    Bonjour,
    j'ai créé une application dont la fenêtre principale contient pleins de controls statics que je crée dynamiquement avec CreateWindowEx.
    Dans chaque static, j'affiche une image avec ma fonction DrawPics (seule solution que j'ai trouvé pour afficher des images avec un canal alpha) :
    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
     
    void DrawPics(HDC hdc,HBITMAP image)
    {
        HDC hMemDC=NULL, hTempDC=NULL;
        BLENDFUNCTION bf;
        HBITMAP hBitmapTemp=NULL, hBitmapOld1=NULL, hBitmapOld2=NULL;
     
        hMemDC = CreateCompatibleDC(hdc);
        hTempDC = CreateCompatibleDC(hdc);
     
        hBitmapTemp = CreateCompatibleBitmap(hdc, 24, 24);
        hBitmapOld1 = (HBITMAP)SelectObject(hTempDC, hBitmapTemp);
     
        //while transparency, clear the contents with the source background
        BitBlt(hTempDC, 0, 0, 24, 24, hdc, 0, 0, SRCCOPY);
     
        hBitmapOld2 = (HBITMAP)SelectObject(hMemDC, image);
     
        bf.BlendOp = AC_SRC_OVER;
        bf.BlendFlags = 0;
        bf.SourceConstantAlpha = 255;
        bf.AlphaFormat = AC_SRC_ALPHA;
     
        AlphaBlend(hTempDC, 0, 0, 24, 24, hMemDC, 0, 0, 24, 24, bf);
     
        //now hTempDC is ready, blt it directly on hdc
        BitBlt(hdc, 0, 0, 24, 24, hTempDC, 0, 0, SRCCOPY);
     
        SelectObject(hMemDC, hBitmapOld2);
        SelectObject(hTempDC, hBitmapOld1);
     
        DeleteObject(hBitmapTemp);
        DeleteDC(hTempDC);
        DeleteDC(hMemDC);
    }
    Tout s'affiche bien sauf pendant le redimensionnement de la fenêtre.
    Quand le redimensionnement est en cours, l'affichage des controls statics clignote avec un fond gris jusqu’à la fin du redimensionnement.
    Voici ce qui se passe pendant le wm_size :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
            case WM_SIZE:
            {
                if(LOWORD(lParam)>0)
                    largeur=LOWORD(lParam);
                if(HIWORD(lParam)>0)
                    hauteur=HIWORD(lParam);
     
                RECT apiRECT;
                GetClientRect(hwnd,&apiRECT);
                hauteurZoneTravail=apiRECT.bottom-apiRECT.top;
                largeurZoneTravail=apiRECT.right-apiRECT.left;
     
                affichage_items();
            }
    voila ce que fait la fonction affichage_items :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    void affichage_items()
    {
        for(unsigned int i=0;i<tab_items.length();i++)
        {
                /*
     
                ici, le code pour calculer la nouvelle position de chaque item
     
                */
                tab_items.id(i).change_position(x, y);
        }
        InvalidateRect(mainhwnd, 0, TRUE);
    }
    j'ai fait une classe qui gère les controls statics et tab_items est un tableau qui contient des objets de cette classe.
    Dans affichage_items, je recalcule la position de chaque static pour qu'ils restent centrés dans la fenêtre.
    La fonction change_position ne fait que des SetWindowPos sur les statics :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    void item::change_position(int posx,int posy)
    {
        x=posx;
        y=posy;
        SetWindowPos(hFond,NULL,-ScrollX+x,-ScrollY+y,0,0,SWP_NOSIZE);
        SetWindowPos(hNom,NULL,-ScrollX+x+35,-ScrollY+y+8,0,0,SWP_NOSIZE);
        SetWindowPos(hDesc,NULL,-ScrollX+x+7,-ScrollY+y+33,0,0,SWP_NOSIZE);
        SetWindowPos(hVersion,NULL,-ScrollX+x+187,-ScrollY+y+35,0,0,SWP_NOSIZE);
        SetWindowPos(hIcone,NULL,-ScrollX+x+6,-ScrollY+y+6,0,0,SWP_NOSIZE);
        SetWindowPos(hPlus,NULL,-ScrollX+x+285,-ScrollY+y+5,0,0,SWP_NOSIZE);
    }
    l'InvalidateRect de la fonction affichage_items provoque le ré-affichage de chaque control static qui est géré ici :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    case WM_CTLCOLORSTATIC:
    {
    	HDC hdcStatic = (HDC) wParam;
    	HWND hST = (HWND) lParam;
     
    	for(unsigned int i=0;i<tab_items.length();i++)
    		tab_items.id(i).draw(hdcStatic,hST);
     
    	return (INT_PTR) GetStockBrush(NULL_BRUSH);
    }
    voila ce que fait le draw (utilisation du DrawPics du début):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    void item::draw(HDC hdcStatic,HWND hSTATIC)
    {
        if(affiche)
        {
            if(hSTATIC==hIcone)
                DrawPics(hdcStatic,icone);
     
            if(hSTATIC==hVersion)
                SetTextColor(hdcStatic, RGB(128,0,0));
        }
    }
    Voila, j'espère que c'est assez clair.
    Je voudrais savoir qu'est ce que je fais de mal pour que l'affichage soit mauvais lors du redimensionnement.
    Merci pour votre aide.

  2. #2
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    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 395
    Par défaut
    Dessiner dans le WM_CTLCOLORSTATIC? Ça me semble un peu sale. Normalement, ça se fait dans le WM_DRAWITEM...

    Pour éviter le clignotement lors du redimensionnement, je me demande si donner à ta fenêtre le style WS_CLIPCHILDREN peut aider.
    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 averti
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    44
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2008
    Messages : 44
    Par défaut
    Merci pour ton aide.
    J'ai essayé le WM_DRAWITEM, mais ça ne fonctionne pas, c'est fait pour les boutons, les combo box, les list box, ou les menus.
    Peut-être faut-il que j'utilise WM_PAINT???
    WS_CLIPCHILDREN ne fait qu'empirer les choses, à la fin du redimensionnement, les controls ne sont pas automatiquement redessinés.

  4. #4
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    44
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2008
    Messages : 44
    Par défaut
    Rectification:
    j'ai vu dans la MSDN, que si on met le style SS_OWNERDRAW à un control static,
    le message WM_DRAWITEM est envoyé lorsqu'il faut le redessiner.
    J'ai essayé, mais aucun message WM_DRAWITEM n'est envoyé.

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    44
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2008
    Messages : 44
    Par défaut
    Maintenant, je reçois les messages WM_DRAWITEM.Mes controls avaient le style SS_BITMAP, ce qui n'est apparemment pas compatible avec SS_OWNERDRAW.
    Donc, je dessine maintenant mes controls static lors des WM_DRAWITEM,
    mais j'obtiens le même résultat qu'avant: l'affichage est correcte, sauf lors des redimensionnements.
    Et le WS_CLIPCHILDREN n'arrange rien.

  6. #6
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    44
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2008
    Messages : 44
    Par défaut
    J'ai trouvé la solution :
    au lieu de faire appel à affichage_items() dans le WM_SIZE, ce qui change la position de chaque static, je fais simplement un ScrollWindowEx.
    Et là, c'est niquel!

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

Discussions similaires

  1. Réponses: 1
    Dernier message: 06/02/2009, 15h15
  2. Bug lors du redimensionnement de la fenêtre
    Par Slayor dans le forum EDT/SwingWorker
    Réponses: 0
    Dernier message: 21/09/2008, 02h09
  3. [Antialising] Comment procéder lors du redimensionnement de la fenêtre ?
    Par wizad dans le forum Windows Presentation Foundation
    Réponses: 3
    Dernier message: 19/09/2008, 11h07
  4. Réponses: 3
    Dernier message: 18/05/2008, 18h39
  5. Problème d'affichage de controle
    Par Kalite dans le forum MFC
    Réponses: 1
    Dernier message: 26/01/2008, 15h27

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