Duilib资源文件详解
四种分类
enum UILIB_RESTYPE
{
UILIB_FILE=1, // 来自磁盘文件
UILIB_ZIP, // 来自磁盘zip压缩包
UILIB_RESOURCE, // 来自资源
UILIB_ZIPRESOURCE, // 来自资源的zip压缩包
};
UILIB_FILE形式加载资源
这种方式会加载存放在硬盘中的资源。
具体使用方式
CPaintManagerUI::SetResourceType(UILIB_RESOURCE);//设置资源类型
CDuiString strResourcePath = CPaintManagerUI::GetInstancePath();
strResourcePath += _T("skin\\");
CPaintManagerUI::SetResourcePath(strResourcePath.GetData());
//设置资源路径
UILIB_ZIP形式加载资源
这种方式会加载存放在硬盘中的压缩包资源。
具体使用方式
CPaintManagerUI::SetResourceType(UILIB_ZIP);//设置资源类型
CDuiString strResourcePath = CPaintManagerUI::GetInstancePath();
strResourcePath += _T("skin\\");
CPaintManagerUI::SetResourcePath(strResourcePath.GetData());
//设置资源路径
CPaintManagerUI::SetResourceZip(_T("skin.zip"), true);//设置压缩包资源,可以加上第三个密码参数(默认为NULL)
UILIB_RESOURCE形式加载资源
这种方式会加载可执行程序中的资源文件。
具体使用方式
CPaintManagerUI::SetResourceType(UILIB_RESOURCE);//设置资源类型
UILIB_ZIPRESOURCE形式加载资源
这种方式会加载可执行程序中的zip压缩文件。
具体使用方式
CPaintManagerUI::SetResourceType(UILIB_ZIPRESOURCE);//设置资源类型
HRSRC hResource = ::FindResource(CPaintManagerUI::GetResourceDll(), _T("IDR_ZIPRES"), _T("ZIPRES"));
if (hResource != NULL) {
DWORD dwSize = 0;
HGLOBAL hGlobal = ::LoadResource(CPaintManagerUI::GetResourceDll(), hResource);
if (hGlobal != NULL) {
dwSize = ::SizeofResource(CPaintManagerUI::GetResourceDll(), hResource);
if (dwSize > 0) {
CPaintManagerUI::SetResourceZip((LPBYTE)::LockResource(hGlobal), dwSize);
}
}
::FreeResource(hResource);
}
运作原理
两种ZIP资源会调用 CPaintManagerUI的SetResourceZip函数将资源加载保存
void CPaintManagerUI::SetResourceZip(LPCTSTR pStrPath, bool bCachedResourceZip, LPCTSTR password)
{
if( m_pStrResourceZip == pStrPath && m_bCachedResourceZip == bCachedResourceZip ) return;
if( m_bCachedResourceZip && m_hResourceZip != NULL ) {
CloseZip((HZIP)m_hResourceZip);
m_hResourceZip = NULL;
}
m_pStrResourceZip = pStrPath;
m_bCachedResourceZip = bCachedResourceZip;
m_pStrResourceZipPwd = password;
if( m_bCachedResourceZip ) {
CDuiString sFile = CPaintManagerUI::GetResourcePath();
sFile += CPaintManagerUI::GetResourceZip();
#ifdef UNICODE
char* pwd = w2a((wchar_t*)password);
m_hResourceZip = (HANDLE)OpenZip(sFile.GetData(), pwd);
if(pwd) {
delete[] pwd;
pwd = NULL;
}
#else
m_hResourceZip = (HANDLE)OpenZip(sFile.GetData(), password);
#endif
}
}
之后在使用字体或图片等资源时会进行类似下面加载图片的判断,
首先判断type是否为空(type为XML文件之内控件的restype属性),
如果type不为空则认为是可执行程序中的资源文件,之后将图片从资源中取出。
如果type不为空,则继续判断之前是否保存过ZIP文件名(UILIB_ZIPRESOURCE调用CPaintManagerUI::SetResourceZip(....)时会默认将ZIP文件名保存为membuffer),
如果保存过ZIP文件,则加载zip中图片资源,
如果没有保存过,则在磁盘中加载文件。
TImageInfo* CRenderEngine::LoadImage(STRINGorID bitmap, LPCTSTR type, DWORD mask, HINSTANCE instance)
{
LPBYTE pData = NULL;
DWORD dwSize = 0;
do
{
if( type == NULL ) {
CDuiString sFile = CPaintManagerUI::GetResourcePath();
if( CPaintManagerUI::GetResourceZip().IsEmpty() ) {
sFile += bitmap.m_lpstr;
HANDLE hFile = ::CreateFile(sFile.GetData(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, \
FILE_ATTRIBUTE_NORMAL, NULL);
if( hFile == INVALID_HANDLE_VALUE ) break;
dwSize = ::GetFileSize(hFile, NULL);
if( dwSize == 0 ) break;
DWORD dwRead = 0;
pData = new BYTE[ dwSize ];
::ReadFile( hFile, pData, dwSize, &dwRead, NULL );
::CloseHandle( hFile );
if( dwRead != dwSize ) {
delete[] pData;
pData = NULL;
break;
}
}
else {
sFile += CPaintManagerUI::GetResourceZip();
CDuiString sFilePwd = CPaintManagerUI::GetResourceZipPwd();
HZIP hz = NULL;
if( CPaintManagerUI::IsCachedResourceZip() ) hz = (HZIP)CPaintManagerUI::GetResourceZipHandle();
else
{
#ifdef UNICODE
char* pwd = w2a((wchar_t*)sFilePwd.GetData());
hz = OpenZip(sFile.GetData(), pwd);
if(pwd) delete[] pwd;
#else
hz = OpenZip(sFile.GetData(), sFilePwd.GetData());
#endif
}
if( hz == NULL ) break;
ZIPENTRY ze;
int i = 0;
CDuiString key = bitmap.m_lpstr;
key.Replace(_T("\\"), _T("/"));
if( FindZipItem(hz, key, true, &i, &ze) != 0 ) break;
dwSize = ze.unc_size;
if( dwSize == 0 ) break;
pData = new BYTE[ dwSize ];
int res = UnzipItem(hz, i, pData, dwSize);
if( res != 0x00000000 && res != 0x00000600) {
delete[] pData;
pData = NULL;
if( !CPaintManagerUI::IsCachedResourceZip() ) CloseZip(hz);
break;
}
if( !CPaintManagerUI::IsCachedResourceZip() ) CloseZip(hz);
}
}
else {
HINSTANCE dllinstance = NULL;
if (instance) {
dllinstance = instance;
}
else {
dllinstance = CPaintManagerUI::GetResourceDll();
}
HRSRC hResource = ::FindResource(dllinstance, bitmap.m_lpstr, type);
if( hResource == NULL ) break;
HGLOBAL hGlobal = ::LoadResource(dllinstance, hResource);
if( hGlobal == NULL ) {
FreeResource(hResource);
break;
}
dwSize = ::SizeofResource(dllinstance, hResource);
if( dwSize == 0 ) break;
pData = new BYTE[ dwSize ];
::CopyMemory(pData, (LPBYTE)::LockResource(hGlobal), dwSize);
::FreeResource(hResource);
}
} while (0);
.......
}
评论区