⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dib.cpp

📁 分布式坦克大战游戏,多机运行
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//////////////////////////////////////////////////////////////////////////
//// Clipboard support

//---------------------------------------------------------------------
//
// Function:   CopyToHandle
//
// Purpose:    Makes a copy of the DIB to a global memory block.  Returns
//             a handle to the new memory block (NULL on error).
//
// Returns:    Handle to new global memory block.
//
//---------------------------------------------------------------------

HGLOBAL CDIB::CopyToHandle()
{
    CSharedFile file;
    try
    {
        if (Save(file)==0)
            return 0;
    }
    catch (CFileException* e)
    {
        e->Delete();
        return 0;
    }
        
    return file.Detach();
}

//---------------------------------------------------------------------
//
// Function:   ReadFromHandle
//
// Purpose:    Initializes from the given global memory block.  
//
// Returns:    Number of read bytes.
//
//---------------------------------------------------------------------

DWORD CDIB::ReadFromHandle(HGLOBAL hGlobal)
{
    CSharedFile file;
    file.SetHandle(hGlobal, FALSE);
    DWORD dwResult = Read(file);
    file.Detach();
    return dwResult;
}

//////////////////////////////////////////////////////////////////////////
//// Serialization support

void CDIB::Serialize(CArchive& ar) 
{
    CFile* pFile = ar.GetFile();
    ASSERT(pFile != NULL);
    if (ar.IsStoring())
    {   // storing code
        Save(*pFile);
    }
    else
    {   // loading code
        Read(*pFile);
    }
}

//////////////////////////////////////////////////////////////////////////
//// Resource support

BOOL CDIB::ReadFromResource (UINT uResID)
{
    HINSTANCE   hInst   = AfxGetInstanceHandle();
    CString     cstrResName;
    //
    // Find the bitmap resource
    //
    cstrResName.Format ("#%d",uResID);
    HRSRC hResInfo = FindResource(hInst, cstrResName, "MY_BITMAP");
    if (!hResInfo)
    {
        TRACE("CDIB: Failed to find resource %d.\n", uResID);
        return FALSE;
    }
    //
    // Load the bitmap resource
    //
    HANDLE hRes = LoadResource(hInst, hResInfo);
    if (!hRes)
    {
        TRACE("CDIB: Failed to load resource %d.\n", uResID);
        return FALSE;
    }
    //
    // Lock the bitmap resource
    //
    PBYTE lpRes = (PBYTE)LockResource(hRes);
    if (!lpRes)
    {
        TRACE("CDIB: Failed to lock resource.\n");
        FreeResource(hRes);
        return FALSE;
    }
    DWORD dwResSize = SizeofResource (hInst, hResInfo);
    CMemFile memFile (lpRes, dwResSize);
    DWORD dwBytesRead = Read (memFile);
    FreeResource (hRes);
    return (dwResSize == dwBytesRead);
}       

//////////////////////////////////////////////////////////////////////////
//// Misc support

BOOL CDIB::CreateEmpty (UINT uXSize, UINT uYSize)
{
    Free ();

    m_pBMI = (LPBITMAPINFO)GlobalAllocPtr(GHND, sizeof(BITMAPINFOHEADER) + 256*sizeof(RGBQUAD));
    if (NULL == m_pBMI)
        return FALSE;
    // Clear palette to black
    memset (m_pBMI->bmiColors, 120, 256 * sizeof(RGBQUAD));
    DWORD dwBmBitsSize = WIDTHBYTES(uXSize*((DWORD)8)) * uYSize;

    m_pBMI->bmiHeader.biSize = sizeof (BITMAPINFOHEADER);
    m_pBMI->bmiHeader.biWidth = uXSize;
    m_pBMI->bmiHeader.biHeight = uYSize;
    m_pBMI->bmiHeader.biPlanes = 1;
    m_pBMI->bmiHeader.biBitCount = 8;
    m_pBMI->bmiHeader.biCompression = BI_RGB;
    m_pBMI->bmiHeader.biSizeImage = dwBmBitsSize;
    m_pBMI->bmiHeader.biXPelsPerMeter = 100;
    m_pBMI->bmiHeader.biYPelsPerMeter = 100;
    m_pBMI->bmiHeader.biClrUsed = 256;
    m_pBMI->bmiHeader.biClrImportant = 256;
    m_pBits = (LPBYTE)GlobalAllocPtr(GHND, dwBmBitsSize);
    if (NULL == m_pBits)
    {
        GlobalFreePtr (m_pBMI);
        return FALSE;
    }
    // Clear image to black
    memset (m_pBits, 0, dwBmBitsSize);
    return TRUE;
}

DWORD CDIB::CalcImageSize()
{
    if ((m_pBMI->bmiHeader.biCompression == BI_RLE8) || (m_pBMI->bmiHeader.biCompression == BI_RLE4))
    {
        // It's an RLE bitmap, we can't calculate size, so trust the
        // biSizeImage field
    }
    else
    {
        DWORD dwBmBitsSize;  // Size of Bitmap Bits only
        // It's not RLE, so size is Width (DWORD aligned) * Height
        dwBmBitsSize = WIDTHBYTES((m_pBMI->bmiHeader.biWidth)*((DWORD)m_pBMI->bmiHeader.biBitCount)) * 
                                   m_pBMI->bmiHeader.biHeight;
        // Now, since we have calculated the correct size, why don't we
        // fill in the biSizeImage field (this will fix any .BMP files which
        // have this field incorrect).
        m_pBMI->bmiHeader.biSizeImage = dwBmBitsSize;
    }
    return m_pBMI->bmiHeader.biSizeImage;
}


void CDIB::FillSolidColor (BYTE R, BYTE G, BYTE B)
{
    DWORD dwImageSize = CalcImageSize();
    if (256<=NumColors())
    {   // Palette based DIB
        PIXEL ColorInd = PIXEL(m_pPalette->GetNearestPaletteIndex(RGB(R, G, B)));
        memset (m_pBits, ColorInd, dwImageSize);
    }
    // We don't support non-palette DIBs for now
}

BOOL CDIB::CopyRectFrom (
    CDIB *pSrcDIB, 
    int SrcX, 
    int SrcY, 
    UINT SrcWidth, 
    UINT SrcHeight,
    int DstX, int DstY
)
{
    if ((DstX >= int(Width())) || (DstY >= int(Height())))
        return FALSE;     // Completely out of region
    if ((DstX + int(SrcWidth) < 0) || (DstY + int(SrcHeight)) < 0)
        return FALSE;     // Completely out of region
    if (NumColors() != pSrcDIB->NumColors())
        return FALSE;     // Must have same color depth
    if (NumColors() > 256)
        return FALSE;     // We currently don't support DIBs without palettes
    if (DstX < 0)
    {
        SrcWidth += DstX;
        SrcX -= DstX;
        DstX = 0;
    }
    if (DstY < 0)
    {
        SrcHeight += DstY;
        SrcY -= DstY;
        DstY = 0;
    }

    DWORD dwSrcDIBWidth = pSrcDIB->Width();
    DWORD dwSrcDIBHeight = pSrcDIB->Height();
    DWORD dwMyWidth = Width();

    ASSERT ((SrcX < int(dwSrcDIBWidth)) &&
            (SrcY < int(dwSrcDIBHeight)));
    ASSERT ((SrcX >= 0) && (SrcY >= 0));

    SrcWidth = min (SrcWidth, UINT(dwMyWidth) - DstX);
    SrcWidth = min (SrcWidth, UINT(dwSrcDIBWidth) - SrcX);
    SrcHeight = min (SrcHeight, UINT(Height()) - DstY);
    SrcHeight = min (SrcHeight, UINT(dwSrcDIBHeight) - SrcY);

    PPIXEL pSrc = pSrcDIB->FindPixel(SrcX, SrcY);
    PPIXEL pDst = FindPixel(DstX, DstY);

    DWORD SrcInc = WIDTHBYTES(dwSrcDIBWidth << 3);
    DWORD DstInc = WIDTHBYTES(dwMyWidth << 3);

    for (UINT uCurHeight = 0; uCurHeight < SrcHeight; uCurHeight++)
    {
        memcpy (pDst, pSrc, SrcWidth);
        pDst+= DstInc;
        pSrc+= SrcInc;
    }
    return TRUE;
}

BOOL CDIB::CopyFrom (CDIB *pSrc)
{
    DWORD dwWidth = Width(),
          dwHeight= Height();
    if (NULL == pSrc)
        return FALSE;   // Bad Src
    if ((dwWidth != pSrc->Width()) ||
        (dwHeight != pSrc->Height()) ||
        (NumColors() != pSrc->NumColors())
       )
        return FALSE;   // Bad size or color depth
    memcpy (m_pBits, pSrc->m_pBits, m_pBMI->bmiHeader.biSizeImage);
    return TRUE;
}

void CDIB::PasteCKRect (CDIB *Dib, int x, int y, PIXEL ColorKey)
{
    // Clip Rect
    int px,py,dx,dy,
        mw = Width(),         // My width
        mh = Height(),        // My height
        ow = Dib->Width(),    // Other's width
        oh = Dib->Height();   // Other's height
    if (x >= 0)
    {
        px = x;
        dx = ((x + ow) < mw) ? ow : mw - x;
    }
    else
    {
        px = 0;
        dx = x + (((x + ow) < mw) ? ow : mw - x);
    }
    if (y >= 0)
    {
        py = y;
        dy = ((y + oh) < mh) ? oh : mh - y;
    }
    else
    {
        py = 0;
        dy = y + (((y + oh) < mh) ? oh : mh - y);
    }    
    // If Nothing to Paste return
    if ( (dx <= 0) || (dy <= 0) )
        return;
    // Prepare Buffer Addresses
    PPIXEL src = Dib->FindPixel (px-x, py-y);
    PPIXEL dst = FindPixel (px, py);
    DWORD SrcInc = WIDTHBYTES(ow << 3);
    DWORD DstInc = WIDTHBYTES(mw << 3);
    // Do Paste
    while ( dy-- )
    {
        for ( int i=0; i<dx; i++ )
            if (src[i] != ColorKey)
                dst[i]=src[i];
        src+=SrcInc;
        dst+=DstInc;
    }
}

void CDIB::FillRect (int x, int y, int w, int h, int R, int G, int B )
{
    // Clip Rect
    int iWidth = int(Width());
    int iHeight = int(Height());
    int px=(x>=0) ? x : 0;
    int py=(y>=0) ? y : 0;
    int dx=((x+w)<iWidth) ? w : iWidth-x;
    int dy=((y+h)<iHeight) ? h : iHeight-y;
    dx=(x>=0) ? dx : dx + x;
    dy=(y>=0) ? dy : dy + y;
    // If Nothing to Fill return
    if ( (dx<=0) || (dy<=0) )
        return;
    // Prepare Buffer Address
    PPIXEL dst = FindPixel (px, py);
    PIXEL ColorInd = PIXEL(m_pPalette->GetNearestPaletteIndex(RGB(R, G, B)));
    DWORD DstInc = WIDTHBYTES(iWidth << 3);
    // Do Fill
    while ( dy-- )
    {
        memset (dst, ColorInd, dx);
        dst+=DstInc;
    }
}

BOOL CDIB::CreateRotated (CDIB *pSrc, UINT uAngle /* 0, 90, 180 or 270 only */, BOOL bFlipHoriz, BOOL bFlipVert)
{
    ASSERT (uAngle == 0 || uAngle == 90 || uAngle == 180 || uAngle == 270);

    UINT uSrcWidth = pSrc->Width();
    UINT uSrcHeight= pSrc->Height();
    UINT uDstWidth;
    UINT uDstHeight;

    if (uAngle == 180)
        return CreateRotated (pSrc, 0, !bFlipHoriz, !bFlipVert);
    if (uAngle == 270)
        return CreateRotated (pSrc, 90, !bFlipHoriz, !bFlipVert);

    BOOL bSuccess;
    if (uAngle == 0)
    {
        bSuccess = CreateEmpty (uSrcWidth, uSrcHeight);
        uDstWidth = uSrcWidth;
        uDstHeight = uSrcHeight;
    }
    else
    {
        bSuccess = CreateEmpty (uSrcHeight, uSrcWidth);
        uDstWidth = uSrcHeight;
        uDstHeight = uSrcWidth;
    }
    if (!bSuccess)
        return FALSE;   // Can't create

    for (int x = 0; x < int(uDstWidth); x++)
        for (int y = 0; y < int(uDstHeight); y++)
            switch (uAngle)
            {
                case   0:
                    ColorAt (x, y) = pSrc->ColorAt ((bFlipHoriz ? uDstWidth-1-x : x), (bFlipVert ? uDstHeight-1-y : y));
                    break;
                case 90:
                    ColorAt (x, y) = 
                        pSrc->ColorAt ((bFlipVert  ? uSrcWidth-1-y : y), (bFlipHoriz ? x : ( uSrcHeight-1-x )));
                    break;
                default:
                    ASSERT (FALSE);
            }
    return TRUE;
}                        

BOOL CDIB::CopyPalette (CDIB *pSrc)
{
    if ((NULL == pSrc) || (NULL == pSrc->m_pPalette))
        return FALSE;   // Bad source or source has no palette
    BOOL bRes = CopyPalette (pSrc->m_pPalette);
    if (bRes)
    {
        memcpy (m_pBMI->bmiColors, pSrc->m_pBMI->bmiColors, 256 * sizeof (RGBQUAD));
    }
    return bRes;
}

BOOL CDIB::CopyPalette (CPalette *pPal)
{
    if (NULL == pPal)
        return FALSE;
    if (m_pPalette)
    {
        m_pPalette->DeleteObject();
        delete m_pPalette;
        m_pPalette = NULL;
    }
    UINT uNumColors = pPal->GetEntryCount();
    // allocate memory block for logical palette
    HANDLE hLogPal = ::GlobalAlloc(GHND, sizeof(LOGPALETTE) + sizeof(PALETTEENTRY)*uNumColors);
    // if not enough memory, clean up and return NULL
    if (hLogPal == 0)
        return FALSE;
    LPLOGPALETTE lpPal = (LPLOGPALETTE)::GlobalLock((HGLOBAL)hLogPal);
    // set version and number of palette entries
    lpPal->palVersion = PALVERSION;
    lpPal->palNumEntries = (WORD)uNumColors;
    UINT uCount = pPal->GetPaletteEntries(0, uNumColors, lpPal->palPalEntry);
    if (uCount != uNumColors)
    {
        ::GlobalUnlock((HGLOBAL) hLogPal);
        ::GlobalFree((HGLOBAL) hLogPal);
        return FALSE;
    }
    m_pPalette = new CPalette;
    BOOL bResult = m_pPalette->CreatePalette(lpPal);
    ::GlobalUnlock((HGLOBAL) hLogPal);
    ::GlobalFree((HGLOBAL) hLogPal);
    return bResult;
}

BOOL CDIB::GetPaletteFromResourceBitmap (UINT uResID)
{
    CDIB tmpDIB;

    if (!tmpDIB.ReadFromResource(uResID))
        return FALSE;
    return CopyPalette (&tmpDIB);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -