VC++ CImageFactory类加载ICON资源文件失败

今天设计CSWComboBox控件发现CImageFactory类接口加载系统ICON资源文件失败,几经周折找到了几种解决方案,其一可以将资源文件类型ICON,改为非系统默认类型(比如MICON,ICON1等等);或者修改代码如下:

Bitmap*	CImageFactory::GetSkinItemImage(UINT uiResID, LPCTSTR lpszResType)
{
	ImgResource* pImgResource = NULL;
	std::map<UINT, ImgResource*>::iterator iter;
	iter = m_mapSkinResItems.find(uiResID);
	if (iter == m_mapSkinResItems.end())
	{
		HINSTANCE hInst = AfxGetResourceHandle();
// 		HINSTANCE hInst = AfxGetInstanceHandle();
// 		HINSTANCE hInst = AfxFindResourceHandle(MAKEINTRESOURCE(uiResID)); 
// 		HINSTANCE hInst = GetModuleHandle(NULL);

		HRSRC hResrc = ::FindResource(hInst, MAKEINTRESOURCE(uiResID), lpszResType);
		if (hResrc == NULL)
		{
			TRACE("%d\n", GetLastError());
			if (lpszResType == RT_ICON)
			{
				HICON hIcon = ::LoadIcon(hInst, MAKEINTRESOURCE(uiResID));
				if (hIcon)
				{
					pImgResource = new ImgResource();
					pImgResource->pImage = (Gdiplus::Bitmap*)Bitmap::FromHICON(hIcon);
					Gdiplus::Status result = pImgResource->pImage->GetLastStatus();
					if (result == Gdiplus::Ok)
					{
						m_mapSkinResItems[uiResID] = pImgResource;
						return pImgResource->pImage;
					}
				}
			}
			else if (lpszResType == RT_BITMAP)
			{
				HBITMAP hBitmap = ::LoadBitmap(hInst, MAKEINTRESOURCE(uiResID));
				if (hBitmap)
				{
					pImgResource = new ImgResource();
					//pImgResource->pImage = (Gdiplus::Bitmap*)Bitmap::FromHBITMAP(hBitmap, NULL);// 如果hBitmap存在透明度,上面方法就是丢失掉图像中的Alpha信息,具有透明度的像素点将显示黑色
                                        pImgResource->pImage = (Gdiplus::Bitmap*)this->GetSkinItemImage(hBitmap);
					Gdiplus::Status result = pImgResource->pImage->GetLastStatus();
					if (result == Gdiplus::Ok)
					{
						m_mapSkinResItems[uiResID] = pImgResource;
						return pImgResource->pImage;
					}
				}
			}

			return NULL;
		}

		DWORD dwSize = SizeofResource(hInst, hResrc);
		HGLOBAL hGlobal = LoadResource(hInst, hResrc);
		if (hGlobal == NULL)
			return NULL;

		BYTE* lpResrc = (BYTE*)LockResource(hGlobal);
		if (lpResrc == NULL)
			return NULL;

		pImgResource = new ImgResource();
		HGLOBAL hAllocMem = GlobalAlloc(GMEM_FIXED, dwSize);
		BYTE* pMem = (BYTE*)GlobalLock(hAllocMem);
		memcpy(pMem, lpResrc, dwSize);
		IStream* pStream = NULL;
		CreateStreamOnHGlobal(hAllocMem, FALSE, &pStream);
		pImgResource->pImage = (Gdiplus::Bitmap*)Bitmap::FromStream(pStream);
		Gdiplus::Status result = pImgResource->pImage->GetLastStatus();
		if (result == Gdiplus::Ok)
		{
			pStream->Release();
			GlobalUnlock(hAllocMem);
			GlobalFree(hAllocMem);
			m_mapSkinResItems[uiResID] = pImgResource;
			return pImgResource->pImage;
		}
		else
		{
			pStream->Release();
			GlobalUnlock(hAllocMem);
			GlobalFree(hAllocMem);
			if (lpszResType == RT_GROUP_ICON)
			{
				HICON hIcon = LoadIcon(hInst, MAKEINTRESOURCE(uiResID));
				if (hIcon)
				{
					pImgResource->pImage = (Gdiplus::Bitmap*)Bitmap::FromHICON(hIcon);
					Gdiplus::Status result = pImgResource->pImage->GetLastStatus();
					if (result == Gdiplus::Ok)
					{
						pStream->Release();
						GlobalUnlock(hAllocMem);
						GlobalFree(hAllocMem);
						m_mapSkinResItems[uiResID] = pImgResource;
						return pImgResource->pImage;
					}
				}
			}
		}

		delete pImgResource->pImage;
		pStream->Release();
		GlobalUnlock(hAllocMem);
		GlobalFree(hAllocMem);
		return NULL;
	}
	else
	{
		pImgResource = iter->second;
	}

	return pImgResource->pImage;
}

新增加接口,通过HBITMAP转换获取Bitmap:

Gdiplus::Bitmap* CImageFactory::GetSkinItemImage(HBITMAP hBitmap)
{
	// 如果图像中没有透明度,调用方法如下:
	// m_pBkgrBitmap = Gdiplus::Bitmap::FromHBITMAP(hBitmap, NULL),
	// 但是如果存在透明度,上面方法就是丢失掉图像中的Alpha信息,具有透明度的像素点将显示黑色,改用如下方法:
	BITMAP bmp = { 0 };
	if (0 == GetObject(hBitmap, sizeof(BITMAP), (LPVOID)&bmp))
		return NULL;

	BYTE *piexlsSrc = NULL;
	LONG cbSize = bmp.bmWidthBytes * bmp.bmHeight;
	piexlsSrc = new BYTE[cbSize];

	BITMAPINFO bmpInfo = { 0 };
	bmpInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
	bmpInfo.bmiHeader.biWidth = bmp.bmWidth;
	bmpInfo.bmiHeader.biHeight = bmp.bmHeight;
	bmpInfo.bmiHeader.biPlanes = bmp.bmPlanes;
	bmpInfo.bmiHeader.biBitCount = bmp.bmBitsPixel;
	bmpInfo.bmiHeader.biCompression = BI_RGB;

	HDC hdcScreen = CreateDC(_T("DISPLAY"), NULL, NULL, NULL);
	LONG cbCopied = GetDIBits(hdcScreen, hBitmap, 0,
		bmp.bmHeight, piexlsSrc, &bmpInfo, DIB_RGB_COLORS);
	DeleteDC(hdcScreen);
	if (0 == cbCopied)
	{
		delete[] piexlsSrc;
		return NULL;
	}

	PixelFormat pf = bmp.bmBitsPixel == 32 ? PixelFormat32bppPARGB : PixelFormat24bppRGB;
	Bitmap *pBitmap = new Bitmap(bmp.bmWidth, bmp.bmHeight, pf);
	BitmapData bitmapData;
	Rect rect(0, 0, bmp.bmWidth, bmp.bmHeight);
	if (Ok != pBitmap->LockBits(&rect, ImageLockModeRead,
		pf, &bitmapData))
	{
		delete pBitmap;
		pBitmap = NULL;
		return NULL;
	}

	BYTE *pixelsDest = (BYTE*)bitmapData.Scan0;
	int nLinesize = (((bmp.bmBitsPixel*bmp.bmPlanes*bmp.bmWidth + 31) & ~31) >> 3);
	int nHeight = bmp.bmHeight;
	for (int y = 0; y < nHeight; y++)
	{
		memcpy_s((pixelsDest + y * nLinesize), nLinesize,
			(piexlsSrc + (nHeight - y - 1) * nLinesize), nLinesize);
	}

	if (Ok != pBitmap->UnlockBits(&bitmapData))
	{
		delete pBitmap;
		pBitmap = NULL;
	}

	delete[] piexlsSrc;
	return pBitmap;
}

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值