Search code examples
c++visual-studiomfcpicturebox

mfc picture control disappears after multiple runs


I am using picture control to display four small colored bmps. I have a member function that sets the bmp to the color I want. The problem is when I run my function SetColor multiple times with the test button click function the picture control disappears and the dialog acts weird such as not having a boarder when dragged. Any help or suggestions would be appreciated.

    void CRLoaderDlg::SetColor(int ColorID, int PictureID) {
    // data structure for picture/PictureID arrangement
    CStatic *pointertopicture[4];

    // check for PictureID boundary
    if (PictureID < 0 || PictureID > 3) {
        MessageBox("PictureID out of bounds", "Error", NULL);
        return; // exit function
    }

    // idc_picturecontrol is the picture control id of the dialog
    pointertopicture[0] = (CStatic*)GetDlgItem(IDC_PICTURECONTROL0);
    pointertopicture[1] = (CStatic*)GetDlgItem(IDC_PICTURECONTROL1);
    pointertopicture[2] = (CStatic*)GetDlgItem(IDC_PICTURECONTROL2);
    pointertopicture[3] = (CStatic*)GetDlgItem(IDC_PICTURECONTROL3);

    // handle for bitmap
    HBITMAP redbmp;     // color id is 0
    HBITMAP orangebmp;  // color id is 1
    HBITMAP yellowbmp;  // color id is 2
    HBITMAP greenbmp;   // color id is 3
    HBITMAP bluebmp;    // color id is 4
    HBITMAP purplebmp;  // color id is 5
    HBITMAP whitebmp;   // color id is 6
    HBITMAP blackbmp;   // color id is 7
    HBITMAP greybmp;    // color id is 8

    // set handle for bitmap with function loadimage to specified image + path (path optional)
    redbmp =    (HBITMAP)LoadImage(NULL, "sred.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
    orangebmp = (HBITMAP)LoadImage(NULL, "sorange.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
    yellowbmp = (HBITMAP)LoadImage(NULL, "syellow.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
    greenbmp =  (HBITMAP)LoadImage(NULL, "sgreen.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
    bluebmp =   (HBITMAP)LoadImage(NULL, "sblue.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
    purplebmp = (HBITMAP)LoadImage(NULL, "spurple.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
    whitebmp =  (HBITMAP)LoadImage(NULL, "swhite.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
    blackbmp =  (HBITMAP)LoadImage(NULL, "sblack.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
    greybmp =   (HBITMAP)LoadImage(NULL, "sgrey.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);

    // function to set bitmap image to handle of image
    if (ColorID == 0) pointertopicture[PictureID]->SetBitmap(redbmp);
    else if (ColorID == 1) pointertopicture[PictureID]->SetBitmap(orangebmp);
    else if (ColorID == 2) pointertopicture[PictureID]->SetBitmap(yellowbmp);
    else if (ColorID == 3) pointertopicture[PictureID]->SetBitmap(greenbmp);
    else if (ColorID == 4) pointertopicture[PictureID]->SetBitmap(bluebmp);
    else if (ColorID == 5) pointertopicture[PictureID]->SetBitmap(purplebmp);
    else if (ColorID == 6) pointertopicture[PictureID]->SetBitmap(whitebmp);
    else if (ColorID == 7) pointertopicture[PictureID]->SetBitmap(blackbmp);
    else if (ColorID == 8) pointertopicture[PictureID]->SetBitmap(greybmp);
    }

    // run SetColor function 50 times
    void CRLoaderDlg::OnBnClickedButtonTest() {
        for (int i = 0; i < 50; i++) {
            for (int c = 0; c < 9; c++) {
                for (int p = 0; p < 4; p++) {
                    SetColor(c, p);
                }
            }
        }
    }

Solution

  • You have GDI resource leak, since you don't delete old bitmaps. Delete them with DeleteObject. SetBitmap returns old HBITMAP for that reason that you could delete old HBITMAP if it is not NULL.

    Having GDI leak may cause painting issues as you've observed, when you get out of GDI resources available.