Files
OpenVulkano/openVulkanoCpp/Host/Windows/EmbeddedResourceLoaderWindows.cpp
2024-12-19 16:10:41 +02:00

102 lines
2.8 KiB
C++

/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#include "EmbeddedResourceLoaderWindows.hpp"
#include "Base/Logger.hpp"
#include "Data/Containers/String.hpp"
#include "../resources/resource.h"
#include <windows.h>
#include <iostream>
namespace OpenVulkano
{
namespace
{
void* HANDLE = ResourceLoader::RegisterResourceLoader(std::make_unique<EmbeddedResourceLoaderWindows>());
}
std::string EmbeddedResourceLoaderWindows::GetResourcePath(const std::string& resourceName)
{
return "";
}
Array<char> EmbeddedResourceLoaderWindows::GetResource(const std::string& resourceName)
{
OpenVulkano::String s(resourceName);
auto tokens = s.Split("_");
if (tokens.empty() || tokens.size() == 1)
{
return {};
}
const std::string& resType = tokens.back();
return GetResource(resourceName.c_str(), GetWinApiResourceType(resType));
}
LPSTR EmbeddedResourceLoaderWindows::GetWinApiResourceType(std::string resourceType) const
{
std::transform(resourceType.begin(), resourceType.end(), resourceType.begin(),
[](char c) { return std::tolower(c); });
if (resourceType == "icon")
{
return RT_GROUP_ICON;
}
else if (resourceType == "font")
{
return RT_FONT;
}
return RT_RCDATA;
}
std::string EmbeddedResourceLoaderWindows::GetResourceName(const char* resId) const
{
// check if resId was provided as interger and not CString
// https://stackoverflow.com/questions/3610565/why-does-makeintresource-work
// first 64KB
uintptr_t ptrT = reinterpret_cast<uintptr_t>(resId);
// id that points to non-mappable memory
if (ptrT <= 0xFFFF)
{
return std::to_string(static_cast<uint16_t>(0xFFFF & ptrT));
}
// C-string
return std::string(resId);
}
Array<char> EmbeddedResourceLoaderWindows::GetResource(const char* resId, char* resourceType)
{
HMODULE exe = GetModuleHandleA(NULL);
LPCSTR resourceName = resId;
HRSRC hRes = FindResourceA(exe, resourceName, resourceType);
if (!hRes)
{
Logger::DATA->debug("Could not find embedded resource {}. Error code = {}.", GetResourceName(resId),
GetLastError());
return {};
}
HGLOBAL hResData = LoadResource(exe, hRes);
if (!hResData)
{
Logger::DATA->debug("Embedded resource {} found, but could not load. Error code = {}.", GetResourceName(resId),
GetLastError());
return {};
}
void* data = LockResource(hResData);
DWORD size = SizeofResource(exe, hRes);
Array<char> dst(size);
std::memcpy(dst.Data(), data, size);
return dst;
}
Array<char> EmbeddedResourceLoaderWindows::GetResource(uint16_t id, char* resourceType)
{
return GetResource(MAKEINTRESOURCE(id), resourceType);
}
}