HRSRC test = FindResourceW(hModule, L"TEST", RT_MANIFEST);
FindResource失败,出现 ERROR_RESOURCE_NAME_NOT_FOUND 。我只将清单的资源名称重命名为字符串,然后尝试找到它。我认为这与MAKEINTRESOURCE
/ IS_INTRESOURCE
有关,或者我不确定。有任何想法吗?但是,仅将资源命名为1
时,它就可以正常工作。
ERROR_RESOURCE_NAME_NOT_FOUND
1814(0x716)
在图像文件中找不到指定的资源名称。
编辑:
struct Resource
{
LPVOID lpData;
LPCWSTR lpType;
LPCWSTR lpName;
DWORD dwSize;
};
bool EnumNamesFunc(HMODULE hModule, LPCWSTR lpType, LPWSTR lpName, LONG_PTR lParam)
{
HRSRC hResource = nullptr;
if (!IS_INTRESOURCE(lpName))
{
hResource = FindResource(hModule, lpName, lpType);
std::wcout << "It is not. " << lpName << std::endl;
}
else if (IS_INTRESOURCE(lpName))
{
hResource = FindResource(hModule, lpName, lpType);
std::cout << "It is" << std::endl;
}
if (!hResource)
{
return false;
}
DWORD dwSize = SizeofResource(hModule, hResource);
HGLOBAL hGlobal = LoadResource(hModule, hResource);
if (!hGlobal)
{
return false;
}
LPVOID lpResource = LockResource(hGlobal);
if (!lpResource)
{
return false;
}
Resource temp;
temp.lpData = hGlobal;
temp.lpType = lpType;
temp.lpName = lpName;
temp.dwSize = dwSize;
resources.push_back(temp);
FreeResource(lpResource);
return true;
}
此代码有效,但会泄漏:
Resource temp;
temp.lpData = hGlobal;
temp.lpType = lpType;
if (!IS_INTRESOURCE(lpName))
{
LPVOID temp = malloc(sizeof(LPCWSTR) * wcslen(lpName));
memcpy(temp, lpName, sizeof(LPCWSTR) * wcslen(lpName));
temp.lpName = temp;
}
else
{
temp.lpName = lpName;
}
答案 0 :(得分:3)
在EnumResourceNames()
回调中,当lpType
返回false时,无法保存lpName
和IS_INTRESOURCE()
的原始指针。一旦回调退出,该数据就会消失,从而使resources
容器中的指针无效。因此,在这种情况下,您需要复制它们指向的以空字符结尾的字符数据(您尝试这样做,但是没有正确执行)。
为避免内存泄漏,请在Resource
为假时向lpName
添加一个析构函数以释放lpType
/ IS_INTRESOURCE()
数据。另外,您需要向Resource
添加一个 copy构造函数和一个 copy赋值运算符来深度复制lpType
/ lpName
数据正确(按Rule of 3)。
此外,您的回调函数需要返回BOOL
而不是bool
,并且需要使用__stdcall
调用约定(由WINAPI
和{{ 1}}宏。
尝试更多类似的方法:
CALLBACK
struct Resource
{
LPWSTR lpType;
LPWSTR lpName;
HANDLE lpData;
DWORD dwSize;
Resource(LPCWSTR, LPWSTR, HANDLE, DWORD);
Resource(const Resource &);
~Resource();
Resource& operator=(const Resource &);
};
LPWSTR MakeResourceCopy(LPCWSTR Value)
{
if (IS_INTRESOURCE(Value))
return const_cast<LPWSTR>(Value);
int len = wcslen(Value) + 1;
LPWSTR copy = new WCHAR[len];
memcpy(copy, Value, sizeof(WCHAR) * len);
return copy;
}
Resource::Resource(LPCWSTR Type, LPWSTR Name, HANDLE Data, DWORD Size)
{
lpType = MakeResourceCopy(Type);
lpName = MakeResourceCopy(Name);
lpData = Data;
dwSize = Size;
}
Resource::Resource(const Resource &src)
{
lpType = MakeResourceCopy(src.lpType);
lpName = MakeResourceCopy(src.lpName);
lpData = src.lpData;
dwSize = src.dwSize;
}
Resource::~Resource()
{
if (!IS_INTRESOURCE(lpType))
delete[] lpType;
if (!IS_INTRESOURCE(lpName))
delete[] lpName;
}
Resource& Resource::operator=(const Resource &rhs)
{
if (&rhs != this)
{
Resource copy(rhs);
using std::swap;
swap(lpType, copy.lpType);
swap(lpName, copy.lpName);
swap(lpData, copy.lpData);
swap(dwSize, copy.dwSize);
}
return *this;
}
也就是说,我建议将BOOL CALLBACK EnumNamesFunc(HMODULE hModule, LPCWSTR lpType, LPWSTR lpName, LONG_PTR lParam)
{
if (!IS_INTRESOURCE(lpType))
std::wcout << "lpType is not an integer. " << lpType << std::endl;
else
std::cout << "lpType is an integer. #" << reinterpret_cast<int>(lpType) << std::endl;
if (!IS_INTRESOURCE(lpName))
std::wcout << "lpName is not an integer. " << lpName << std::endl;
else
std::cout << "lpName is an integer. #" << reinterpret_cast<int>(lpName) << std::endl;
HRSRC hResource = FindResource(hModule, lpName, lpType);
if (!hResource)
return FALSE;
DWORD dwSize = SizeofResource(hModule, hResource);
HGLOBAL hGlobal = LoadResource(hModule, hResource);
if (!hGlobal)
return FALSE;
LPVOID lpResource = LockResource(hGlobal);
if (!lpResource)
return FALSE;
Resource res(lpType, lpName, hGlobal, dwSize);
resources.push_back(res);
return TRUE;
}
的{{1}} / Resource
字段改为lpType
。如果获得数字lpName
/ std::wstring
值,只需将其转换为lpType
格式。让编译器为您处理所有内存管理:
lpName
"#..."
或者,使用struct Resource
{
std::wstring lpType;
std::wstring lpName;
HANDLE lpData;
DWORD dwSize;
};
代替:
std::wstring MakeResourceWString(LPCWSTR Value)
{
if (IS_INTRESOURCE(Value))
return L"#" + std::to_wstring(reinterpret_cast<int>(Value));
else
return Value;
}
BOOL CALLBACK EnumNamesFunc(HMODULE hModule, LPCWSTR lpType, LPWSTR lpName, LONG_PTR lParam)
{
if (!IS_INTRESOURCE(lpType))
std::wcout << "lpType is not an integer. " << lpType << std::endl;
else
std::cout << "lpType is an integer. #" << reinterpret_cast<int>(lpType) << std::endl;
if (!IS_INTRESOURCE(lpName))
std::wcout << "lpName is not an integer. " << lpName << std::endl;
else
std::cout << "lpName is an integer. #" << reinterpret_cast<int>(lpName) << std::endl;
HRSRC hResource = FindResource(hModule, lpName, lpType);
if (!hResource)
return FALSE;
DWORD dwSize = SizeofResource(hModule, hResource);
HGLOBAL hGlobal = LoadResource(hModule, hResource);
if (!hGlobal)
return FALSE;
LPVOID lpResource = LockResource(hGlobal);
if (!lpResource)
return FALSE;
Resource res;
res.lpType = MakeResourceWString(lpType);
res.lpName = MakeResourceWString(lpName);
res.lpData = hGlobal;
res.dwSize = dwSize;
resources.push_back(res);
return TRUE;
}
std::variant