因为工作上的需要,开发了个小插件,然后对比较好的小伙伴可能会悄悄分享给他们用,也不想声张,反正又没有额外奖励。考虑到小伙伴的编程水平几乎是0(虽然大学都教了C语言),本人的编程水平经过这几年的磨练应该有0.2了吧……所以还是想办法把插件调用的资源全部整合在一个文件里,后面给小伙伴用的时候就不用再折腾什么了。
1个文件都还不会用,那也别好意思说自己学过编程了。
作为新手,关于资源的调用我也是初学,以为网上有视频资源,结果搜不到,然后就只有从图文教程出发了。一开始也找不到搜索关键词,经过三天的摸索,一个坑一个坑地踩,总算是迎来了曙光。
主要参考的文献名称为《编程实现自定义资源释放》、《将文件作为资源存储与释放的技术》,主要代码如下:
程序逻辑:
BOOL FreeMyResource(UINT uiResouceName, char *lpszResourceType, char *lpszSaveFileName)
{
// 获取指定模块里的指定资源
HRSRC hRsrc = ::FindResource(NULL, MAKEINTRESOURCE(uiResouceName), lpszResourceType);
if (NULL == hRsrc)
{
FreeRes_ShowError("FindResource");
return FALSE;
}
// 获取资源的大小
DWORD dwSize = ::SizeofResource(NULL, hRsrc);
if (0 >= dwSize)
{
FreeRes_ShowError("SizeofResource");
return FALSE;
}
// 将资源加载到内存里
HGLOBAL hGlobal = ::LoadResource(NULL, hRsrc);
if (NULL == hGlobal)
{
FreeRes_ShowError("LoadResource");
return FALSE;
}
// 锁定资源
LPVOID lpVoid = ::LockResource(hGlobal);
if (NULL == lpVoid)
{
FreeRes_ShowError("LockResource");
return FALSE;
}
// 保存资源为文件
FILE *fp = NULL;
fopen_s(&fp, lpszSaveFileName, "wb+");
if (NULL == fp)
{
FreeRes_ShowError("LockResource");
return FALSE;
}
fwrite(lpVoid, sizeof(char), dwSize, fp);
fclose(fp);
return TRUE;
}
程序调用测试:
BOOL FreeMyResource(UINT uiResouceName, char *lpszResourceType, char *lpszSaveFileName)
{
// 获取指定模块里的指定资源
HRSRC hRsrc = ::FindResource(NULL, MAKEINTRESOURCE(uiResouceName), lpszResourceType);
if (NULL == hRsrc)
{
FreeRes_ShowError("FindResource");
return FALSE;
}
// 获取资源的大小
DWORD dwSize = ::SizeofResource(NULL, hRsrc);
if (0 >= dwSize)
{
FreeRes_ShowError("SizeofResource");
return FALSE;
}
// 将资源加载到内存里
HGLOBAL hGlobal = ::LoadResource(NULL, hRsrc);
if (NULL == hGlobal)
{
FreeRes_ShowError("LoadResource");
return FALSE;
}
// 锁定资源
LPVOID lpVoid = ::LockResource(hGlobal);
if (NULL == lpVoid)
{
FreeRes_ShowError("LockResource");
return FALSE;
}
// 保存资源为文件
FILE *fp = NULL;
fopen_s(&fp, lpszSaveFileName, "wb+");
if (NULL == fp)
{
FreeRes_ShowError("LockResource");
return FALSE;
}
fwrite(lpVoid, sizeof(char), dwSize, fp);
fclose(fp);
return TRUE;
}
一路走来踩了各种“坑”,现在再提一个:按照上面的代码编译,其实是不通过的,因为找不到资源!
原因就出现在下面这段代码:
HRSRC hRsrc = ::FindResource(NULL, MAKEINTRESOURCE(uiResouceName), lpszResourceType);
下文为引用:
在exe中,FindResource相关函数的第一个参数可以为NULL,表示当前模块,但是DLL中执行该函数时,参数使用NULL的话则代表在调用该DLL的程序的资源文件中搜索。所以该函数始终会返回空,搜索不到资源!\
通过GetModuleHandle可以获取到该DLL在当前进程空间中的位置,参数为DLL的字符串名称。
也就是说因为我们编译的是DLL文件,所以参数NULL必须改为GetModuleHandle(\_T("XXX.DLL"))
。
HRSRC hRsrc = ::FindResource(GetModuleHandle(\_T("XXX.DLL")), MAKEINTRESOURCE(uiResouceName), lpszResourceType);