/*
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
#include "Resources.h"
#include "FileUtils.h"
#include "WinErrorHandling.h"
#include <fstream>
Resource::Resource(LPCTSTR name, LPCTSTR type, HINSTANCE module) {
init(name, type, module);
}
Resource::Resource(UINT id, LPCTSTR type, HINSTANCE module) {
init(MAKEINTRESOURCE(id), type, module);
}
void Resource::init(LPCTSTR name, LPCTSTR type, HINSTANCE module) {
if (IS_INTRESOURCE(name)) {
std::wostringstream printer;
printer << L"#" << reinterpret_cast<size_t>(name);
nameStr = printer.str();
namePtr = name;
} else {
nameStr = name;
namePtr = nameStr.c_str();
}
if (IS_INTRESOURCE(type)) {
std::wostringstream printer;
printer << L"#" << reinterpret_cast<size_t>(name);
typeStr = printer.str();
typePtr = type;
} else {
typeStr = type;
typePtr = typeStr.c_str();
}
instance = module;
}
std::string Resource::getErrMsg(const std::string &descr) const {
return (tstrings::any() << descr << " (name='" << nameStr <<
"', type='" << typeStr << "')").str();
}
HRSRC Resource::findResource() const {
LPCTSTR id = namePtr;
// string resources are stored in blocks (stringtables)
// id of the resource is (stringId / 16 + 1)
if (typePtr == RT_STRING) {
id = MAKEINTRESOURCE(UINT(size_t(id) / 16 + 1));
}
return FindResource(instance, id, typePtr);
}
LPVOID Resource::getPtr(DWORD &size) const
{
// LoadString returns the same result if value is zero-length or
// if if the value does not exists,
// so wee need to ensure the stringtable exists
HRSRC resInfo = findResource();
if (resInfo == NULL) {
JP_THROW(SysError(getErrMsg("cannot find resource"), FindResource));
}
HGLOBAL res = LoadResource(instance, resInfo);
if (res == NULL) {
JP_THROW(SysError(getErrMsg("cannot load resource"), LoadResource));
}
LPVOID ptr = LockResource(res);
if (res == NULL) {
JP_THROW(SysError(getErrMsg("cannot lock resource"), LockResource));
}
if (typePtr == RT_STRING) {
// string resources are stored in stringtables and
// need special handling
// The simplest way (while we don't need handle resource locale)
// is LoadString
// But this adds dependency on user32.dll,
// so implement custom string extraction
// number in the block (namePtr is an integer)
size_t num = size_t(namePtr) & 0xf;
LPWSTR strPtr = (LPWSTR)ptr;
for (size_t i = 0; i < num; i++) {
// 1st symbol contains string length
strPtr += DWORD(*strPtr) + 1;
}
// *strPtr contains string length, string value starts at strPtr+1
size = DWORD(*strPtr) * sizeof(wchar_t);
ptr = strPtr+1;
} else {
size = SizeofResource(instance, resInfo);
}
return ptr;
}
bool Resource::available() const {
return NULL != findResource();
}
unsigned Resource::size() const {
DWORD size = 0;
/**代码未完, 请加载全部代码(NowJava.com).**/