Избегайте повторной загрузки изображений во время прокрутки

Я строю приложение MFC 2008 mdi, которое отображает изображения. Когда я прокручиваю, все изображения должны быть перезагружены. Я стараюсь избежать этого, сохраняя файлы CPngImage и CBitmap в первый раз, а затем повторно их используя.

Оператор pngBmp[iPic].GetBitmap(&bi); вызывая перерыв во второй раз после загрузки файлов;

Может кто-то помочь мне с этим. Код указан ниже;

// Global

#define MAX_IMAGE 100

CPngImage pngImage[MAX_IMAGE];
CBitmap pngBmp[MAX_IMAGE];

    void CFileViewerView::DrawImages(CDC* pDC)
{
    CString pngPath,imageLegend;
    CDC bmDC;
    CBitmap *pOldbmp;
    BITMAP  bi;
    int xPos = marginRect.left, yPos,nPic,nPage;
    int xOffset,yOffset,imageHeight,imageWidth,numPics;
    float aspect;
    BOOL status;

    PayAppReport report = 
            projectList[m_pModeless->GetCurrentProject()].reports[m_pModeless->GetCurrentReport()];

    numPics = report.GetNumberOfPictures();
    bmDC.CreateCompatibleDC(pDC);
    imageHeight = 6500;
    //yPos = pageRect.bottom + marginRect.top;

    nPage = numPics/6;
    for(int iPic=0; iPic<numPics; iPic++)
        {
        if(!imagesLoaded)
            {
            pngPath = report.GetPictures(iPic);
            pngPath.TrimRight();

            pngImage[iPic].LoadFromFile(pngPath);
            status = pngBmp[iPic].Attach(pngImage[iPic].Detach());
            if(!status) 
                {
                CString err;
                err.Format(_T("Cannot open image file \n\r %s"),pngPath);
                MessageBox(err,_T("Image Loading Error"),MB_ICONERROR);
                return;
                }
            }
        else
            pngBmp[iPic].Attach(pngImage[iPic].Detach());

        pngBmp[iPic].GetBitmap(&bi); //   ****** ABORTS Here

        pOldbmp= bmDC.SelectObject(&pngBmp[iPic]);

        aspect = (float)bi.bmWidth / (float)bi.bmHeight;
        imageWidth = (int)(aspect*imageHeight),numPics;

        xOffset = imageWidth;
        yOffset = (int)(-imageHeight*1.20f);

        nPic = iPic;
        if(iPic > 5)
            nPic = iPic - (iPic/6)*6;

        if(nPic == 0)
            {
            xPos = marginRect.left;
            yPos = (pageRect.bottom + marginRect.top)*((iPic/6)+1);
            }
        else if(nPic < 3)
            {
            xPos = marginRect.left;
            yPos += yOffset;
            }
        else if(nPic == 3)
            {
            xPos = marginRect.right-imageWidth;
            yPos = (pageRect.bottom + marginRect.top)*((iPic/6)+1);
            }
        else if(nPic > 3 && nPic < 6)
            {
            xPos = marginRect.right-imageWidth;
            yPos += yOffset;
            }

        _ftprintf(dbgFile,_T("iPic %d nPic %d xPos %d yPos %d\n"),iPic,nPic,xPos,yPos);

        pDC->SetStretchBltMode(HALFTONE);
        SetBrushOrgEx(bmDC,0,0,NULL);
        pDC->StretchBlt(xPos,yPos,imageWidth,-imageHeight,&bmDC,0,0,bi.bmWidth, bi.bmHeight,SRCCOPY);
        bmDC.SelectObject(pOldbmp);
        pngBmp[iPic].Detach();

        imageLegend.Format(_T("Photo %2d"),iPic+1);
        CSize rSize = pDC->GetTextExtent(imageLegend, imageLegend.GetLength());
        pDC->TextOut(xPos+(imageWidth/2)-rSize.cx/2,yPos-imageHeight,imageLegend, imageLegend.GetLength());
        }
    imagesLoaded = true;
}

1 ответ

pngBmp[iPic].Attach(pngImage[iPic].Detach());

Ты звонил Detach() на pngImage, так pngImage больше не действителен В следующем звонке pngBmp будет недействительным.

pngBmp[iPic].GetBitmap(&bi); //   ****** ABORTS Here

pngBmp[iPic].GetBitmap(&bi); потерпит неудачу, если нет действительного HBITMAP

Более простое решение:

CPngImage происходит от CBitmap, это может сделать все CBitmap делает. Вы можете упростить свой код, удалив pngBmp в целом и использовать pngImage для рисования.

Вы можете проверить достоверность изображения PNG с:

if(!pngImage[index].m_hObject)
    return;
Другие вопросы по тегам