#include "stdafx.h" #include #include #include #include #include #include #pragma warning(push) #pragma warning(disable: 6387) #include #include #pragma warning(pop) #include using boost::numeric_cast; namespace ActiveBasic { namespace Resource { namespace { template typename Map::iterator GetCacheFromMap(Map& map, Key key, AddValueFunctor f) { auto low = map.lower_bound(key); if (low != map.end() && map.key_comp()(key, low->first)) { return low; } else { typedef typename Map::key_type key_type; typedef typename Map::value_type value_type; return map.insert(low, std::make_pair(std::move(key), f())); } } HICON LoadIconCursorImpl(HINSTANCE hinst, USHORT id, int cxDesired, int cyDesired, UINT load, bool isIcon) { auto pResource = LoadResourceAlt(hinst, id, isIcon ? RT_GROUP_ICON : RT_GROUP_CURSOR); auto idIcon = LookupIconIdFromDirectoryEx(reinterpret_cast(pResource), isIcon, cxDesired, cyDesired, load); auto icon = LoadResourceAltWithSize(hinst, numeric_cast(idIcon), isIcon ? RT_ICON : RT_CURSOR); return CreateIconFromResourceEx(reinterpret_cast(icon.first), icon.second, isIcon, 0x00030000, cxDesired, cyDesired, load); } } // unnamed namespace void* LoadResourceAlt(HINSTANCE hinst, USHORT id, LPCTSTR type) { if (auto hrsrc = ::FindResource(hinst, MAKEINTRESOURCE(id), type)) { if (auto hSrc = ::LoadResource(hinst, hrsrc)) { return ::LockResource(hSrc); } } return nullptr; } std::pair LoadResourceAltWithSize(HINSTANCE hinst, USHORT id, LPCTSTR type) { typedef std::pair result_type; if (auto hrsrc = ::FindResource(hinst, MAKEINTRESOURCE(id), type)) { if (auto hSrc = ::LoadResource(hinst, hrsrc)) { auto p = ::LockResource(hSrc); auto size = ::SizeofResource(hinst, hrsrc); if (p != nullptr && size > 0) { return result_type(p, size); } } } return result_type(nullptr, 0); } HICON LoadIconAlt(HINSTANCE hinst, USHORT id, int cxDesired, int cyDesired, UINT load) { return LoadIconCursorImpl(hinst, id, cxDesired, cyDesired, load, true); } HICON LoadIconAlt(HINSTANCE hinst, USHORT id) { return LoadIconCursorImpl(hinst, id, 32, 32, LR_SHARED, true); } HCURSOR LoadCursorAlt(HINSTANCE hinst, USHORT id) { return LoadIconCursorImpl(hinst, id, 32, 32, LR_SHARED, false); } // 文字列リソースの読み込みについては以下を参照。 // How To Use LoadResource to Load Strings from a String Table // http://support.microsoft.com/kb/200893/en-us boost::optional LoadStringAlt(HINSTANCE hinst, USHORT id) { UINT idRsrcBlk = id / 16 + 1; int strIndex = id % 16; auto hrsrc = FindResourceEx(hinst, RT_STRING, MAKEINTRESOURCE(idRsrcBlk), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT)); if (hrsrc == nullptr) return boost::none; auto hRes = LoadResource(hinst, hrsrc); if (hRes == nullptr) return boost::none; LPCWSTR p = static_cast(LockResource(hRes)); if (p == nullptr) return boost::none; for (int i = 0; i < strIndex; ++i) { UINT length = *p++; p += length; } UINT cch = *p++; if (cch == 0) { return boost::none; } else { return std::wstring(p, cch); } } namespace { // http://msdn.microsoft.com/en-us/library/ms648010.aspx struct ACCELTABLEENTRY { WORD fFlags; WORD wAnsi; WORD wId; WORD padding; }; ACCEL AccelFromEntry(ACCELTABLEENTRY const& e) { ACCEL t = {static_cast(e.fFlags & 0x7f), e.wAnsi, e.wId}; return t; } } // unnamed namespace HACCEL LoadAcceleratorsAlt(HINSTANCE hinst, USHORT id) { using namespace boost::adaptors; auto accel = LoadResourceAltWithSize(hinst, id, RT_ACCELERATOR); if (accel.first == nullptr) { return nullptr; } auto pate = static_cast(accel.first); auto a = boost::copy_range>( boost::make_iterator_range(pate, pate + accel.second / sizeof (ACCELTABLEENTRY)) | transformed(AccelFromEntry)); if (a.size() > INT_MAX) { a.resize(INT_MAX); } return CreateAcceleratorTable(&a[0], static_cast(a.size())); } HMENU LoadMenuAlt(HINSTANCE hinst, USHORT id) { return LoadMenuIndirect(LoadResourceAlt(hinst, id, RT_MENU)); } INT_PTR DialogBoxAlt(HINSTANCE hinst, USHORT id, HWND hwndParent, DLGPROC dialogFunc, LPARAM initParam) { auto dlgTemplate = static_cast(LoadResourceAlt(hinst, id, RT_DIALOG)); return ::DialogBoxIndirectParam(hinst, dlgTemplate, hwndParent, dialogFunc, initParam); } HWND CreateDialogAlt(HINSTANCE hinst, USHORT id, HWND hwndParent, DLGPROC dialogFunc, LPARAM initParam) { auto dlgTemplate = static_cast(LoadResourceAlt(hinst, id, RT_DIALOG)); return ::CreateDialogIndirectParam(hinst, dlgTemplate, hwndParent, dialogFunc, initParam); } HBITMAP LoadBitmapAlt(HINSTANCE hinst, USHORT id) { WTL::CDC dc = ::GetDC(nullptr); auto pbi = static_cast(LoadResourceAlt(hinst, id, RT_BITMAP)); return CreateDIBitmap(dc, &pbi->bmiHeader, CBM_INIT, reinterpret_cast(pbi) + pbi->bmiHeader.biSize, pbi, DIB_RGB_COLORS); } }}