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

📄 bmpproc.cpp

📁 超强的图形界面聊天软件.rar
💻 CPP
📖 第 1 页 / 共 5 页
字号:
 *	   # 如果本身类中不存在位图,函数将返回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 + -