📄 bmpproc.cpp
字号:
* # 如果本身类中不存在位图,函数将返回FALSE
*
************************************************************************/
BOOL CBmpProc::CopyTranCenter(CBmpProc& souBmp,
CRect* crArea,
COLORREF crColour,
int mode)
{
if (!IsValid())
return FALSE;
ASSERT(m_pInfo);
ASSERT(m_pInfo->bmiHeader.biSize == sizeof(BITMAPINFOHEADER));
if (!souBmp.IsValid())
return FALSE;
ASSERT(souBmp.m_pInfo);
ASSERT(souBmp.m_pInfo->bmiHeader.biSize == sizeof(BITMAPINFOHEADER));
CRect rect(Rect());
if (crArea)
rect = *crArea;
// 矩形坐标规范化
rect.NormalizeRect();
if ((rect.Width()==0)||(rect.Height()==0))
return FALSE;
// 复制源图
CDC compDC;
CBitmap *pOldBmp;
// 创建与当前显示设备兼容的内存设备描述表
compDC.CreateCompatibleDC(NULL);
pOldBmp = compDC.SelectObject((CBitmap*)this);
// 复制指定尺寸的源位图到目标位图
souBmp.DrawTranCenter(compDC, &rect, crColour, mode);
compDC.SelectObject(pOldBmp);
return TRUE;
}
/*************************************************************************
*
* CopyTranTile()
*
* 参数说明:
*
* CBmpProc& souBmp - 源位图目标
* CRect* crArea - 平铺的范围(缺省值为NULL)
* COLORREF crColour - 要滤掉或保留的颜色(缺省值是白色)
* int mode - 如果是0则将不拷贝指定的颜色,如果是1则保留指定
* 的颜色(缺省值为0)
*
* 返回值:
*
* BOOL - 如果成功返回TRUE,否则返回FALSE
*
* 描述:
*
* 将源位图透明的平铺到本类的指定矩形中
*
* 如果入口参数crArea设为NULL,则平铺矩形等于本身类中图像的尺寸。
* 该函数不会拉伸或压缩源位图图像。
*
* 注:# 本身类中原来必需已存在位图,且调用之后的位图不会被删除
* # 如果源位图类是空的,则返回FALSE
* # 如果本身类中不存在位图,函数将返回FALSE
*
************************************************************************/
BOOL CBmpProc::CopyTranTile(CBmpProc& souBmp,
CRect* crArea,
COLORREF crColour,
int mode)
{
// 运行环境检测
if (!IsValid())
return FALSE;
ASSERT(m_pInfo);
ASSERT(m_pInfo->bmiHeader.biSize == sizeof(BITMAPINFOHEADER));
if (!souBmp.IsValid())
return FALSE;
ASSERT(souBmp.m_pInfo);
ASSERT(souBmp.m_pInfo->bmiHeader.biSize == sizeof(BITMAPINFOHEADER));
// 缺省情况下铺设范围就是本身位图的尺寸
CRect rect(Rect());
if (crArea)
rect = *crArea; // 另外指定尺寸
// 矩形坐标规范化
rect.NormalizeRect();
if ((rect.Width()==0)||(rect.Height()==0))
return FALSE;
// 复制源图
CDC compDC;
CBitmap *pOldBmp;
// 创建与当前显示设备兼容的内存设备描述表
compDC.CreateCompatibleDC(NULL);
pOldBmp = compDC.SelectObject((CBitmap*)this);
// 复制指定尺寸的源位图到目标位图
souBmp.DrawTranTile(compDC, &rect, crColour, mode);
compDC.SelectObject(pOldBmp);
return TRUE;
}
/*************************************************************************
*
* LoadFromClipboard()
*
* 参数说明:无
*
*
* 返回值:
*
* BOOL - 如果成功返回TRUE,否则返回FALSE
*
* 描述:
*
* 读取剪贴板中的DIB位图到类中
*
* 如果函数成功,则类中原来的位图(如果有的话)将被删除
*
************************************************************************/
BOOL CBmpProc::LoadFromClipboard()
{
// 检查剪贴板的有效性
if (!PasteAvailable())
return FALSE;
// 打开剪贴板
if (::OpenClipboard(NULL))
{
// 获取剪贴板中的DIB数据
HANDLE h = ::GetClipboardData(CF_DIB);
if (!h)
{
CloseClipboard();
return FALSE;
}
LPSTR lpDIB = (LPSTR)CreateMemoryBlockFromHandle(h);
if (!lpDIB)
{ // 读入的剪贴板数据句柄不需要释放,系统会自动释放
CloseClipboard();
return FALSE;
}
CloseClipboard();
// 检查DIB信息块的有效性
if (*((DWORD*)lpDIB) != sizeof(BITMAPINFOHEADER))
{
::free((void*)lpDIB);
return FALSE;
}
// 复制信息块
ASSERT(CalculateDIBInfoSize((LPBITMAPINFOHEADER)lpDIB) >= sizeof(BITMAPINFOHEADER));
LPBITMAPINFO pInfo = (LPBITMAPINFO)CreateMemoryBlockFromAddress(
(LPVOID)lpDIB, CalculateDIBInfoSize((LPBITMAPINFOHEADER)lpDIB));
if (!pInfo)
{
::free((void*)lpDIB);
return FALSE;
}
// 计算位数据首地址
LPSTR pBits = (LPSTR)FindDIBBits(lpDIB);
ASSERT(pBits);
// 制作DDB位图
HBITMAP hBmp;
HWND hWnd = ::GetDesktopWindow();
ASSERT(hWnd);
HDC hDC = ::GetDC(hWnd);
hBmp = ::CreateDIBitmap(hDC, // 创建DDB位图。(将DIB位数据
(BITMAPINFOHEADER *)pInfo, // 转换为DDB位数据)
CBM_INIT, pBits,
(BITMAPINFO *)pInfo,
DIB_RGB_COLORS);
::ReleaseDC(hWnd, hDC);
// 创建完逻辑位图后,从剪贴板中读取的数据已无用,释放
::free((void*)lpDIB);
if (hBmp) // 成功
{
// 删除原来的图像,并且设置新的位图
if (!ClearAndSetData(IT_CLIP,0,(LPCTSTR)"",pInfo,hBmp))
{
::free((void*)pInfo);
::DeleteObject(hBmp);
return FALSE;
}
return TRUE;
}
else // 失败
{
::free((void*)pInfo);
return FALSE;
}
}
return FALSE;
}
/*************************************************************************
*
* LoadFromFile()
*
* 参数说明:
*
* LPCTSTR lpszPathName - 待读入的位图文件名称(路径)
*
* 返回值:
*
* BOOL - 如果成功返回TRUE,否则返回FALSE
*
* 描述:
*
* 读取指定位图文件到类中
*
* 如果函数成功,则类中原来的位图(如果有的话)将被删除
* 如果入口参数指定的文件不存在或不是一个位图文件,则函数返回FALSE
*
************************************************************************/
BOOL CBmpProc::LoadFromFile(LPCTSTR lpszPathName)
{
CFile file;
LPBITMAPINFO lpbi;
LPSTR pBits;
HBITMAP hBmp;
if (!file.Open(lpszPathName, CFile::modeRead | CFile::shareDenyWrite))
return FALSE;
// 判断文件是否是有效的BMP文件
if (IsValidBmpFile(file) == FALSE)
{
file.Close();
return FALSE;
}
// 读取BMP文件信息
if ((lpbi=GetBmpFileInfo(file)) == NULL)
{
file.Close();
return FALSE;
}
// 本类不支持压缩位图,所以如果是压缩位图则返回FALSE
if ((lpbi->bmiHeader.biCompression==BI_RLE4)||(lpbi->bmiHeader.biCompression==BI_RLE8))
{
::free((void*)lpbi);
file.Close();
return FALSE;
}
// 提取BMP位数据
if ((pBits=GetBmpFileBits(file)) == NULL)
{
::free((void*)lpbi);
file.Close();
return FALSE;
}
HWND hWnd = ::GetDesktopWindow();
ASSERT(hWnd);
HDC hDC = ::GetDC(hWnd);
hBmp = ::CreateDIBitmap(hDC, // 创建DDB位图。(将DIB位数据
(BITMAPINFOHEADER *)lpbi, // 转换为DDB位数据)
CBM_INIT, pBits,
(BITMAPINFO *)lpbi,
DIB_RGB_COLORS);
::ReleaseDC(hWnd, hDC);
// 创建完逻辑位图后,从文件中读取的位数据已无用,释放
::free((void*)pBits);
file.Close();
if (hBmp) // 成功
{
// 删除原来的图像,并且设置新的位图
if (!ClearAndSetData(IT_DISKFILE,0,lpszPathName,lpbi,hBmp))
{
::free((void*)lpbi);
::DeleteObject(hBmp);
return FALSE;
}
return TRUE;
}
else // 失败
{
::free((void*)lpbi);
return FALSE;
}
}
/*************************************************************************
*
* LoadFromResourceID()
*
* 参数说明:
*
* UINT uID - 待读入的位图资源名称(标识值)
* HINSTANCE hInstance - 位图资源所在实例的句柄(如果它被设为NULL,则
* 函数将该值设为当前应用程序进程)
*
* 返回值:
*
* BOOL - 如果成功返回TRUE,否则返回FALSE
*
* 描述:
*
* 读取指定位图资源到类中
*
* 如果函数成功,则类中原来的位图(如果有的话)将被删除
*
************************************************************************/
BOOL CBmpProc::LoadFromResourceID(UINT uID, HINSTANCE hInst)
{
return LoadFromResourceName((LPCTSTR)MAKEINTRESOURCE(uID), hInst);
}
/*************************************************************************
*
* LoadFromResourceName()
*
* 参数说明:
*
* LPCTSTR lpResourceName - 待读入的位图资源名称(字符串)
* HINSTANCE hInstance - 位图资源所在实例的句柄(如果它被设为NULL,则
* 函数将该值设为当前应用程序进程)
*
* 返回值:
*
* BOOL - 如果成功返回TRUE,否则返回FALSE
*
* 描述:
*
* 读取指定位图资源到类中
*
* 如果函数成功,则类中原来的位图(如果有的话)将被删除
*
************************************************************************/
BOOL CBmpProc::LoadFromResourceName(LPCTSTR lpResourceName,
HINSTANCE hInstance)
{
HINSTANCE hInst = hInstance;
HBITMAP hBmp = NULL;
//如果入口参数hInstance是NULL,则函数将用当前应用程序进程的实例句柄
if (hInst == NULL)
hInst = ::AfxGetResourceHandle();
ASSERT(hInst);
HRSRC hSrc = ::FindResource(hInst, lpResourceName, RT_BITMAP);
BOOL bSuccess = FALSE;
if (!hSrc)
return bSuccess;
// 由LoadResource()函数读入的资源目标不需要显示的删除它,Windows
// 系统会自动删除。LockResource()锁定的资源目标也不需要显示的解锁
HGLOBAL hResData = LoadResource(hInst, hSrc);
if (hResData)
{
LPVOID lpResData = LockResource(hResData);
if (lpResData)
{
// 如果是有效的DIB资源,则资源的首位应该是BITMAPINFOHEADER
// 结构
ASSERT(*((DWORD*)lpResData) == sizeof(BITMAPINFOHEADER));
LPSTR pBits = FindDIBBits((LPSTR)lpResData);
ASSERT(pBits > (LPSTR)lpResData);
HWND hWnd = ::GetDesktopWindow();
ASSERT(hWnd);
HDC hDC = ::GetDC(hWnd);
hBmp = CreateDIBitmap(hDC, // 创建DDB位图。(将DIB位数据
(BITMAPINFOHEADER *)lpResData, // 转换为DDB位数据)
CBM_INIT, pBits,
(BITMAPINFO *)lpResData,
DIB_RGB_COLORS);
::ReleaseDC(hWnd, hDC);
if (hBmp) // 成功
{
DWORD dwInfoSize = (DWORD)((LPSTR)pBits-(LPSTR)lpResData);
ASSERT(dwInfoSize > (DWORD)(sizeof(BITMAPFILEHEADER)));
LPBITMAPINFO lpbi = (LPBITMAPINFO)CreateMemoryBlockFromAddress(
(LPVOID)NULL, dwInfoSize);
if (lpbi)
{
// 复制位图信息块,因为lpResData所指的内存不是运行时态库
// 函数分配的内存块,所以未用CreateMemoryBlockFromAddress()
// 的复制功能
::memcpy((void*)lpbi, (const void*)lpResData, dwInfoSize);
}
else
{
::DeleteObject(hBmp);
return FALSE;
}
if ((((DWORD)lpResourceName)>>16) == 0)
{// 如果指定资源时使用的是标识,则串指针的高16位是0
// 删除原来的图像,并且设置新的位图
if (!ClearAndSetData(IT_RESOURCE,(DWORD)lpResourceName,(LPCTSTR)"",lpbi,hBmp))
{
::free((void*)lpbi);
::DeleteObject(hBmp);
return FALSE;
}
}
else
{
// 删除原来的图像,并且设置新的位图
if (!ClearAndSetData(IT_RESOURCE,0, lpResourceName,lpbi,hBmp))
{
::free((void*)lpbi);
::DeleteObject(hBmp);
return FALSE;
}
}
bSuccess = TRUE;
}
}
}
return bSuccess;
}
/*************************************************************************
*
* LoadFromObject()
*
* 参数说明:
*
* CBmpProc& souBmp - 源位图目标
* CRect *pSouRect - 复制矩形
*
* 返回值:
*
* BOOL - 如果成功返回TRUE,否则返回FALSE
*
* 描述:
*
* 读取源位图目标中指定区域(矩形)的图像到类中
*
* 如果入口参数pSouRect设为NULL,则复制源目标的整个位图
* 入口参数pSouRect必须是一个正常的矩形坐标数据(即
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -