c语⾔.rc⽂件,cc++从rc资源中加载⾃定义资源_赵克⽴博客_技
术栈
对于rc资源中常见的类型:BITMAP、CURSOR和ICON,可以⽤LoadBitmap、LoadCursor和LoadIcon将它们加载到内存中,或者统⼀使⽤LoadImage
API函数也可以。但是对于⾃定义类型的PNG、ZIP(在添加⽂件到资源中时会提⽰设定资源类型),则没有专门的函数来使⽤。LoadImage 仅仅是⽀持BITMAP、CURSOR和ICON三种类型。
那应该如何将⾃定义类型的资源⽂件从rc资源加载到内存中或者导出呢?对于⾃定义类型的对象,可以使⽤FindResource、LoadResource、LockResource和SizeofResource等API函数来处理。⼤致的处理流程如下:
⾸先
先调⽤FindResource,根据资源ID和资源类型(注意:这个资源类型就是在资源中添加⽂件时提⽰输⼊的资源类型标识串,⽐如下⾯代码中的“PNG”和“ZIP”),到资源信息块句柄;然后将句柄传给LoadResource去加载资源,将资源加载到全局内存中,注意此时不能直接操作返回的内存句柄;调⽤LockResource将资源数据锁住后再使⽤内存中的数据,进⽽可以进⾏资源的数据的拷贝或导出操作了;
可以调⽤SizeofResource得到资源⽂件的⼤⼩。
然后
当然在事务处理完之后,要调⽤UnlockResource解锁,最后调⽤FreeResource将调⽤LoadResource申请的内存释放掉。
将PNG图⽚读出到CImage对象中
为了说明相关函数的使⽤⽅法,下⾯给出从rc资源加载到内存中或者导出的例⼦代码。
由于PNG图⽚可以做到很多透明效果,界⾯⽤PNG后效果⾮常好,所以现在很多软件都会使⽤到。PNG图⽚在⾼版本的VS中都使⽤CImage类来加载,相关代码如下所⽰:(代码中的lpszType
为“PNG”)CImage* CImageUtility::LoadCImage(UINT nID, LPCTSTR lpszType, HINSTANCE hInstance)
{
CImage* pImage = NULL;
/
/ 兼容bmp的加载
if (RT_BITMAP == lpszType)
{
pImage = new CImage();
pImage->LoadFromResource(hInstance, nID);
if (!pImage->IsNull())
{
return pImage;
}
else
自定义函数怎么用c语言{
delete pImage;
pImage = NULL;
return pImage;
}
}
CString strLog;
HRSRC hRsrc = ::FindResource(hInstance, MAKEINTRESOURCE(nID), lpszType); ASSERT(hRsrc != NULL);
if (NULL == hRsrc)
{
return NULL;
}
DWORD dwSize = ::SizeofResource(hInstance, hRsrc);
LPBYTE lpRsrc = (LPBYTE)::LoadResource(hInstance, hRsrc);
ASSERT(lpRsrc != NULL);
if (NULL == hRsrc)
{
return NULL;
}
// 后⾯采⽤流加载的⽅式使⽤到了CreateStreamOnHGlobal,它需要使⽤HGLOBAL内存HGLOBAL hMem = ::GlobalAlloc(GMEM_FIXED, dwSize);
if (NULL == hMem)
{
::FreeResource(lpRsrc);
return NULL;
}
LPBYTE pMem = (LPBYTE)::GlobalLock(hMem);
if (NULL == pMem)
{
::GlobalUnlock(hMem);
::GlobalFree(hMem);
::FreeResource(lpRsrc);
return NULL;
}
memcpy(pMem, lpRsrc, dwSize);
IStream * pStream = NULL;
HRESULT hr = ::CreateStreamOnHGlobal(hMem, FALSE, &pStream);
if (pStream != NULL && hr == S_OK)
{
pImage = new CImage();
HRESULT hrs = pImage->Load(pStream);
pStream->Release();
// 释放资源
::GlobalUnlock(hMem);
::GlobalFree(hMem);
::FreeResource(lpRsrc);
if (hrs == S_OK)
{
// 处理图⽚中的透明效果
if (pImage->GetBPP() == 32)
{
for (int i = 0; i GetWidth(); i++)
{
for (int j = 0; j GetHeight(); j++)
{
unsigned char* pucColor = reinterpret_cast(pImage->GetPixelAddress(i, j)); pucColor[0] = pucColor[0] * pucColor[3] / 255;
pucColor[1] = pucColor[1] * pucColor[3] / 255;
pucColor[2] = pucColor[2] * pucColor[3] / 255;
}
}
}
return pImage;
}
else
{
delete pImage;
pImage = NULL;
return pImage;
}
}
else
{ // 释放资源
::GlobalUnlock(hMem);
::GlobalFree(hMem);
::FreeResource(lpRsrc);
return NULL;
}
}
将zip压缩⽂件导出到磁盘上
对于程序安装包来说,安装到⽬标安装路径的⽂件是要放到exe安装包中的,那怎样才能塞到安装包中呢?将相关的⽂件打包成zip⽂件,作为资源添加到资源列表中,启动安装的时候再从资源中取出来,释放到磁盘上在解压,然后执⾏⽂件的拷贝操作。从资源中导出⽂件的相关代码如下所⽰:void CProcessLogic::ExportResFile(CString strExportPath)
{
// 导出system.zip
CString strSysDir = strExportPath + _T("system.zip");
HRSRC hrSrcSys = FindResource(AfxGetResourceHandle(), MAKEINTRESOURCE(IDR_ZIP_SYSDIR), _T("ZIP"));
HGLOBAL hGlobalSys = LoadResource(AfxGetResourceHandle(), hrSrcSys);
LPVOID lpGlobalSys = LockResource(hGlobalSys);
ret = 0;
if (ret = file.Open(strSysDir, CFile::modeCreate | CFile::modeWrite))
{
file.Write(lpGlobalSys, (UINT)SizeofResource(AfxGetResourceHandle(), hrSrcSys));
file.Close();
}
::UnlockResource(hGlobalSys);
::FreeResource(hGlobalSys);
}
⾄于怎么解压zip包,使⽤⽹上常⽤的unzip.cpp⽂件即可。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论