44 printer << L"#" << reinterpret_cast<size_t>(name); 45 nameStr = printer.str(); 46 namePtr = name; 47 } else { 48 nameStr = name; 49 namePtr = nameStr.c_str(); 50 } 51 if (IS_INTRESOURCE(type)) { 52 std::wostringstream printer; 53 printer << L"#" << reinterpret_cast<size_t>(name); 54 typeStr = printer.str(); 55 typePtr = type; 56 } else { 57 typeStr = type; 58 typePtr = typeStr.c_str(); 59 } 60 instance = module; 61 } 62 63 std::string Resource::getErrMsg(const std::string &descr) const { 64 return (tstrings::any() << descr << " (name='" << nameStr << "', type='" << typeStr << "')").str(); 65 } 66 67 HRSRC Resource::findResource() const { 68 LPCTSTR id = namePtr; 69 // string resources are stored in blocks (stringtables) 70 // id of the resource is (stringId / 16 + 1) 71 if (typePtr == RT_STRING) { 72 id = MAKEINTRESOURCE(UINT(size_t(id) / 16 + 1)); 73 } 74 return FindResource(instance, id, typePtr); 75 } 76 77 LPVOID Resource::getPtr(DWORD &size) const 78 { 79 // LoadString returns the same result if value is zero-length or if if the value does not exists, 80 // so wee need to ensure the stringtable exists 81 HRSRC resInfo = findResource(); 82 if (resInfo == NULL) { 83 JP_THROW(SysError(getErrMsg("cannot find resource"), FindResource)); 84 } 85 86 HGLOBAL res = LoadResource(instance, resInfo); 87 if (res == NULL) { 88 JP_THROW(SysError(getErrMsg("cannot load resource"), LoadResource)); 89 } 90 91 LPVOID ptr = LockResource(res); 92 if (res == NULL) { 93 JP_THROW(SysError(getErrMsg("cannot lock resource"), LockResource)); 94 } 95 96 if (typePtr == RT_STRING) { 97 // string resources are stored in stringtables and need special handling 98 // The simplest way (while we don't need handle resource locale) is LoadString 99 // But this adds dependency on user32.dll, so implement custom string extraction 100 101 // number in the block (namePtr is an integer) 102 size_t num = size_t(namePtr) & 0xf; 103 LPWSTR strPtr = (LPWSTR)ptr; 104 for (size_t i = 0; i < num; i++) { 105 // 1st symbol contains string length 106 strPtr += DWORD(*strPtr) + 1; 107 } 108 // *strPtr contains string length, string value starts at strPtr+1 109 size = DWORD(*strPtr) * sizeof(wchar_t); 110 ptr = strPtr+1; 111 } else { 112 size = SizeofResource(instance, resInfo); 113 } 114 115 return ptr; 116 } 117 118 bool Resource::available() const { 119 return NULL != findResource(); | 44 printer << L"#" << reinterpret_cast<size_t>(name); 45 nameStr = printer.str(); 46 namePtr = name; 47 } else { 48 nameStr = name; 49 namePtr = nameStr.c_str(); 50 } 51 if (IS_INTRESOURCE(type)) { 52 std::wostringstream printer; 53 printer << L"#" << reinterpret_cast<size_t>(name); 54 typeStr = printer.str(); 55 typePtr = type; 56 } else { 57 typeStr = type; 58 typePtr = typeStr.c_str(); 59 } 60 instance = module; 61 } 62 63 std::string Resource::getErrMsg(const std::string &descr) const { 64 return (tstrings::any() << descr << " (name='" << nameStr << 65 "', type='" << typeStr << "')").str(); 66 } 67 68 HRSRC Resource::findResource() const { 69 LPCTSTR id = namePtr; 70 // string resources are stored in blocks (stringtables) 71 // id of the resource is (stringId / 16 + 1) 72 if (typePtr == RT_STRING) { 73 id = MAKEINTRESOURCE(UINT(size_t(id) / 16 + 1)); 74 } 75 return FindResource(instance, id, typePtr); 76 } 77 78 LPVOID Resource::getPtr(DWORD &size) const 79 { 80 // LoadString returns the same result if value is zero-length or 81 // if if the value does not exists, 82 // so wee need to ensure the stringtable exists 83 HRSRC resInfo = findResource(); 84 if (resInfo == NULL) { 85 JP_THROW(SysError(getErrMsg("cannot find resource"), FindResource)); 86 } 87 88 HGLOBAL res = LoadResource(instance, resInfo); 89 if (res == NULL) { 90 JP_THROW(SysError(getErrMsg("cannot load resource"), LoadResource)); 91 } 92 93 LPVOID ptr = LockResource(res); 94 if (res == NULL) { 95 JP_THROW(SysError(getErrMsg("cannot lock resource"), LockResource)); 96 } 97 98 if (typePtr == RT_STRING) { 99 // string resources are stored in stringtables and 100 // need special handling 101 // The simplest way (while we don't need handle resource locale) 102 // is LoadString 103 // But this adds dependency on user32.dll, 104 // so implement custom string extraction 105 106 // number in the block (namePtr is an integer) 107 size_t num = size_t(namePtr) & 0xf; 108 LPWSTR strPtr = (LPWSTR)ptr; 109 for (size_t i = 0; i < num; i++) { 110 // 1st symbol contains string length 111 strPtr += DWORD(*strPtr) + 1; 112 } 113 // *strPtr contains string length, string value starts at strPtr+1 114 size = DWORD(*strPtr) * sizeof(wchar_t); 115 ptr = strPtr+1; 116 } else { 117 size = SizeofResource(instance, resInfo); 118 } 119 120 return ptr; 121 } 122 123 bool Resource::available() const { 124 return NULL != findResource(); |