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

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

DialogBox, CreateDialogの代替関数を実装

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