📄 dib.cpp
字号:
// dib.cpp
//
#include "stdafx.h"
#include "Finger.h"
#include "dib.h"
#include <windowsx.h>
#include <afxadv.h>
#include <io.h>
#include <errno.h>
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CDib
IMPLEMENT_DYNAMIC(CDib, CObject)
CDib::CDib()
{
m_pBMI = NULL;
m_pBits = NULL;
m_pPalette = NULL;
}
CDib::~CDib()
{
Free();
}
void CDib::Free()
{
// Make sure all member data that might have been allocated is freed.
if (m_pBits)
{
GlobalFreePtr(m_pBits);
m_pBits = NULL;
}
if (m_pBMI)
{
GlobalFreePtr(m_pBMI);
m_pBMI = NULL;
}
if (m_pPalette)
{
m_pPalette->DeleteObject();
delete m_pPalette;
m_pPalette = NULL;
}
}
LPBYTE CDib::GetPBmp()
{
return m_pBits;
}
/*************************************************************************
*
* Paint()
*
* Parameters:
*
* HDC hDC - DC to do output to
*
* LPRECT lpDCRect - rectangle on DC to do output to
*
* LPRECT lpDIBRect - rectangle of DIB to output into lpDCRect
*
* CPalette* pPal - pointer to CPalette containing DIB's palette
*
* Return Value:
*
* BOOL - TRUE if DIB was drawn, FALSE otherwise
*
* Description:
* Painting routine for a DIB. Calls StretchDIBits() or
* SetDIBitsToDevice() to paint the DIB. The DIB is
* output to the specified DC, at the coordinates given
* in lpDCRect. The area of the DIB to be output is
* given by lpDIBRect.
*
************************************************************************/
BOOL CDib::Paint(HDC hDC, LPRECT lpDCRect, LPRECT lpDIBRect) const
{
if (!m_pBMI)
return FALSE;
HPALETTE hPal = NULL; // Our DIB's palette
HPALETTE hOldPal = NULL; // Previous palette
// Get the DIB's palette, then select it into DC
if (m_pPalette != NULL)
{
hPal = (HPALETTE) m_pPalette->m_hObject;
// Select as background since we have
// already realized in forground if needed
hOldPal = ::SelectPalette(hDC, hPal, TRUE);
}
/* Make sure to use the stretching mode best for color pictures */
::SetStretchBltMode(hDC, COLORONCOLOR);
/* Determine whether to call StretchDIBits() or SetDIBitsToDevice() */
BOOL bSuccess;
if ((RECTWIDTH(lpDCRect) == RECTWIDTH(lpDIBRect)) &&
(RECTHEIGHT(lpDCRect) == RECTHEIGHT(lpDIBRect)))
bSuccess = ::SetDIBitsToDevice(hDC, // hDC
lpDCRect->left, // DestX
lpDCRect->top, // DestY
RECTWIDTH(lpDCRect), // nDestWidth
RECTHEIGHT(lpDCRect), // nDestHeight
lpDIBRect->left, // SrcX
(int)Height() -
lpDIBRect->top -
RECTHEIGHT(lpDIBRect), // SrcY
0, // nStartScan
(WORD)Height(), // nNumScans
m_pBits, // lpBits
m_pBMI, // lpBitsInfo
DIB_RGB_COLORS); // wUsage
else
bSuccess = ::StretchDIBits(hDC, // hDC
lpDCRect->left, // DestX
lpDCRect->top, // DestY
RECTWIDTH(lpDCRect), // nDestWidth
RECTHEIGHT(lpDCRect), // nDestHeight
lpDIBRect->left, // SrcX
lpDIBRect->top, // SrcY
RECTWIDTH(lpDIBRect), // wSrcWidth
RECTHEIGHT(lpDIBRect), // wSrcHeight
m_pBits, // lpBits
m_pBMI, // lpBitsInfo
DIB_RGB_COLORS, // wUsage
SRCCOPY); // dwROP
/* Reselect old palette */
if (hOldPal != NULL)
{
::SelectPalette(hDC, hOldPal, TRUE);
}
return bSuccess;
}
/*************************************************************************
*函数名:
* CreatePalette()
*
* 返回值:
*
* BOOL-----成功则为-----TRUE,否则为------FALSE
*
* 函数功能:
*
*该函数由一个已经分配了内存逻辑调色板的DIB位图生成调色板
*从DIB颜色表中读取和存储颜色值到逻辑调色板中
*然后由这个逻辑调色板创建一个调色板,最后返回调色板句柄
*这样可以使的DIB使用最好的颜色得到显示
************************************************************************/
BOOL CDib::CreatePalette()
{
if (!m_pBMI)
return FALSE;
// 获得DIB中颜色的数目
WORD wNumColors = NumColors();
if (wNumColors != 0)
{
// 为逻辑调色板分配内存块
HANDLE hLogPal = ::GlobalAlloc(GHND, sizeof(LOGPALETTE) + sizeof(PALETTEENTRY)*wNumColors);
// 如果内存不足, 则清空内存并返回--NULL
if (hLogPal == 0)
return FALSE;
LPLOGPALETTE lpPal = (LPLOGPALETTE)::GlobalLock((HGLOBAL)hLogPal);
// 设置调色板各项的版本和数目
lpPal->palVersion = PALVERSION;
lpPal->palNumEntries = (WORD)wNumColors;
for (int i = 0; i < (int)wNumColors; i++)
{
lpPal->palPalEntry[i].peRed = m_pBMI->bmiColors[i].rgbRed;
lpPal->palPalEntry[i].peGreen = m_pBMI->bmiColors[i].rgbGreen;
lpPal->palPalEntry[i].peBlue = m_pBMI->bmiColors[i].rgbBlue;
lpPal->palPalEntry[i].peFlags = 0;
}
// 创建一个调色板,并得到它的句柄
if (m_pPalette)
{
m_pPalette->DeleteObject();
delete m_pPalette;
}
m_pPalette = new CPalette;
BOOL bResult = m_pPalette->CreatePalette(lpPal);
::GlobalUnlock((HGLOBAL) hLogPal);
::GlobalFree((HGLOBAL) hLogPal);
return bResult;
}
return TRUE;
}
/*************************************************************************
*
* Width()
*
* Return Value:
*
* DWORD - width of the DIB
*
* Description:
*
* This function gets the width of the DIB from the BITMAPINFOHEADER
* width field
*
************************************************************************/
DWORD CDib::Width() const
{
if (!m_pBMI)
return 0;
/* return the DIB width */
return m_pBMI->bmiHeader.biWidth;
}
/*************************************************************************
*
* Height()
*
* Return Value:
*
* DWORD - height of the DIB
*
* Description:
*
* This function gets the height of the DIB from the BITMAPINFOHEADER
* height field
*
************************************************************************/
DWORD CDib::Height() const
{
if (!m_pBMI)
return 0;
/* return the DIB height */
return m_pBMI->bmiHeader.biHeight;
}
/*************************************************************************
*
* PaletteSize()
*
* Return Value:
*
* WORD - size of the color palette of the DIB
*
* Description:
*
* This function gets the size required to store the DIB's palette by
* multiplying the number of colors by the size of an RGBQUAD
*
************************************************************************/
WORD CDib::PaletteSize() const
{
if (!m_pBMI)
return 0;
return NumColors() * sizeof(RGBQUAD);
}
/*************************************************************************
* 函数名
*
* NumColors()
*
* 返回值:
*
* WORD -----颜色表中的颜色数
*
* 函数功能:
*
* 该函数通过获得DIB每相素的位数,来计算DIB颜色表中的颜色数
* 如果位数是1:color=2;
* 如果位数是4:color=16;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -