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 :

Fuite d'objets GDI


Sujet :

Windows

  1. #1
    Membre à l'essai
    Homme Profil pro
    Inscrit en
    Avril 2011
    Messages
    22
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Avril 2011
    Messages : 22
    Points : 14
    Points
    14
    Par défaut Fuite d'objets GDI
    Bonjour,

    J'ai un problème bizarre, j'utilise des barres d'outils créées avec CreateWindowEx déclarée comme TOLLBARCLASSNAME, CHILD de ma fenêtre principale, et je constate que le nbre d'objets GDI de mon appli augmente indéfiniment (+22 à chaque clic sur un bouton!!) même sans autre action. Je n' arrive pas à trouver d'où vient le problème, je crois que c'est connu (fuite GDI) mais il dépasse mes compétences. Je posterai le code concerné si nécessaire.
    Merci d'avance

  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 519
    Points
    41 519
    Par défaut
    Je pense qu'il va falloir poster le code en effet.
    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 à l'essai
    Homme Profil pro
    Inscrit en
    Avril 2011
    Messages
    22
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Avril 2011
    Messages : 22
    Points : 14
    Points
    14
    Par défaut Fuite objets GDI
    J'ai utilisé GDI View qui liste les objets par types. Ceux créés par l'appli ne changent pas, mais la colonne "All GDI" augmente, ce qui semble lié à la création d'icones par Windows qd on clique sur un bouton (création de l'icone "cliqué"). Mon appli charge des listes d'images extraites d'un fichier bitmap qd je crée les barres, après je ne fais plus rien sinon intercepter les WM_COMMAND des boutons dans le WinProc principal. J'ai sans doute oublié une option quelque part à la création mais je ne vois pas.

    CODE DE CREATION D'UNE DES TOOLBARS AVEC TOOLTIPS

    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
    112
    113
    114
    115
    116
    /*.............................................BARRE D'OUTILS DESSIN...........................   */
    
    HWND GenDrawBar (HWND hParent)
    {
    	TBBUTTON BtnDes[11];
        HIMAGELIST hListDessin;
        HANDLE hBitmapDessin;
        HWND hDrw, hTooltips;
        TOOLINFO ti;
        RECT rect;
    
        HINSTANCE hAppInstance=(HINSTANCE) GetWindowLongPtr(hParent, GWLP_HINSTANCE);
    
    	hDrw= CreateWindowEx(
    		WS_EX_TOOLWINDOW,
    		TOOLBARCLASSNAME,
    		NULL,
            WS_CHILD | WS_VISIBLE | CCS_NORESIZE | CCS_NODIVIDER | TBSTYLE_FLAT |TBSTYLE_TOOLTIPS,
            368,0,624,60,
    		hParent,
    		NULL,
    		hAppInstance,
    		NULL);
    
        hListDessin=ImageList_Create(32,24,ILC_COLOR32,10,0);
        hBitmapDessin=LoadImage(hAppInstance, "BarreDessin-3.bmp",IMAGE_BITMAP,288 ,24, LR_LOADFROMFILE) ;
    
        ImageList_Add(hListDessin,(HBITMAP)hBitmapDessin,NULL);
        SendMessage(hDrw,WM_USER+60,0,0);
        SendMessage(hDrw, TB_SETIMAGELIST, 0, (LPARAM) hListDessin);
    
    	    BtnDes[0].iBitmap = 0;
            BtnDes[0].idCommand = -1;
            BtnDes[0].fsState = 0;
            BtnDes[0].fsStyle = TBSTYLE_SEP;
            BtnDes[0].dwData = 0;
            BtnDes[0].iString = -1;
    
            BtnDes[1].iBitmap = 0;
            BtnDes[1].idCommand = CMD_POINT;
            BtnDes[1].fsState = TBSTATE_ENABLED;
            BtnDes[1].fsStyle = TBSTYLE_BUTTON | TBSTYLE_CHECKGROUP;
            BtnDes[1].dwData = 0;
            BtnDes[1].iString = SendMessage(hDrw, TB_ADDSTRING, 0,(LPARAM)"Point");
    
            BtnDes[2].iBitmap = 1;
            BtnDes[2].idCommand= CMD_LINE;
            BtnDes[2].fsState = TBSTATE_ENABLED;
            BtnDes[2].fsStyle = TBSTYLE_BUTTON |TBSTYLE_CHECKGROUP;
            BtnDes[2].dwData =  0;
            BtnDes[2].iString = SendMessage(hDrw, TB_ADDSTRING, 0,(LPARAM)"Ligne");
    
            BtnDes[3].iBitmap = 2;
            BtnDes[3].idCommand = CMD_CONSTRUCTLINE;
            BtnDes[3].fsState = TBSTATE_ENABLED;
            BtnDes[3].fsStyle = TBSTYLE_BUTTON | TBSTYLE_CHECKGROUP;
            BtnDes[3].dwData = 0;
            BtnDes[3].iString = SendMessage(hDrw, TB_ADDSTRING, 0,(LPARAM)"Ligne de construction");
    
            BtnDes[4].iBitmap = 3;
            BtnDes[4].idCommand = CMD_CHAIN;
            BtnDes[4].fsState = TBSTATE_ENABLED;
            BtnDes[4].fsStyle = TBSTYLE_BUTTON |TBSTYLE_CHECKGROUP;
            BtnDes[4].dwData = 0;
            BtnDes[4].iString = SendMessage(hDrw, TB_ADDSTRING, 0,(LPARAM)"Ligne chainée");
    
            BtnDes[5].iBitmap = 4;
            BtnDes[5].idCommand = CMD_RECT_CORNER;
            BtnDes[5].fsState = TBSTATE_ENABLED;
            BtnDes[5].fsStyle = TBSTYLE_BUTTON |TBSTYLE_CHECKGROUP;
            BtnDes[5].dwData = 0;
            BtnDes[5].iString = SendMessage(hDrw, TB_ADDSTRING, 0,(LPARAM)"Rectangle défini par 2 coins");
    
            BtnDes[6].iBitmap = 5;
            BtnDes[6].idCommand = CMD_RECT_CENTER;
            BtnDes[6].fsState = TBSTATE_ENABLED;
            BtnDes[6].fsStyle = TBSTYLE_BUTTON |TBSTYLE_CHECKGROUP;
            BtnDes[6].dwData = 0;
            BtnDes[6].iString = SendMessage(hDrw, TB_ADDSTRING, 0,(LPARAM)"Rectangle centré");
    
            BtnDes[7].iBitmap = 6;
            BtnDes[7].idCommand = CMD_CIRCLE_R;
            BtnDes[7].fsState = TBSTATE_ENABLED;
            BtnDes[7].fsStyle = TBSTYLE_BUTTON |TBSTYLE_CHECKGROUP;
            BtnDes[7].dwData = 0;
            BtnDes[7].iString = SendMessage(hDrw, TB_ADDSTRING, 0,(LPARAM)"Cercle défini par centre et rayon");
    
            BtnDes[8].iBitmap = 7;
            BtnDes[8].idCommand = CMD_CIRCLE_DIAM;
            BtnDes[8].fsState = TBSTATE_ENABLED;
            BtnDes[8].fsStyle = TBSTYLE_BUTTON |TBSTYLE_CHECKGROUP;
            BtnDes[8].dwData = 0;
            BtnDes[8].iString = SendMessage(hDrw, TB_ADDSTRING, 0,(LPARAM)"Cercle défini par 2 points diamétraux");
    
            BtnDes[9].iBitmap = 8;
            BtnDes[9].idCommand = CMD_POLYGON;
            BtnDes[9].fsState = TBSTATE_ENABLED;
            BtnDes[9].fsStyle = TBSTYLE_BUTTON |TBSTYLE_CHECKGROUP;
            BtnDes[9].dwData = 0;
            BtnDes[9].iString = SendMessage(hDrw, TB_ADDSTRING, 0,(LPARAM)"Polygone centré");
    
            BtnDes[10].iBitmap = 0;
            BtnDes[10].idCommand = -1;
            BtnDes[10].fsState = 0;
            BtnDes[10].fsStyle = TBSTYLE_SEP;
            BtnDes[10].dwData = 0;
            BtnDes[10].iString = -1;
    
            SendMessage(hDrw, TB_BUTTONSTRUCTSIZE, sizeof(TBBUTTON), 0);
            SendMessage(hDrw, TB_ADDBUTTONS, 11, (LPARAM)&BtnDes);
            SendMessage(hDrw, TB_AUTOSIZE, 0, 0);
    
            DeleteObject(hBitmapDessin);
           return hDrw;
    }
    Extrait du fichier resource.h definissant les messages

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    #define CMD_MOVESPLITTER 100
    
    #define CMD_ERROR    9
    #define CMD_SELECT  10
    #define CMD_POINT   11
    #define CMD_LINE    12
    #define CMD_CONSTRUCTLINE 13
    #define CMD_CHAIN         14
    #define CMD_RECT_CORNER   15
    #define CMD_RECT_CENTER   16
    #define CMD_CIRCLE_R      17
    #define CMD_CIRCLE_DIAM   18
    #define CMD_POLYGON       19
    WinProc fenetre principale:


    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
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    /* ...................................... WINPROC FENETRE PRINCIPALE .............................. */
    
    LRESULT CALLBACK WinProc (HWND hMain, UINT message, WPARAM wParam, LPARAM lParam)
    {
        char nomAppli[]="MINIDRAW", caption[128];
        static int xSplitter(200), showDlg;
        static bool init(false), splitStart(false);
        static RECT mainClient, dlgRect;  // zone client fenetre principale
    
        switch (message)     // gestion des messages
        {
            case WM_CREATE:
                cmdActive=CMD_SELECT;         // active la commande par défaut (mode sélection)
                cmdPrev=  CMD_SELECT;
                cmdName="Cmde=SELECTION";
                dlgPosition.x=5;   dlgPosition.y=150; // position par défaut des dialogbox
                break;
            case WM_SIZE:
                GetClientRect(hMain, &mainClient);    // calage des fenetres CHILD permanentes
                MoveWindow(hStatusBar, mainClient.left, mainClient.bottom+30, mainClient.right, 30, TRUE);
                MoveWindow(hPanel, mainClient.left, mainClient.top+65, xSplitter, mainClient.bottom-95, TRUE);
                MoveWindow(hSplitter, mainClient.left+xSplitter, mainClient.top+65, 5, mainClient.bottom-95, TRUE);
                MoveWindow(hGraphic, xSplitter+5, mainClient.top+65, mainClient.right-(xSplitter+5), mainClient.bottom-95, TRUE);
                if (!init) init=graphicParam.Initialize(hGraphic);   // initialise origine et zoom au démarrage
                break;
            case WM_ACTIVATE:
                    SendMessage(hStatusBar, SB_SETTEXT, (WPARAM)(INT) 6| 0, (LPARAM) cmdName);
                    SetFocus(hGraphic);
                    hInfo=NULL;    // RAZ du handle de fenetre dialog
                break;
            case WM_CLOSE:
                if (MessageBox(hMain, "Voulez vous vraiment quitter?", nomAppli, MB_YESNO | MB_ICONQUESTION )==IDYES)
                    {
                    DestroyWindow(hMain);
                    PostQuitMessage(0);
                    }
                break;
            case WM_COMMAND:
                cmdPrev=cmdActive;          // mémorise la commande actuelle
                cmdActive=LOWORD(wParam);
                switch (LOWORD(wParam))
                {
                    case IDM_NEW:
                        GetWindowText(hMain,caption,128);
                        strcat(caption," Dessin1");
                        SetWindowText(hMain,caption); //TODO appel dlg fichier
                        break;
                    case IDM_HELP:   // TODO
                        break;
                    case CMD_POINT: cmdName="Cmde=POINT"; showDlg=SW_HIDE; break;
                    case CMD_LINE:
                        cmdName="Cmde=LIGNE";
                        showDlg=SW_HIDE;
                        constructMode=false;
                        break;
                    case CMD_CHAIN:
                        cmdName="Cmde=LIGNE BRISEE";
                        showDlg=SW_HIDE;
                        constructMode=false;
                        break;
                    case CMD_CONSTRUCTLINE:
                        cmdName="Cmde=LIGNE DE CONSTRUCTION";
                        showDlg=SW_HIDE;
                        constructMode=true;
                        break;
                    case CMD_CIRCLE_R:    cmdName="Cmde=CERCLE PAR RAYON";     showDlg=SW_HIDE; break;
                    case CMD_CIRCLE_DIAM: cmdName="Cmde=CERCLE PAR DIAMETRE";  showDlg=SW_HIDE; break;
                    case CMD_RECT_CORNER: cmdName="Cmde=RECTANGLE PAR COINS";  showDlg=SW_HIDE; break;
                    case CMD_RECT_CENTER: cmdName="Cmde=RECTANGLE PAR CENTRE"; showDlg=SW_HIDE; break;
                    case CMD_POLYGON:     cmdName="Cmde= POLYGONE";            showDlg=SW_SHOW; break; // active visu dlgBox polygone
                    case CMD_ZOOM_ALL:
                        SendMessage(hGraphic,WM_COMMAND,(WPARAM) CMD_ZOOM_UPDATE, (LPARAM) ALL); // les cdes zoom sont transmises
                        cmdActive=cmdPrev;                                                       // à la fenetre graphique
                        break;                                                                   // action selon valeur de LPARAM
                    case CMD_ZOOM_UP:                                                            // les cde zoom ne changent pas
                        SendMessage(hGraphic,WM_COMMAND,(WPARAM) CMD_ZOOM_UPDATE, (LPARAM) UP);  // la dlgBox de saisie des polygones
                        cmdActive=cmdPrev;
                        break;
                    case CMD_ZOOM_DOWN:
                        SendMessage(hGraphic,WM_COMMAND, (LPARAM)CMD_ZOOM_UPDATE,(LPARAM) DOWN);
                        cmdActive=cmdPrev;
                        break;
                    case CMD_ZOOM_WIN:
                        SendMessage(hGraphic,WM_COMMAND,(WPARAM) CMD_ZOOM_UPDATE, (LPARAM) WIN);
                        cmdActive=cmdPrev;
                        break;
                }
                dlgPosition=SaveDlgPosition(hPolygonDlg);
                SetWindowPos(hPolygonDlg,HWND_TOP, dlgPosition.x,dlgPosition.y,0,0,SWP_NOSIZE); // place la dlgBox à sa dernière position
                ShowWindow(hPolygonDlg,showDlg);                                                // cache ou affiche selon commande active
                SendMessage(hStatusBar, SB_SETTEXT, (WPARAM)(INT) 6| 0, (LPARAM)cmdName);  //affiche cde active ds la StatusBar
                break;
    
            case WM_MOUSEMOVE:
                switch (cmdActive)
                {
                    case CMD_MOVESPLITTER:  // **************  déplacement du splitter
                        if (!wParam==MK_LBUTTON) break;     // on n'agit que si bouton gauche appuyé
                        xSplitter=LOWORD(lParam);           // position horizontale du curseur
                        if (xSplitter <100) xSplitter=100;                 // butee gauche
                        if (xSplitter >400) xSplitter=400;                 // butee droite
                        DynSplitter(hMain,splitStart, xSplitter);
                        if (splitStart==false) splitStart=true;
                    break;
                }
                break;
    
            case WM_LBUTTONUP:              //*************** relachement bouton gauche
                SetCursor(hCursorPrev);               // restaure le curseur
                cmdActive=cmdPrev;                    // et la commande courante
                splitStart=false;
                SendMessage(hMain,WM_SIZE,0,0);       // redimensionne les fenetres
                InvalidateRect(hGraphic, NULL, true);
                ReleaseCapture();                     //restaure la capture souris mormale
                break;
    
            default:
                return DefWindowProc (hMain, message, wParam, lParam);
        }
        return 0;
    }

  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 519
    Points
    41 519
    Par défaut
    Je m'attendais à voir l'appel à GenDrawBar() dans le case WM_CREATE...
    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 à l'essai
    Homme Profil pro
    Inscrit en
    Avril 2011
    Messages
    22
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Avril 2011
    Messages : 22
    Points : 14
    Points
    14
    Par défaut Fuite objet GDI
    A la base je crée les fenêtres dans le Main. J'ai déplacé le tout dans les WM_CREATE pour tester mais ça ne change pas le problème.

    voici le Main

    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
    #ifdef _WIN32_WINNT
    #undef _WIN32_WINNT
    #endif
    #define _WIN32_WINNT 0x500
    
    #include <windows.h>
    
    #if defined __MINGW_H
    #define _WIN32_IE 0x0400
    #endif
    //........................ bibliothèques C++
    #include <stdio.h>
    #include <iostream>
    #include <sstream>
    #include <stdlib.h>
    //........................ API windows
    #include <commctrl.h>
    #include <winuser.h>
    #include <wingdi.h>
    #include <math.h>
    //........................ headers de l'application
    #include "resource.h"
    #include "GenWindows.h"
    #include "Class2D.h"
    #include "Genclass.h"
    #include "DynFunctions.h"
    #include "Function.h"
    #include "DefList.h"
    
    LRESULT CALLBACK WinProc      (HWND hwnd,UINT message, WPARAM wParam, LPARAM lParam);
    LRESULT CALLBACK GraphicProc  (HWND hwnd,UINT message, WPARAM wParam, LPARAM lParam);
    LRESULT CALLBACK PanelProc    (HWND hwnd,UINT message, WPARAM wParam, LPARAM lParam);
    LRESULT CALLBACK SplitterProc (HWND hwnd,UINT message, WPARAM wParam, LPARAM lParam);
    
    void DefineCursors();
    
    HWND hMain, hGraphic, hPanel, hSplitter, hStatusBar, hZoomBar, hMenu, hStdBar, hDrawBar, hInfo(NULL), hPolygonDlg(NULL);
    HINSTANCE hInst;
    
    HMENU hRightClicMenu;
    
    HCURSOR hCursorCross, hCursorHelp,  hCursorArrow, hCursorDrag, hCursorPan, hCursorHand, hCursorNo;   // curseurs standard
    HCURSOR hCursorTrap,hCursorPen, hCursorPenH, hCursorPenV, hCursorMes, hCursorDim;                    // curseurs spécifiques
    HCURSOR hCursor, hCursorPrev;
    
    COLORREF colBkg(RGB(220,220,250));
    POINT dlgPosition;
    int lScreen, hScreen;
    char cmdActive, cmdPrev, keyCode;  // commande courante/précédente
    bool constructMode(false);
    char const* cmdName;
    static TGraphParam graphicParam;
    
    /*...........................................PROGRAMME PRINCIPAL................................... */
    
    int WINAPI WinMain (HINSTANCE hInst, HINSTANCE hPrevInstance, LPSTR lpszArg, int nCmdShow)
    {
        MSG message;
        INITCOMMONCONTROLSEX initCtrl;           // initialisation des COMMONCONTROL
            initCtrl.dwSize=sizeof(initCtrl);
            initCtrl.dwICC=ICC_BAR_CLASSES;
        InitCommonControlsEx(&initCtrl);
        DefineCursors();
        //................................ création des fenetres et barres principales
    
        hMain=      GenMainWindow(hInst);   
        hStatusBar= GenStatusBar(hMain);
        hStdBar=    GenStandardBar(hMain);
        hDrawBar=   GenDrawBar(hMain);
        hZoomBar=   GenZoomBar(hMain);
        hPanel=     GenPanel(hMain, PanelProc, colBkg);
        hSplitter=  GenSplitter(hMain, SplitterProc);
        hGraphic=   GenGraphic(hMain, GraphicProc, colBkg);
        hPolygonDlg=GenDialog(hGraphic, "DLG_POLYGON");
        hRightClicMenu=CreateMenu();
        ShowWindow (hMain, SW_MAXIMIZE);
        SetFocus(hGraphic);                 // active la fenetre graphique
    
        while (GetMessage (&message, NULL, 0, 0))       /* boucle de message principale */
        {
            if(!IsWindow(hInfo) || !IsDialogMessage(hInfo, &message)) // ignore les messages des Dialog
            {
                TranslateMessage(&message);
                DispatchMessage(&message);
            }
        }
        return message.wParam;
    }

  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 519
    Points
    41 519
    Par défaut
    Je ne vois rien ici qui ait l'air d'un endroit à fuites.
    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
    Membre à l'essai
    Homme Profil pro
    Inscrit en
    Avril 2011
    Messages
    22
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Avril 2011
    Messages : 22
    Points : 14
    Points
    14
    Par défaut Fuite objet GDI
    Merci d'avoir relu mon code. Je vais faire des tests sur un programme minimaliste avec differentes options à la création de la TOOLBAR. Je reviendrai ensuite. En fait le programme plante arrivé à 10000 objets, le problème semble connu en lisant les posts de différents forums, mais je n'ai trouvé nulle part de réponse satisfaisante.

  8. #8
    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 519
    Points
    41 519
    Par défaut
    Si tu mets tes toolbars en commentaire, ça donne quoi?
    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.

  9. #9
    Membre à l'essai
    Homme Profil pro
    Inscrit en
    Avril 2011
    Messages
    22
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Avril 2011
    Messages : 22
    Points : 14
    Points
    14
    Par défaut Fuite objets GDI
    En neutralisant ces 2 lignes dans le WinProc principal:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     dlgPosition=SaveDlgPosition(hPolygonDlg);
                //SetWindowPos(hPolygonDlg,HWND_TOP, dlgPosition.x,dlgPosition.y,0,0,SWP_NOSIZE); // place la dlgBox à sa dernière position
                //ShowWindow(hPolygonDlg,showDlg);                                                // cache ou affiche selon commande active
                SendMessage(hStatusBar, SB_SETTEXT, (WPARAM)(INT) 6| 0, (LPARAM)cmdName);  //affiche cde active ds la StatusBar
    Le problème disparait. Je vais approfondir pour essayer de comprendre.

    A+

  10. #10
    Membre à l'essai
    Homme Profil pro
    Inscrit en
    Avril 2011
    Messages
    22
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Avril 2011
    Messages : 22
    Points : 14
    Points
    14
    Par défaut Fuite objet GDI
    En fait la fuite se trouvait dans la procédure de la dialogBox qui rechargeait les icones à chaque appel. J'ai redéclaré les icones en STATIC et tout marche nickel. Merci et a ++

    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
    /*............................... BOITE DIALOGUE NON MODALE.........................*/
    
    
    HWND GenDialog  (HWND hOwner, char dlgName[])
    {
        HWND hDialog;
        HINSTANCE hAppInstance=(HINSTANCE) GetWindowLongPtr(hOwner, GWLP_HINSTANCE);   // récupère instance application
        hDialog=CreateDialogParam(hAppInstance, dlgName, hOwner, (DLGPROC) DlgProc, (LPARAM) NULL);
        return hDialog;
    }
    
    BOOL CALLBACK DlgProc(HWND hDlg,UINT message, WPARAM wParam, LPARAM lParam)
    {
        static int newValue;
        HINSTANCE hAppInstance=(HINSTANCE) GetWindowLongPtr(hDlg, GWLP_HINSTANCE);   // récupère instance application
        HWND hOwner=GetParent(hDlg);
        static HICON hIconError=(HICON) LoadImage(NULL, MAKEINTRESOURCE(OIC_ERROR), IMAGE_ICON, 32,32, LR_SHARED);
        static HICON hIconAppli=(HICON) LoadImage(hAppInstance, MAKEINTRESOURCE (ICO_APPLI), IMAGE_ICON, 32,32, LR_DEFAULTCOLOR);
    
        switch (message)
        {
        case WM_INITDIALOG:
    
            SetDlgItemInt(hDlg, DLG_EDIT_POLY, 6, false);  // valeur par défaut= 6 cotés
            return true;
            break;
    
        case WM_COMMAND:
    
            if (LOWORD(wParam)==DLG_EDIT_POLY && HIWORD(wParam)==EN_CHANGE)
            {
                newValue=GetDlgItemInt(hDlg,DLG_EDIT_POLY,NULL,false); // teste la valeur entrée
                if (newValue<3 || newValue>24 )
                {
                    MessageBeep(10);
                    SetDlgItemText(hDlg,DLG_TEXT_POLY,"  VALEUR \n INCORRECTE");
                    SendDlgItemMessage(hDlg, DLG_ICO_POLY, STM_SETICON,(WPARAM) hIconError, NULL);
                }
                else
                {
                    SetDlgItemText(hDlg,DLG_TEXT_POLY,"entrer une valeur \n entre 3 et 24");
                    SendDlgItemMessage(hDlg, DLG_ICO_POLY, STM_SETICON,(WPARAM) hIconAppli, NULL);
                }
            }       
            return true;
            break;
    
        case WM_CLOSE:
            EndDialog(hDlg,NULL);
            return true;
            break;
    
        default:
            return false;
        }
    
    }

  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 519
    Points
    41 519
    Par défaut
    Attention, si tu as besoin d'un cast sur ta DialogProc, c'est qu'elle est mal déclarée.

    Remplace BOOL par INT_PTR dans son prototype, tu devrais pouvoir l'utiliser sans cast.
    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
    Inactif  

    Homme Profil pro
    Ingénieur test de performance
    Inscrit en
    Décembre 2003
    Messages
    1 986
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur test de performance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 1 986
    Points : 2 605
    Points
    2 605
    Par défaut
    Bonjour.

    Il faut parfois prendre le temps de lire la documentation :

    When you are finished using a bitmap, cursor, or icon you loaded without specifying the LR_SHARED flag, you can release its associated memory by calling one of the functions in the following table :

    Bitmap : DeleteObject
    Cursor : DestroyCursor
    Icon : DestroyIcon
    source (LoadImage) : http://msdn.microsoft.com/en-us/libr...(v=vs.85).aspx

    Il est aussi possible de spécifier LR_SHARED qui peut-être intéressant, car la ressource est détruite par le système lorsqu'elle n'est plus utilisée. Un petit gain de mémoire...

    PS : c'est certainement le hIconAppli qui posait problème, pas le hIconError.

  13. #13
    Membre à l'essai
    Homme Profil pro
    Inscrit en
    Avril 2011
    Messages
    22
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Avril 2011
    Messages : 22
    Points : 14
    Points
    14
    Par défaut Fuite objet GDI
    En effet, c'est bien hIconAppli qui pausait problème. J'ai mis LR_SHARED ça marche sans le Static. Je croyais à tort que LR_SHARED était réservé aux ressources OEM.
    Merci

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

Discussions similaires

  1. objets gdi ?
    Par Pol63 dans le forum Windows Forms
    Réponses: 2
    Dernier message: 20/10/2009, 17h16
  2. bug sur un objet Gdi
    Par ____22 dans le forum MFC
    Réponses: 9
    Dernier message: 09/09/2009, 22h09
  3. Compter les Objets GDI
    Par hfranck dans le forum MFC
    Réponses: 4
    Dernier message: 02/10/2008, 10h20
  4. [VC++6]Créations de fenêtres et objets GDI
    Par Yoyo@ dans le forum MFC
    Réponses: 20
    Dernier message: 10/07/2005, 16h12
  5. [MFC] libération des objets GDI's
    Par Kevgeii dans le forum MFC
    Réponses: 5
    Dernier message: 01/02/2004, 10h37

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