SOUI IBitmap转换为ICON

该博客介绍了如何在没有MSDN直接支持的情况下,通过自定义函数CURSORICON_LoadFromBuf从内存中的PNG数据转换为HICON。代码示例展示了如何使用SOUI库中的方法创建HICON,包括计算缓冲区大小、写入图标头信息以及处理RGB像素数据的过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在实际使用中,有的API必须要求HICON。

先上效果,这里的托盘图标是用PNG转换为ICON加载的。

上代码 :

CURSORICON_LoadFromBuf。在SOUI的Res解析代码里。翻了一下MSDN没有找到API从内存里加载为HICON的。所以只有用SOUI里的方法了。如有更好的方法忘不吝赐教。

extern HICON CURSORICON_LoadFromBuf(const BYTE* bits, DWORD filesize, INT width, INT height, BOOL fCursor, UINT loadflags);
extern HICON CURSORICON_LoadFromFile(LPCWSTR filename,
	INT width, INT height,
	BOOL fCursor, UINT loadflags);
class CRGBA2ICON
{
private:	
	SArray<IBitmap*> m_pBitmapList;
	
	size_t getBufSize()
	{
		if (m_pBitmapList.GetCount() == 0)
			return 0;
		size_t retSize = 6;
		for (int i = 0; i < m_pBitmapList.GetCount(); i++)
		{
			CSize size = m_pBitmapList[i]->Size();
			int width = size.cx;
			int height = size.cy;
			retSize += 16+40;
			retSize += height * ((width + 31) / 32 * 32 / 8 + width * 3);	//Note 4 bytes alignment
			retSize += height * width;//AND MASK
		}
		return retSize;
	}
	void writeByte(LPBYTE& data,const int val, const int byte)
	{
		memcpy(data, (void*)&val, byte);
		data += byte;
	}
	void writeByte(LPBYTE &data, LPCVOID val, const int byte)
	{
		memcpy(data,val, byte);
		data += byte;
	}
	HICON createHIcon()
	{
		if (m_pBitmapList.GetCount() == 0)
			return nullptr;
		{
			size_t bufsize = getBufSize();
			std::unique_ptr<BYTE> buffer(new BYTE[bufsize]);
			LPBYTE buf = buffer.get();			
			int x, y;
			int index = 0;
			int Size = 0;
			int offset = 6 + m_pBitmapList.GetCount() * 16;
			int bpp = 32;
			writeByte(buf, 0, 2);				//idReserved
			writeByte(buf, 1, 2);				//idType 1为图标 2为光标
			writeByte(buf, m_pBitmapList.GetCount(), 2);//idCount 图像数量
			//
			int width = 0, height = 0;
			//字入所有的头
			for (int i = 0; i < m_pBitmapList.GetCount(); i++)
			{
				CSize size = m_pBitmapList[i]->Size();
				width = size.cx;
				height = size.cy;
				//图像块16字节
				writeByte(buf, width, 1);			//bWidth
				writeByte(buf, height, 1);			//bHeight
				writeByte(buf, 0, 1);				//bColorCount
				writeByte(buf, 0, 1);				//bReserved
				writeByte(buf, 1, 2);				//wPlanes
				writeByte(buf, bpp, 2);				//wBitCount
				Size = 40 + height * ((width + 31) / 32 * 32 / 8 + width * 3);	//Note 4 bytes alignment
				Size += height * width;//AND MASK
				writeByte(buf, Size, 4);			//dwBytesInRes
				writeByte(buf, offset, 4);		//dwImageOffset
				offset += Size;
			}
			//写入实际的数据 
			for (int i = 0; i < m_pBitmapList.GetCount(); i++)
			{
				CSize size = m_pBitmapList[i]->Size();
				width = size.cx;
				height = size.cy;
				//BMP头40字节
				writeByte(buf, 40, 4);				//biSize
				writeByte(buf, width, 4);			//biWidth
				writeByte(buf, 2 * height, 4);		//biHeight 
				writeByte(buf, 1, 2);				//biPlanes
				writeByte(buf, bpp, 2);				//biBitCount
				writeByte(buf, 0, 4);				//biCompression
				writeByte(buf, 0, 4);				//biSizeImage
				writeByte(buf, 0, 4);				//biXPelsPerMeter   
				writeByte(buf, 0, 4);				//biYPelsPerMeter
				writeByte(buf, 0, 4);				//biClrUsed 
				writeByte(buf, 0, 4);				//biClrImportant

				unsigned char* data = (unsigned char*)m_pBitmapList[i]->LockPixelBits();
				// XOR mask
				for (y = height - 1; y >= 0; --y) {
					for (x = 0; x < width; ++x) {
						index = (y * width + x) * 4;
						writeByte(buf,data[index], 1);        //Blue 
						writeByte(buf,data[index + 1], 1);    //Green
						writeByte(buf,data[index + 2], 1);    //Red
						writeByte(buf,data[index + 3], 1);    //Alpha
					}
				}
				// AND mask
				for (y = 0; y < (height * ((width + 31) / 32 * 32 / 8)); ++y) {
					writeByte(buf,0, 1);
				}
			}

			/*SStringT appdir;
			appdir = SApplication::getSingleton().GetAppDir();
			std::ofstream iconfile(SStringT().Format(LR"(%s\testpic\008.icon)", appdir), std::ofstream::binary);
			iconfile.write((const char*)buffer.get(), bufsize);*/
			
			return CURSORICON_LoadFromBuf(buffer.get(), bufsize, 0,0, FALSE, LR_DEFAULTSIZE | LR_DEFAULTCOLOR);
		}
		return nullptr;
	}

public:
	HICON SaveToHICON()
	{
		return createHIcon();
	}
	void AddBitmapToIco(IBitmap* pBitmap)
	{
		pBitmap->AddRef();
		m_pBitmapList.Add(pBitmap);
	}
	void RemoveAllBitmap()
	{
		for (int i = 0; i < m_pBitmapList.GetCount(); i++)
		{
			m_pBitmapList[i]->Release();
		}
		m_pBitmapList.RemoveAll();
	}
	~CRGBA2ICON()
	{
		RemoveAllBitmap();
	}
};

源码下载 https://download.youkuaiyun.com/download/lovehuanhuan1314/15206799 不需要积分

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值