/* * 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 #include namespace OpenVulkano { namespace { void* HANDLE = ResourceLoader::RegisterResourceLoader(std::make_unique()); } std::string EmbeddedResourceLoaderWindows::GetResourcePath(const std::string& resourceName) { return ""; } Array 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) { 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) { // check if resId was provided as interger or CString // https://stackoverflow.com/questions/3610565/why-does-makeintresource-work // first 64KB uintptr_t ptrT = reinterpret_cast(resId); // id that points to non-mappable memory if (ptrT <= 0xFFFF) { return std::to_string(static_cast(0xFFFF & ptrT)); } // C-string return std::string(resId); } Array 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 dst(size); std::memcpy(dst.Data(), data, size); return dst; } Array EmbeddedResourceLoaderWindows::GetResource(uint16_t id, char* resourceType) { return GetResource(MAKEINTRESOURCE(id), resourceType); } }