source: dev/branches/egtra/ab5.0/abdev/abdev-impl/Resource/Load.cpp@ 802

Last change on this file since 802 was 797, checked in by イグトランス (egtra), 14 years ago

プロパティシート周りを9x対応させた

File size: 5.3 KB
Line 
1#include "stdafx.h"
2#include <vector>
3#include <utility>
4#include <boost/range.hpp>
5#include <boost/range/adaptor/transformed.hpp>
6#include <boost/numeric/conversion/cast.hpp>
7#include <atlbase.h>
8#pragma warning(push)
9#pragma warning(disable: 6387)
10#include <atlapp.h>
11#include <atlgdi.h>
12#pragma warning(pop)
13#include <Resource/Load.h>
14
15using boost::numeric_cast;
16
17namespace ActiveBasic { namespace Resource {
18
19namespace {
20
21template<typename Map, typename Key, typename AddValueFunctor>
22typename Map::iterator GetCacheFromMap(Map& map, Key key, AddValueFunctor f)
23{
24 auto low = map.lower_bound(key);
25 if (low != map.end() && map.key_comp()(key, low->first))
26 {
27 return low;
28 }
29 else
30 {
31 typedef typename Map::key_type key_type;
32 typedef typename Map::value_type value_type;
33 return map.insert(low, std::make_pair(std::move(key), f()));
34 }
35}
36
37HICON LoadIconCursorImpl(HINSTANCE hinst, USHORT id, int cxDesired, int cyDesired, UINT load, bool isIcon)
38{
39 auto pResource = LoadResourceAlt(hinst, id, isIcon ? RT_GROUP_ICON : RT_GROUP_CURSOR);
40
41 auto idIcon = LookupIconIdFromDirectoryEx(reinterpret_cast<PBYTE>(pResource), isIcon, cxDesired, cyDesired, load);
42 auto icon = LoadResourceAltWithSize(hinst, numeric_cast<USHORT>(idIcon), isIcon ? RT_ICON : RT_CURSOR);
43
44 return CreateIconFromResourceEx(reinterpret_cast<PBYTE>(icon.first),
45 icon.second, isIcon, 0x00030000, cxDesired, cyDesired, load);
46}
47
48} // unnamed namespace
49
50void* LoadResourceAlt(HINSTANCE hinst, USHORT id, LPCTSTR type)
51{
52 if (auto hrsrc = ::FindResource(hinst, MAKEINTRESOURCE(id), type))
53 {
54 if (auto hSrc = ::LoadResource(hinst, hrsrc))
55 {
56 return ::LockResource(hSrc);
57 }
58 }
59 return nullptr;
60}
61
62std::pair<void*, DWORD> LoadResourceAltWithSize(HINSTANCE hinst, USHORT id, LPCTSTR type)
63{
64 typedef std::pair<void*, DWORD> result_type;
65 if (auto hrsrc = ::FindResource(hinst, MAKEINTRESOURCE(id), type))
66 {
67 if (auto hSrc = ::LoadResource(hinst, hrsrc))
68 {
69 auto p = ::LockResource(hSrc);
70 auto size = ::SizeofResource(hinst, hrsrc);
71 if (p != nullptr && size > 0)
72 {
73 return result_type(p, size);
74 }
75 }
76 }
77 return result_type(nullptr, 0);
78}
79
80HICON LoadIconAlt(HINSTANCE hinst, USHORT id, int cxDesired, int cyDesired, UINT load)
81{
82 return LoadIconCursorImpl(hinst, id, cxDesired, cyDesired, load, true);
83}
84
85HICON LoadIconAlt(HINSTANCE hinst, USHORT id)
86{
87 return LoadIconCursorImpl(hinst, id, 32, 32, LR_SHARED, true);
88}
89
90HCURSOR LoadCursorAlt(HINSTANCE hinst, USHORT id)
91{
92 return LoadIconCursorImpl(hinst, id, 32, 32, LR_SHARED, false);
93}
94
95// 文字列リソースの読み込みについては以下を参照。
96// How To Use LoadResource to Load Strings from a String Table
97// http://support.microsoft.com/kb/200893/en-us
98boost::optional<std::wstring> LoadStringAlt(HINSTANCE hinst, USHORT id)
99{
100 UINT idRsrcBlk = id / 16 + 1;
101 int strIndex = id % 16;
102
103 auto hrsrc = FindResourceEx(hinst, RT_STRING, MAKEINTRESOURCE(idRsrcBlk), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT));
104 if (hrsrc == nullptr)
105 return boost::none;
106
107 auto hRes = LoadResource(hinst, hrsrc);
108 if (hRes == nullptr)
109 return boost::none;
110 LPCWSTR p = static_cast<LPCWSTR>(LockResource(hRes));
111 if (p == nullptr)
112 return boost::none;
113
114 for (int i = 0; i < strIndex; ++i)
115 {
116 UINT length = *p++;
117 p += length;
118 }
119
120 UINT cch = *p++;
121 if (cch == 0)
122 {
123 return boost::none;
124 }
125 else
126 {
127 return std::wstring(p, cch);
128 }
129}
130
131namespace {
132
133// http://msdn.microsoft.com/en-us/library/ms648010.aspx
134struct ACCELTABLEENTRY
135{
136 WORD fFlags;
137 WORD wAnsi;
138 WORD wId;
139 WORD padding;
140};
141
142ACCEL AccelFromEntry(ACCELTABLEENTRY const& e)
143{
144 ACCEL t = {static_cast<BYTE>(e.fFlags & 0x7f), e.wAnsi, e.wId};
145 return t;
146}
147
148} // unnamed namespace
149
150HACCEL LoadAcceleratorsAlt(HINSTANCE hinst, USHORT id)
151{
152 using namespace boost::adaptors;
153
154 auto accel = LoadResourceAltWithSize(hinst, id, RT_ACCELERATOR);
155 if (accel.first == nullptr)
156 {
157 return nullptr;
158 }
159
160 auto pate = static_cast<ACCELTABLEENTRY const*>(accel.first);
161
162 auto a = boost::copy_range<std::vector<ACCEL>>(
163 boost::make_iterator_range(pate, pate + accel.second / sizeof (ACCELTABLEENTRY))
164 | transformed(AccelFromEntry));
165
166 if (a.size() > INT_MAX)
167 {
168 a.resize(INT_MAX);
169 }
170 return CreateAcceleratorTable(&a[0], static_cast<int>(a.size()));
171}
172
173HMENU LoadMenuAlt(HINSTANCE hinst, USHORT id)
174{
175 return LoadMenuIndirect(LoadResourceAlt(hinst, id, RT_MENU));
176}
177
178INT_PTR DialogBoxAlt(HINSTANCE hinst, USHORT id, HWND hwndParent, DLGPROC dialogFunc, LPARAM initParam)
179{
180 auto dlgTemplate = static_cast<DLGTEMPLATE*>(LoadResourceAlt(hinst, id, RT_DIALOG));
181 return ::DialogBoxIndirectParam(hinst, dlgTemplate, hwndParent, dialogFunc, initParam);
182}
183
184HWND CreateDialogAlt(HINSTANCE hinst, USHORT id, HWND hwndParent, DLGPROC dialogFunc, LPARAM initParam)
185{
186 auto dlgTemplate = static_cast<DLGTEMPLATE*>(LoadResourceAlt(hinst, id, RT_DIALOG));
187 return ::CreateDialogIndirectParam(hinst, dlgTemplate, hwndParent, dialogFunc, initParam);
188}
189
190HBITMAP LoadBitmapAlt(HINSTANCE hinst, USHORT id)
191{
192 WTL::CDC dc = ::GetDC(nullptr);
193 auto pbi = static_cast<BITMAPINFO const*>(LoadResourceAlt(hinst, id, RT_BITMAP));
194 return CreateDIBitmap(dc, &pbi->bmiHeader, CBM_INIT, reinterpret_cast<BYTE const*>(pbi) + pbi->bmiHeader.biSize, pbi, DIB_RGB_COLORS);
195}
196
197}}
Note: See TracBrowser for help on using the repository browser.