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

Windows Discussion :

[GDI] Toute petite question (pour une fois) : effacer régulièrement les Rectangle() ?


Sujet :

Windows

  1. #1
    Membre régulier Avatar de kidpaddle2
    Inscrit en
    Avril 2006
    Messages
    430
    Détails du profil
    Informations forums :
    Inscription : Avril 2006
    Messages : 430
    Points : 95
    Points
    95
    Par défaut [GDI] Toute petite question (pour une fois) : effacer régulièrement les Rectangle() ?
    Bonjour,

    Alors puisque le titre n'est pas très explicite, je vous explique : J'ai fait un visualiseur de spectre musical avec des progressbars mais comme personne ne sait comment les rendre transparentes, je me suis dit que j'allais le faire avec des Rectangle(). C'est ce que j'ai fais. Cela marche parfaitement (du moins l'affichage), excepté le rafraichissement. En effet, même avec des InvalidateRect(), mes Rectangle() restent toujours à l'écran et laissent donc des traces derrière eux.

    [edit] Voir screen ci joint.

    Comment pourrais je les effacer juste avant de les afficher ? Auriez vous une fonction ?

    Merci d'avance.

    P.S. : Je risque de faire un nouveau post (encore) car impossible de compiler un code d'infobulle sur trayIcon avec NIF_INFO : il est non déclaré... (même en définissant _WIN32_IE et en vérifiant la version de Shell32.dll (pourtant à 6 et quelques...) A part si vous avez une réponse ?
    Vive l'embarqué.

  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 518
    Points
    41 518
    Par défaut
    Ah, je n'avais pas vu ce post là avant de répondre à l'autre.

    Bon, mon conseil : Tu te fais un contrôle avec une couleur d'arrière-plan (le bleu, ici) et tu fais des InvalidateRect() avec le dernier paramètre à TRUE pour effacer le tout (ou si tu travailles sur un bitmap en mémoire, un gros FillRect() pour tout effacer), puis tu dessines tous les rectangles du spectre dans le traitement de WM_PAINT.

    Si l'affichage parait clignotant, alors tu fais tout dans le WM_PAINT en passant par un bitmap en mémoire: FillRect() pour tout effacer, dessin de tous les rectangles, puis BitBlt() pour copier le tout.

    Et n'oublie pas de garder le bitmap et le MemoryDC en mémoire pour toute la durée de vie de la fenêtre, ce sera plus rapide que les créer et les détruire à chaque fois...
    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 régulier Avatar de kidpaddle2
    Inscrit en
    Avril 2006
    Messages
    430
    Détails du profil
    Informations forums :
    Inscription : Avril 2006
    Messages : 430
    Points : 95
    Points
    95
    Par défaut
    Donc si je comprends bien, je dois faire un InvalidateRect() sur tout la surface de la dialogbox dans le wm_timer. Ensuite, je colle mon image (avec drawstate par exemple ou bitblt) et je finis par dessiner mes Rectangle(), le tout dans le WM_PAINT ?

    A mon avis j'ai oublié quelque chose...

    Bon d'accord je vais essayer. Merci encore.

    [edit] Comme tu l'as dit le rafraichissement a du mal ... ca clignote pas mal.
    Voici mon code actuel :

    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
    //Procédure
        static float *oldSpectrum = NULL, finalSpectrum[BARS_NUMBER] = {0.0};
        static HBITMAP BarBmp = (HBITMAP)LoadImage(hInst, "E:/Dune/Untitled2.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
        static HRGN region = BmpToRgn(BarBmp,RGB(0,0,0));
    
        switch (uMsg)
        {
            case WM_INITDIALOG:
                SetWindowRgn(hDlg,region,TRUE);
    
                SetTimer(hDlg, 0, 0, (TIMERPROC)NULL);
                break;
    
            case WM_PAINT :
            {
              HDC hdc;
              PAINTSTRUCT ps;
              HBITMAP hbmTmp;
              BITMAP bmpi;
              HDC hdcMem;
    
              hdcMem = CreateCompatibleDC(NULL);
              hbmTmp = (HBITMAP)SelectObject(hdcMem,BarBmp);
              GetObject(BarBmp,sizeof(bmpi),&bmpi);
    
              hdc = BeginPaint(hDlg, &ps);
              BitBlt(hdc,0,0,bmpi.bmWidth,bmpi.bmHeight,hdcMem,0,0,SRCCOPY);
              refreshBars(hdc,finalSpectrum);
              EndPaint(hDlg, &ps);
    
              SelectObject(hdcMem,hbmTmp);
              DeleteDC(hdcMem);
            }
            break;
    
                case WM_TIMER:
                if(IsWindowVisible(hDlg))
                {
                    static const RECT rects = {0,300,BAR_WIDTH*BARS_NUMBER,0};
    
                    oldSpectrum = FSOUND_DSP_GetSpectrum();
                    adaptSpectrum(oldSpectrum, finalSpectrum);
                    
                    InvalidateRect(hDlg,&rects,TRUE);
                }
                break;
    
               //...
    Vive l'embarqué.

  4. #4
    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 518
    Points
    41 518
    Par défaut
    Citation Envoyé par Médinoc
    Et n'oublie pas de garder le bitmap et le MemoryDC en mémoire pour toute la durée de vie de la fenêtre (j'aurais du dire du contrôle en fait), ce sera plus rapide que les créer et les détruire à chaque fois...
    Bon, déjà, j'espère qu'on est d'accord, tu fais un contrôle qui ne sert QU'À ÇA : Afficher le spectre.

    NOTE: On va mettre tout en static pour cette fois, ce qui limite le contrôle à un seul exemplaire. Pour faire autrement, il faut utiliser les Set/GetWindowLong(CWL_USERDATA)

    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
    void DessinerSpectre(HDC hdc, int largeur, int hauteur);
    
    LRESULT CALLBACK SpectrumWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
    {
    static HBITMAP s_hOldBmp = NULL;
    static HDC s_hMemDC = NULL;
    static HBRUSH s_hBack = NULL;
    
    LRESULT lrRetour = 0;
    
    switch(uMsg)
    	{
    	case WM_CREATE:
    		{
    		RECT r;
    		HDC hdc = GetDC(NULL);
    		HBITMAP hBmp = NULL;
    		
    		GetClientRect(&r);
    		hBmp = CreateCompatibleBitmap(hdc, r.right, r.bottom);
    		s_hMemDC = CreateCompatibleDC(hdc);
    		ReleaseDC(NULL, hdc);
    		
    		s_hOldBmp = SelectObject(s_hMemDC, hBmp);
    		s_hBack = CreateSolidBrush(COULEUR_DU_FOND);
    		}
    		break;
    		
    	case WM_DESTROY:
    		{
    		HBITMAP hBmp = SelectObject(s_hMemDC, s_hOldBmp);
    		s_hOldBmp = NULL;
    		DeleteObject(hBmp);
    		DeleteDC(s_hMemDC), s_hMemDC=NULL;
    		DeleteObject(s_hBack), s_hBack=NULL;
    		}
    		break;
    	
    	case WM_TIMER:
    		InvalidateRect(hWnd, NULL, FALSE); /*Inutile d'effacer, puisqu'on remplit tout*/
    		break;
    	
    	case WM_PAINT:
    		{
    		RECT r;
    		GetClientRect(hWnd, &r);
    		FillRect(s_hMemDC, &r, s_hBack);
    		DessinerSpectre(s_hMemDC, r.right, r.bottom);
    			{
    			PAINTSTRUCT ps;
    			HDC hdc = BeginPaint(hWnd, &ps);
    			
    			BitBlt(hdc, 0, 0, r.right, r.bottom, s_hMemDC, 0, 0, SRCCOPY);
    			
    			EndPaint(hWnd, &ps);
    			}
    		}
    		break;
    	
    	default:
    		lrRetour = DefWindowProc(hWnd, uMsg, wParam, lParam);
    	}
    return lrRetour;
    }
    PS: Attention, ce n'est pas testé, ni même compilé. Mais c'est l'idée générale.
    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.

  5. #5
    Membre régulier Avatar de kidpaddle2
    Inscrit en
    Avril 2006
    Messages
    430
    Détails du profil
    Informations forums :
    Inscription : Avril 2006
    Messages : 430
    Points : 95
    Points
    95
    Par défaut
    Merci pour ton code Médinoc. Mais il y a quelques choses que je ne comprends pas : Par exemple pourquoi dis tu que le InvalidateRect() est inutile puisqu'on dessine tout lécran ? En effet le WM_PAINT est appelé quand la fenêtre a besoin d'être redessinée ! Or sans le InvalidateRect() elle n'en aurait pas besoin ...

    Ensuite, c'est le coup du bitmap que je ne comprends pas... A aucun endroit on ne le blitte ! Donc on ne verrait que la couleur de fond...

    Enfin, pourquoi ais je besoin des largeurs et hauteur du spectre ? A quelques pixels pres c'est la taille totale de la dlgbox...

    Je vais voir ça. Je poste dès que j'ai finis.

    [edit] Je viens de finir... euh je n'ai pas pu tester du fait de la quinzaine d'erreurs que j'ai eu. Des jump case label, invalid cast etc...

    Bref n'y a t il pas quelque chose de plus simple ? J'aimerais en fait travailler sur un hdc où on a collé précédemment le bitmap, donc afficher mes Rectangle() et finalement copier le tout sur le hdc final.
    Vive l'embarqué.

  6. #6
    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 518
    Points
    41 518
    Par défaut
    Citation Envoyé par kidpaddle2
    Merci pour ton code Médinoc. Mais il y a quelques choses que je ne comprends pas :
    Normal, on ne peut pas toujours tout comprendre d'un coup, surtout que c'est pas vraiment commenté
    Citation Envoyé par kidpaddle2
    Par exemple pourquoi dis tu que le InvalidateRect() est inutile puisqu'on dessine tout lécran ? En effet le WM_PAINT est appelé quand la fenêtre a besoin d'être redessinée ! Or sans le InvalidateRect() elle n'en aurait pas besoin ...
    C'est le troisième paramètre fErase qui est inutile, pas l'appel de la fonction.
    Citation Envoyé par kidpaddle2
    Ensuite, c'est le coup du bitmap que je ne comprends pas... A aucun endroit on ne le blitte ! Donc on ne verrait que la couleur de fond...
    Relis le code, le bitmap est blitté, et je n'ai pas édité.
    Citation Envoyé par kidpaddle2
    Enfin, pourquoi ais je besoin des largeurs et hauteur du spectre ? A quelques pixels pres c'est la taille totale de la dlgbox...
    Mais je ne sais pas comment tu es supposé l'avoir, la taille.
    Ici, la taille du spectre est celle du contrôle, indépendamment de celle de la dialogbox.
    Si ta fonction de dessin n'a pas besoin de connaitre la taille (si c'est une taille fixe, par exemple) alors tu ne la passe pas, j'avais mis ça parce que c'est ce que j'ai l'habitude de faire.
    Citation Envoyé par kidpaddle2
    Je vais voir ça. Je poste dès que j'ai finis.
    Bonne chance!
    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.

  7. #7
    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 518
    Points
    41 518
    Par défaut
    Citation Envoyé par kidpaddle2
    [edit] Je viens de finir... euh je n'ai pas pu tester du fait de la quinzaine d'erreurs que j'ai eu. Des jump case label, invalid cast etc...
    Ça me parait bizarre, ça... Tu es en C++ maintenant ?

    PS: Tu peux me lister les erreurs?
    Mon code est le meilleur compromis que je puisse faire entre simplicité et rapidité.
    Et puis, je te pensais désormais habitué aux bitmaps qui durent toute la vie d'une fenêtre ou d'un contrôle...
    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.

  8. #8
    Membre régulier Avatar de kidpaddle2
    Inscrit en
    Avril 2006
    Messages
    430
    Détails du profil
    Informations forums :
    Inscription : Avril 2006
    Messages : 430
    Points : 95
    Points
    95
    Par défaut
    Relis le code, le bitmap est blitté, et je n'ai pas édité.
    Ah bon ? Bizarre à aucun endroit je ne vois de drawstate, bitblt (enfin si mais c'est celui du s_hMemDc où sont dessinées les barres) ou autre...

    Ça me parait bizarre, ça... Tu es en C++ maintenant ?
    Euh oui mais en fait je n'utilise pas de classes (c'est intelligent ça ) J'en avais besoin pour quelques fonctions comme le BmpToRgn que j'ai mis hyper longtemps à trouver

    Et puis, je te pensais désormais habitué aux bitmaps qui durent toute la vie d'une fenêtre ou d'un contrôle...
    Dans une certaine mesure, oui. Mais c'est assez vague je n'ai pas tout à fait saisi la logique du GDI pour certaines choses...

    Mon code est le meilleur compromis que je puisse faire entre simplicité et rapidité.
    D'accord alors je vais te lister les erreurs.

    D'abord 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
    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
    void refreshBars( HDC hdc, float spectrum[]);
    
    BOOL APIENTRY SpectrumProc(HWND hDlg,UINT uMsg,WPARAM wParam,LPARAM lParam)
    {
        static float *oldSpectrum = NULL, finalSpectrum[BARS_NUMBER] = {0.0};
        static HBITMAP BarBmp = (HBITMAP)LoadImage(hInst, "E:/Dune/Untitled2.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
        static HRGN region = BmpToRgn(BarBmp,RGB(0,0,0));
        static HBITMAP s_hOldBmp = NULL;
        static HDC s_hMemDC = NULL;
        static HBRUSH s_hBack = NULL;
    
        switch (uMsg)
        {
            case WM_INITDIALOG:
                SetWindowRgn(hDlg,region,TRUE);
    
                RECT r;
                HDC hdc = GetDC(NULL);
                HBITMAP hBmp = NULL;
    
                GetClientRect(hDlg,&r);
                hBmp = CreateCompatibleBitmap(hdc, r.right, r.bottom);
                s_hMemDC = CreateCompatibleDC(hdc);
                ReleaseDC(NULL, hdc);
    
                s_hOldBmp = SelectObject(s_hMemDC, hBmp);
                s_hBack = CreateSolidBrush(RGB(0,0,0));
    
                SetTimer(hDlg, 0, 0, (TIMERPROC)NULL);
                break;
    
            case WM_PAINT :
            {
                RECT r;
                GetClientRect(hDlg, &r);
                FillRect(s_hMemDC, &r, s_hBack);
                refreshBars(s_hMemDC, finalSpectrum);
                    {
                    PAINTSTRUCT ps;
                    HDC hdc = BeginPaint(hDlg, &ps);
    
                    BitBlt(hdc, 0, 0, r.right, r.bottom, s_hMemDC, 0, 0, SRCCOPY);
    
                    EndPaint(hDlg, &ps);
                    }
            }
            break;
    
            case WM_TIMER:
                if(IsWindowVisible(hDlg))
                {   oldSpectrum = FSOUND_DSP_GetSpectrum();
                    adaptSpectrum(oldSpectrum, finalSpectrum);
    
                    InvalidateRect(hDlg, NULL, FALSE);
                }
                break;
    
            case WM_CLOSE:
                HBITMAP hBmp = SelectObject(s_hMemDC, s_hOldBmp);
                s_hOldBmp = NULL;
                DeleteObject(hBmp);
                DeleteDC(s_hMemDC), s_hMemDC=NULL;
                DeleteObject(s_hBack), s_hBack=NULL;
                //ShowWindow (hDlg,SW_HIDE);
                PostQuitMessage(0);
                break;
    
          default:
             return FALSE;
        }
    
        return TRUE;
    }
    
    void refreshBars( HDC hdc, float spectrum[])
    {
        static int height[BARS_NUMBER] = {0};
    
        SelectObject(hdc, CreateSolidBrush(RGB(0,180,255)));
    
        for(int i = 0 ; i < BARS_NUMBER ; i++)
        {
            if(spectrum[i] < height[i])
                height[i]-=3;
    
            else if(spectrum[i] > height[i])
            {
                if(spectrum[i] > 250)
                    height[i] = 290;
                else
                    height[i] = (int)spectrum[i];
            }
        }
    
        for(int i = 0 ; i < BARS_NUMBER ; i++)
            Rectangle(hdc, (i*BEFORE_NEXT)+17, WINDOW_HEIGHT-height[i], ((i*BEFORE_NEXT)+17)+BAR_WIDTH, WINDOW_HEIGHT);
    
        return;
    }
    Puis les erreurs :
    invalid conversion from void* to HBITMAP__*
    jump to case label
    crosses initialization of HBITMAP__*hBmp
    jump to case label
    crosses initialization of HBITMAP__*hBmp (2eme)
    jump to case label (2eme)
    crosses initialization of HBITMAP__*hBmp (3eme)
    jump to case label (3eme)
    redeclaration of HBITMAP__*hBmp
    HBITMAP__*hBmp previously declared here
    crosses initialization of HBITMAP__*hBmp (4eme)
    jump to case label (4eme)
    Super non ? J'ai un peu de mal à corriger les erreurs puisque je n'ai pas fini d'étudier ton code... il est un peu plus compliqué que ce que j'ai eu à manier précédemment. (à savoir juste un bitmap à afficher)
    Vive l'embarqué.

  9. #9
    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 518
    Points
    41 518
    Par défaut
    Ah bon ? Bizarre à aucun endroit je ne vois de drawstate, bitblt (enfin si mais c'est celui du s_hMemDc où sont dessinées les barres) ou autre...
    Ben, c'est de ce BitBlt() là que je parle.
    Mais le contrôle n'est pas transparent, c'est ça que tu voulais savoir?
    Pour le rendre transparent comme le reste, je pense que remplacer le CreateSolidBrush() par un truc du genre (HBRUSH)SendMessage(GetParent(hCtrl), WM_CTLCOLORSTATIC, (WPARAM)hdc, (LPARAM)hCtrl); (je dis bien un truc du genre, car c'est de tête et c'est pas testé) devrait faire l'affaire si la fenêtre parent traite WM_CTLCOLORSTATIC comme je t'ai déjà appris à le faire.

    invalid conversion from void* to HBITMAP__*
    En C++, il faut un cast, en C, pas besoin. Tu dois caster le retour de SelectObject() en HBITMAP (car SelectObject() retourne un HGDIOBJ qui est un void*).
    jump to case label
    crosses initialization of HBITMAP__*hBmp
    Les accolades que j'avais mises dans les case ne sont pas décoratives.
    Au passage, les destructions d'objet doivent être mises dans le case WM_DESTROY, pas WM_CLOSE.

    PS: Tu dois retirer l'appel à PostQuitMessage(). Seule la fenêtre principale a le droit de faire ça (comprendre "doit avoir le droit de faire ça").

    J'ai un peu de mal à corriger les erreurs puisque je n'ai pas fini d'étudier ton code... il est un peu plus compliqué que ce que j'ai eu à manier précédemment. (à savoir juste un bitmap à afficher)
    Ben, c'est un bitmap à remplir juste avant de l'afficher, c'est tout...
    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.

  10. #10
    Membre régulier Avatar de kidpaddle2
    Inscrit en
    Avril 2006
    Messages
    430
    Détails du profil
    Informations forums :
    Inscription : Avril 2006
    Messages : 430
    Points : 95
    Points
    95
    Par défaut
    Ben, c'est de ce BitBlt() là que je parle.
    Mais le contrôle n'est pas transparent, c'est ça que tu voulais savoir?
    Pour le rendre transparent comme le reste, je pense que remplacer le CreateSolidBrush() par un truc du genre (HBRUSH)SendMessage(GetParent(hCtrl), WM_CTLCOLORSTATIC, (WPARAM)hdc, (LPARAM)hCtrl); (je dis bien un truc du genre, car c'est de tête et c'est pas testé) devrait faire l'affaire si la fenêtre parent traite WM_CTLCOLORSTATIC comme je t'ai déjà appris à le faire.
    D'accord mais pourquoi diable veux tu rendre le controle (je suppose que tu parles de la visualisation spectrale [juste les barres]) transparent ? D'après ce que je comprends, on colle les barres rafraichies sur le bitmap avant de l'afficher non ? (après un invalidaterect bien sûr)
    En C++, il faut un cast, en C, pas besoin. Tu dois caster le retour de SelectObject() en HBITMAP (car SelectObject() retourne un HGDIOBJ qui est un void*).
    J'y ai pensé aussi. Même si cela ne se voit pas, j'ai déjà appris les bases du C++ :p Donc j'ai essayé de le transtyper en HBITMAP mais idem...
    Les accolades que j'avais mises dans les case ne sont pas décoratives.
    Au passage, les destructions d'objet doivent être mises dans le case WM_DESTROY, pas WM_CLOSE.
    Oui je sais je n'avais pas fait attention ...
    PS: Tu dois retirer l'appel à PostQuitMessage(). Seule la fenêtre principale a le droit de faire ça (comprendre "doit avoir le droit de faire ça").
    Ne fais pas attention à cela. C'est un programme de test qui affiche seulement la dialogbox. Je l'intègrerais quand il sera finis.
    Ben, c'est un bitmap à remplir juste avant de l'afficher, c'est tout...
    Oui je comprends mieux maintenant.

    Je vais m'en occuper et je poste si je n'y arrive pas.
    Vive l'embarqué.

  11. #11
    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 518
    Points
    41 518
    Par défaut
    D'accord mais pourquoi diable veux tu rendre le controle (je suppose que tu parles de la visualisation spectrale [juste les barres]) transparent ? D'après ce que je comprends, on colle les barres rafraichies sur le bitmap avant de l'afficher non ? (après un invalidaterect bien sûr)
    Ben, je m'étais inspiré de ta capture, sur laquelle l'analyseur spectral possède simplement un fond bleu.

    Le bitmap sert juste de zone de dessin hors-écran pour éviter un clignotement : Ce n'est pas un bitmap d'arrière-plan.
    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.

  12. #12
    Membre régulier Avatar de kidpaddle2
    Inscrit en
    Avril 2006
    Messages
    430
    Détails du profil
    Informations forums :
    Inscription : Avril 2006
    Messages : 430
    Points : 95
    Points
    95
    Par défaut
    D'accord ... Mais en fait le fond n'est pas bleu ... ce sont des lignes de différentes teintes de bleu faisant penser à un écran. J'ai dû faire un fond uni pour la listbox (playlist) mais l'effet n'est pas terrible... Donc quand tu parlais de la ligne de code (que tu as fait de tête) permettant de rendre transparent le controle (et donc la zone de dessin) tu parlais de ça ? Pouvoir afficher les rectangles sur un fond transparent ?

    Parce que si tu regarde bien le bitmap, le fond n'est pas bleu.
    (désolé d'être pointilleux )

    [edit] En fait en regardant je remarque que les lignes sont moins marquées que chez la playlist... je vais pouvoir utiliser ta méthode. Avec une couleur unie de cette teinte là cela devrait aller. Je m'en occupe.
    Vive l'embarqué.

  13. #13
    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 518
    Points
    41 518
    Par défaut
    Quand je parlais de code pour rendre transparent, cela permettait de rendre le contrôle perso (parce que pour moi c'est un contrôle, avec une WNDCLASS et sa WNDPROC, et non une boîte de dialogue à part entière) similaire à un static: Il aurait réagit comme un static, donc le code servant à rendre transparent un static l'aurait rendu transparent aussi.

    Mais tu peux aussi lui mettre un bitmap en fond, mais pour cela, il faudra un second bitmap et un second MemoryDC.
    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.

  14. #14
    Membre régulier Avatar de kidpaddle2
    Inscrit en
    Avril 2006
    Messages
    430
    Détails du profil
    Informations forums :
    Inscription : Avril 2006
    Messages : 430
    Points : 95
    Points
    95
    Par défaut
    En fait je combine mon code et le tien comme je l'ai fait dans ce que j'ai donné plus haut c'est ça ?
    A mon avis j'ai toutes les infos qu'il me faut. Place aux tests ...

    [edit]... ou pas. J'ai mis les accolades oubliées et les erreurs s'n trouvent sensiblement réduites : je n'ai plus que les invalid cast pour le selectobject. Mais ici, rien à faire, il refuse de le transtyper. Que cela soit (void*), ou (HGDIOBJ) il remet les erreurs.

    [reedit] J'ai été voir le prototype et en fait cela ne venait pas des arguments mais du retour. Je n'y avais à vrai dire pas pensé. (quel crétin)Donc voici les nouvelles : avec le code ci dessous, j'obtiens un visualiseur parfait, sauf que ... le bitmap ne s'affiche pas. Le fond est de la couleur sélectionnée dans CreateSolidBrush() et donc du Bk. (cad noire)

    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
    BOOL APIENTRY SpectrumProc(HWND hDlg,UINT uMsg,WPARAM wParam,LPARAM lParam)
    {
        static float *oldSpectrum = NULL, finalSpectrum[BARS_NUMBER] = {0.0};
        static HBITMAP BarBmp = (HBITMAP)LoadImage(hInst, "E:/Dune/Untitled2.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
        static HRGN region = BmpToRgn(BarBmp,RGB(0,0,0));
        static HBITMAP s_hOldBmp = NULL;
        static HDC s_hMemDC = NULL;
        static HBRUSH s_hBack = NULL;
    
        switch (uMsg)
        {
            case WM_INITDIALOG:
            {
                SetWindowRgn(hDlg,region,TRUE);
    
                RECT r;
                HDC hdc = GetDC(NULL);
                HBITMAP hBmp = NULL;
    
                GetClientRect(hDlg,&r);
                hBmp = CreateCompatibleBitmap(hdc, r.right, r.bottom);
                s_hMemDC = CreateCompatibleDC(hdc);
                ReleaseDC(NULL, hdc);
    
                s_hOldBmp = (HBITMAP)SelectObject(s_hMemDC, (HGDIOBJ)hBmp);
                s_hBack = CreateSolidBrush(RGB(0,0,0));
    
                SetTimer(hDlg, 0, 0, (TIMERPROC)NULL);
                break;
            }
            case WM_PAINT :
            {
                RECT r;
                GetClientRect(hDlg, &r);
                FillRect(s_hMemDC, &r, s_hBack);
                refreshBars(s_hMemDC, finalSpectrum);
                    {
                    PAINTSTRUCT ps;
                    HDC hdc = BeginPaint(hDlg, &ps);
    
                    BitBlt(hdc, 0, 0, r.right, r.bottom, s_hMemDC, 0, 0, SRCCOPY);
    
                    EndPaint(hDlg, &ps);
                    }
            }
            break;
    
            case WM_TIMER:
                if(IsWindowVisible(hDlg))
                {   oldSpectrum = FSOUND_DSP_GetSpectrum();
                    adaptSpectrum(oldSpectrum, finalSpectrum);
    
                    InvalidateRect(hDlg, NULL, FALSE);
                }
                break;
    
            case WM_CLOSE:
                HBITMAP hBmp = (HBITMAP)SelectObject(s_hMemDC, (HGDIOBJ)s_hOldBmp);
                s_hOldBmp = NULL;
                DeleteObject(hBmp);
                DeleteDC(s_hMemDC), s_hMemDC=NULL;
                DeleteObject(s_hBack), s_hBack=NULL;
                //ShowWindow (hDlg,SW_HIDE);
                PostQuitMessage(0);
                break;
    
          default:
             return FALSE;
        }
    
        return TRUE;
    }
    Pourquoi cela ne marche t il pas ?
    Vive l'embarqué.

  15. #15
    Membre régulier Avatar de kidpaddle2
    Inscrit en
    Avril 2006
    Messages
    430
    Détails du profil
    Informations forums :
    Inscription : Avril 2006
    Messages : 430
    Points : 95
    Points
    95
    Par défaut
    Up
    Vive l'embarqué.

  16. #16
    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 518
    Points
    41 518
    Par défaut
    J'avais opas vu ton edit.
    Le bitmap d'arrière-plan que tu veux afficher est donc spécifique à ton contrôle, si j'ai bien compris, il n'est donc pas transparent (tant mieux, ce sera plus simple).

    Ton fameux bitmap d'arrière-plan, c'est BarBmp, c'est ça?
    Eh bien il te manque encore un MemoryDC pour ce bitmap.
    Comme je te l'ai dit, il te faut un second MemoryDC (static lui aussi), et tu n'en as qu'un pour l'instant.
    Tu n'as qu'à créer le second en même temps que le premier dans le traitement de WM_INITDIALOG (à remplacer par WM_CREATE si tu en fais un contrôle) et sélectionner directement BarBmp dedans.

    Dans le WM_PAINT, tu remplaces le FillRect() par un BitBlt de ton bitmap, toujours vers s_hMemDC. Tu peux aussi le mettre juste après le FillRect(), comme ça tu auras quand même une couleur de fond même si le chargement de l'image échoue.

    PS: Si tu n'utilises plus hBack, tu pourras le supprimer.
    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.

  17. #17
    Membre régulier Avatar de kidpaddle2
    Inscrit en
    Avril 2006
    Messages
    430
    Détails du profil
    Informations forums :
    Inscription : Avril 2006
    Messages : 430
    Points : 95
    Points
    95
    Par défaut
    Ca yest j'ai ajouté cette modification, (et j'ai enfin compris ) et cela marche parfaitement !
    Y a pas à dire, tu as vraiment réponse à tout

    Merci pour ta patience. [Topic résolu]
    Vive l'embarqué.

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

Discussions similaires

  1. Question existentielle, pour une fois
    Par Sunchaser dans le forum La taverne du Club : Humour et divers
    Réponses: 26
    Dernier message: 14/11/2011, 12h42
  2. j'ai une petite question pour l'opérateur >>=
    Par PIC16F877A dans le forum Débuter
    Réponses: 2
    Dernier message: 08/03/2010, 06h50
  3. une petite question pour creer un site
    Par lyam_3 dans le forum Débuter
    Réponses: 88
    Dernier message: 27/03/2008, 10h22
  4. une toute petits aide pour finaliser tout sa
    Par yoan_111 dans le forum ASP
    Réponses: 6
    Dernier message: 16/12/2005, 16h04
  5. Petite question pour Backup
    Par chicken92000 dans le forum Administration
    Réponses: 2
    Dernier message: 16/09/2004, 16h10

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