soui 5.0.0.1
Soui5 Doc
 
Loading...
Searching...
No Matches
SResProviderMgr.cpp
1#include "souistd.h"
2#include "res.mgr/SResProviderMgr.h"
3#include "res.mgr/SResProvider.h"
4#include "helper/SplitString.h"
5#include <res.mgr/SUiDef.h>
6
7SNSBEGIN
8
9const static TCHAR KTypeFile[] = _T("file"); //从文件加载资源时指定的类型
10
14
19
21{
22 SAutoLock lock(m_cs);
23 SPOSITION pos = m_lstResPackage.GetHeadPosition();
24 while (pos)
25 {
26 IResProvider *pResProvider = m_lstResPackage.GetNext(pos);
27#ifdef _DEBUG //检查资源使用情况
28 SSLOGD() << "++++begin of check resource usage";
29 pResProvider->EnumResource(&SResProviderMgr::CheckUsage, (LPARAM)&m_mapResUsageCount);
30 SSLOGD() << "----end of check resource usage";
31#endif
32 pResProvider->Release();
33 }
34 m_lstResPackage.RemoveAll();
35
36 pos = m_mapCachedCursor.GetStartPosition();
37 while (pos)
38 {
39 CURSORMAP::CPair *pPair = m_mapCachedCursor.GetNext(pos);
40 DestroyCursor(pPair->m_value);
41 }
42 m_mapCachedCursor.RemoveAll();
43}
44
45IResProvider *SResProviderMgr::GetMatchResProvider(LPCTSTR pszType, LPCTSTR pszResName)
46{
47 SAutoLock lock(m_cs);
48 SPOSITION pos = m_lstResPackage.GetTailPosition();
49 while (pos)
50 {
51 IResProvider *pResProvider = m_lstResPackage.GetPrev(pos);
52 if (pResProvider->HasResource(pszType, pszResName))
53 {
54#ifdef _DEBUG
55 m_mapResUsageCount[SStringT().Format(_T("%s:%s"), pszType, pszResName).MakeLower()]++;
56#endif
57 return pResProvider;
58 }
59 }
60 return NULL;
61}
62
63void SResProviderMgr::AddResProvider(IResProvider *pResProvider, LPCTSTR pszUidef)
64{
65 SAutoLock lock(m_cs);
66 m_lstResPackage.AddTail(pResProvider);
67 pResProvider->AddRef();
68 if (pszUidef)
69 {
70 GETUIDEF->InitDefUiDef(pResProvider, pszUidef);
71 }
72}
73
74void SResProviderMgr::AddResProviderA(IResProvider *pResProvider, LPCSTR pszUidef)
75{
76 if (!pszUidef)
77 return AddResProvider(pResProvider, NULL);
78 SStringT strUiDef = S_CA2T(pszUidef, CP_UTF8);
79 return AddResProvider(pResProvider, strUiDef.c_str());
80}
81
83{
84 SAutoLock lock(m_cs);
85 SPOSITION pos = m_lstResPackage.GetTailPosition();
86 while (pos)
87 {
88 SPOSITION posPrev = pos;
89 IResProvider *pResProvierT = m_lstResPackage.GetPrev(pos);
90 if (pResProvierT == pResProvider)
91 {
92 m_lstResPackage.RemoveAt(posPrev);
93 pResProvierT->Release();
94 break;
95 }
96 }
97}
98
100{
101 return m_lstResPackage.GetHead();
102}
103
105{
106 return m_lstResPackage.GetTail();
107}
108
109LPCTSTR SResProviderMgr::SysCursorName2ID(LPCTSTR pszCursorName)
110{
111 struct Cursor2ID
112 {
113 LPCTSTR szName;
114 LPCTSTR szID;
115 };
116 static const Cursor2ID cursorMap[] = {
117 { _T("arrow"), IDC_ARROW }, { _T("ibeam"), IDC_IBEAM }, { _T("wait"), IDC_WAIT }, { _T("cross"), IDC_CROSS }, { _T("uparrow"), IDC_UPARROW }, { _T("size"), IDC_SIZE }, { _T("sizenwse"), IDC_SIZENWSE }, { _T("sizenesw"), IDC_SIZENESW }, { _T("sizewe"), IDC_SIZEWE }, { _T("sizens"), IDC_SIZENS }, { _T("sizeall"), IDC_SIZEALL }, { _T("no"), IDC_NO }, { _T("hand"), IDC_HAND }, { _T("help"), IDC_HELP },
118 };
119 SAutoLock lock(m_cs);
120 for (int i = 0; i < ARRAYSIZE(cursorMap); i++)
121 {
122 if (0 == _tcsicmp(cursorMap[i].szName, pszCursorName))
123 return cursorMap[i].szID;
124 }
125 return NULL;
126}
127
128BOOL SResProviderMgr::GetRawBuffer(LPCTSTR strType, LPCTSTR pszResName, LPVOID pBuf, size_t size)
129{
130 SAutoLock lock(m_cs);
131 if (!strType)
132 { // support res src by resource path.
133 SPOSITION pos = m_lstResPackage.GetHeadPosition();
134 while (pos)
135 {
136 IResProvider *pRes = m_lstResPackage.GetNext(pos);
137 if (pRes->HasResource(NULL, pszResName))
138 return pRes->GetRawBuffer(strType, pszResName, pBuf, size);
139 }
140 return FALSE;
141 }
142 if (IsFileType(strType))
143 {
144 SStringT strPath = m_strFilePrefix + pszResName;
145 return SResLoadFromFile::GetRawBuffer(strPath, pBuf, size);
146 }
147 else
148 {
149#ifdef _DEBUG
150 m_mapResUsageCount[SStringT().Format(_T("%s:%s"), strType, pszResName).MakeLower()]++;
151#endif
152 IResProvider *pResProvider = GetMatchResProvider(strType, pszResName);
153 if (!pResProvider)
154 return FALSE;
155 return pResProvider->GetRawBuffer(strType, pszResName, pBuf, size);
156 }
157}
158
159size_t SResProviderMgr::GetRawBufferSize(LPCTSTR strType, LPCTSTR pszResName)
160{
161 SAutoLock lock(m_cs);
162 if (!strType)
163 { // support res src by resource path.
164 SPOSITION pos = m_lstResPackage.GetHeadPosition();
165 while (pos)
166 {
167 IResProvider *pRes = m_lstResPackage.GetNext(pos);
168 if (pRes->HasResource(NULL, pszResName))
169 return pRes->GetRawBufferSize(strType, pszResName);
170 }
171 return 0;
172 }
173 if (IsFileType(strType))
174 {
175 SStringT strPath = m_strFilePrefix + pszResName;
177 }
178 else
179 {
180#ifdef _DEBUG
181 m_mapResUsageCount[SStringT().Format(_T("%s:%s"), strType, pszResName).MakeLower()]++;
182#endif
183
184 IResProvider *pResProvider = GetMatchResProvider(strType, pszResName);
185 if (!pResProvider)
186 return 0;
187 return pResProvider->GetRawBufferSize(strType, pszResName);
188 }
189}
190
191IImgX *SResProviderMgr::LoadImgX(LPCTSTR strType, LPCTSTR pszResName)
192{
193 SAutoLock lock(m_cs);
194 if (!strType)
195 { // support res src by resource path.
196 SPOSITION pos = m_lstResPackage.GetHeadPosition();
197 while (pos)
198 {
199 IResProvider *pRes = m_lstResPackage.GetNext(pos);
200 IImgX *img = pRes->LoadImgX(NULL, pszResName);
201 if (img)
202 return img;
203 }
204 return NULL;
205 }
206
207 if (IsFileType(strType))
208 {
209 SStringT strPath = m_strFilePrefix + pszResName;
210 return SResLoadFromFile::LoadImgX(strPath);
211 }
212 else
213 {
214#ifdef _DEBUG
215 m_mapResUsageCount[SStringT().Format(_T("%s:%s"), strType, pszResName).MakeLower()]++;
216#endif
217
218 IResProvider *pResProvider = GetMatchResProvider(strType, pszResName);
219 if (!pResProvider)
220 return NULL;
221 return pResProvider->LoadImgX(strType, pszResName);
222 }
223}
224
225IBitmapS *SResProviderMgr::LoadImage(LPCTSTR pszType, LPCTSTR pszResName)
226{
227 SAutoLock lock(m_cs);
228 if (!pszType)
229 { // support res src by resource path.
230 SPOSITION pos = m_lstResPackage.GetHeadPosition();
231 while (pos)
232 {
233 IResProvider *pRes = m_lstResPackage.GetNext(pos);
234 IBitmapS *bmp = pRes->LoadImage(NULL, pszResName);
235 if (bmp)
236 return bmp;
237 }
238 return NULL;
239 }
240 if (IsFileType(pszType))
241 {
242 SStringT strPath = m_strFilePrefix + pszResName;
243 return SResLoadFromFile::LoadImage(strPath);
244 }
245 else
246 {
247#ifdef _DEBUG
248 m_mapResUsageCount[SStringT().Format(_T("%s:%s"), pszType, pszResName).MakeLower()]++;
249#endif
250
251 IResProvider *pResProvider = GetMatchResProvider(pszType, pszResName);
252 if (!pResProvider)
253 {
254 SSLOGW() << "load image failed, resource index " << pszType << ":" << pszResName << " not found!";
255 return NULL;
256 }
257 IBitmapS *pRet = pResProvider->LoadImage(pszType, pszResName);
258 if (!pRet)
259 {
260 SSLOGW() << "load image failed, resource content " << pszType << ":" << pszResName << " not found!";
261 }
262 return pRet;
263 }
264}
265
266HBITMAP SResProviderMgr::LoadBitmap(LPCTSTR pszResName, BOOL bFromFile /*= FALSE*/)
267{
268 SAutoLock lock(m_cs);
269 if (bFromFile)
270 {
271 SStringT strPath = m_strFilePrefix + pszResName;
272 return SResLoadFromFile::LoadBitmap(strPath);
273 }
274 else
275 {
276#ifdef _DEBUG
277 m_mapResUsageCount[SStringT().Format(_T("bitmap:%s"), pszResName).MakeLower()]++;
278#endif
279
280 IResProvider *pResProvider = GetMatchResProvider(KTypeBitmap, pszResName);
281 if (!pResProvider)
282 {
283 SSLOGW() << "load bitmap failed, resource index " << pszResName << " not found!";
284 return NULL;
285 }
286 HBITMAP hBmp = pResProvider->LoadBitmap(pszResName);
287 if (!hBmp)
288 {
289 SSLOGW() << "load bitmap failed, resource content " << pszResName << " not found!";
290 }
291 return hBmp;
292 }
293}
294
295HCURSOR SResProviderMgr::LoadCursor(LPCTSTR pszResName, BOOL bFromFile /*= FALSE*/)
296{
297 SAutoLock lock(m_cs);
298 if (IS_INTRESOURCE(pszResName))
299 {
300 return ::LoadCursor(NULL, pszResName);
301 }
302 else
303 {
304 LPCTSTR pszCursorID = SysCursorName2ID(pszResName);
305 if (pszCursorID)
306 return ::LoadCursor(NULL, pszCursorID);
307 }
308 const CURSORMAP::CPair *pPair = m_mapCachedCursor.Lookup(pszResName);
309 if (pPair)
310 return pPair->m_value;
311
312 HCURSOR hRet = NULL;
313 if (bFromFile)
314 {
315 SStringT strPath = m_strFilePrefix + pszResName;
316 hRet = SResLoadFromFile::LoadCursor(strPath);
317 }
318 else
319 {
320
321#ifdef _DEBUG
322 m_mapResUsageCount[SStringT().Format(_T("cursor:%s"), pszResName).MakeLower()]++;
323#endif
324
325 IResProvider *pResProvider = GetMatchResProvider(KTypeCursor, pszResName);
326 if (!pResProvider)
327 {
328 SSLOGW() << "load cursor failed, resource index " << pszResName << " not found!";
329 return NULL;
330 }
331 else
332 {
333 hRet = pResProvider->LoadCursor(pszResName);
334 }
335 }
336 if (hRet)
337 {
338 m_mapCachedCursor[pszResName] = hRet;
339 }
340 else
341 {
342 SSLOGW() << "load cursor failed, resource content " << pszResName << " not found!";
343 }
344 return hRet;
345}
346
347HICON SResProviderMgr::LoadIcon(LPCTSTR pszResName, int cx /*=0*/, int cy /*=0*/, BOOL bFromFile /*= FALSE*/)
348{
349 SAutoLock lock(m_cs);
350 if (bFromFile)
351 {
352 SStringT strPath = m_strFilePrefix + pszResName;
353 return SResLoadFromFile::LoadIcon(strPath, cx, cy);
354 }
355 else
356 {
357#ifdef _DEBUG
358 m_mapResUsageCount[SStringT().Format(_T("icon:%s"), pszResName).MakeLower()]++;
359#endif
360 IResProvider *pResProvider = GetMatchResProvider(KTypeIcon, pszResName);
361 if (!pResProvider)
362 {
363 SSLOGW() << "load icon failed, resource index " << pszResName << " not found!";
364 return NULL;
365 }
366 HICON hRet = pResProvider->LoadIcon(pszResName, cx, cy);
367 if (!hRet)
368 {
369 SSLOGW() << "load icon failed, resource content " << pszResName << " not found!";
370 }
371 return hRet;
372 }
373}
374
375BOOL SResProviderMgr::HasResource(LPCTSTR pszType, LPCTSTR pszResName)
376{
377 SAutoLock lock(m_cs);
378 if (IsFileType(pszType))
379 {
380 SStringT strPath = m_strFilePrefix + pszResName;
381 return IsFilePathValid(strPath);
382 }
383 else
384 {
385 return NULL != GetMatchResProvider(pszType, pszResName);
386 }
387}
388
390{
391 SStringT strImgID2 = S_CW2T(strImgID);
392 SStringTList strLst;
393 int nSegs = ParseResID(strImgID2, strLst);
394 if (nSegs == 2)
395 return LoadImage(strLst[0], strLst[1]);
396 else
397 return LoadImage(NULL, strLst[0]);
398}
399
401{
402 SStringT strIconID2 = S_CW2T(strIconID);
403 SStringTList strLst;
404 int nSegs = ParseResID(strIconID2, strLst);
405 if (nSegs == 2)
406 {
407 int cx = _ttoi(strLst[1]);
408 return LoadIcon(strLst[0], cx, cx);
409 }
410 else
411 {
412 return LoadIcon(strLst[0]);
413 }
414}
415
416BOOL SResProviderMgr::IsFileType(LPCTSTR pszType)
417{
418 if (!pszType)
419 return FALSE;
420 return _tcsicmp(pszType, KTypeFile) == 0;
421}
422
423#ifdef _DEBUG
424BOOL SResProviderMgr::CheckUsage(LPCTSTR pszName, LPCTSTR pszType, LPARAM lp)
425{
426 SMap<SStringT, int> *mapResUsageCount = (SMap<SStringT, int> *)lp;
427 if (IS_INTRESOURCE(pszName))
428 return TRUE;
429 SStringT key = SStringT().Format(_T("%s:%s"), pszType, pszName);
430 key.MakeLower();
431 if (!mapResUsageCount->Lookup(key))
432 { //发现未使用资源
433 SSLOGD() << _T("resource of [") << key.c_str() << _T("] was not used.");
434 }
435 return TRUE;
436}
437#endif
438void SResProviderMgr::SetFilePrefix(LPCTSTR pszFilePrefix)
439{
440 SAutoLock lock(m_cs);
441 m_strFilePrefix = pszFilePrefix;
442 if (!m_strFilePrefix.EndsWith(_T(PATH_SLASH)))
443 m_strFilePrefix.Append(_T(PATH_SLASH));
444}
445
446BOOL SResProviderMgr::LoadRawBuffer(LPCTSTR pszType, LPCTSTR pszResName, IResProvider *pResProvider, SAutoBuf &buf)
447{
448 SAutoLock lock(m_cs);
449 if (IsFileType(pszType))
450 {
451 size_t dwSize = SResLoadFromFile::GetRawBufferSize(pszResName);
452 if (dwSize == 0)
453 return FALSE;
454 buf.Allocate(dwSize);
455 SResLoadFromFile::GetRawBuffer(pszResName, buf, dwSize);
456 return TRUE;
457 }
458 if (!pResProvider)
459 {
460 pResProvider = GetMatchResProvider(pszType, pszResName);
461 }
462 if (!pResProvider)
463 {
464 SSLOGW() << "GetMatchResProvider failed: " << pszType << ":" << pszResName << " not found in respovider list";
465 return FALSE;
466 }
467 size_t dwSize = pResProvider->GetRawBufferSize(pszType, pszResName);
468 if (dwSize == 0)
469 {
470 SSLOGW() << "GetMatchResProvider failed: " << pszType << ":" << pszResName << " pResProvider->GetRawBufferSize return 0";
471 return FALSE;
472 }
473 buf.Allocate(dwSize);
474 return pResProvider->GetRawBuffer(pszType, pszResName, buf, dwSize);
475}
476
477SNSEND
A smart buffer management class that automatically handles memory allocation and deallocation.
Definition SAutoBuf.h:18
char * Allocate(size_t nElements)
Allocates a buffer of the specified size. If a buffer is already allocated, it will be freed first.
Definition SAutoBuf.cpp:40
Auto-lock class for managing critical sections.
static HBITMAP LoadBitmap(LPCTSTR pszFileName)
Loads a bitmap from a file.
static size_t GetRawBufferSize(LPCTSTR pszFileName)
Retrieves the size of the raw buffer for a file.
static BOOL GetRawBuffer(LPCTSTR pszFileName, LPVOID pBuf, size_t size)
Retrieves the raw buffer for a file.
static IBitmapS * LoadImage(LPCTSTR pszFileName)
Loads an image from a file as an IBitmapS object.
static IImgX * LoadImgX(LPCTSTR pszFileName)
Loads an image from a file as an IImgX object.
static HICON LoadIcon(LPCTSTR pszFileName, int cx=0, int cy=0)
Loads an icon from a file.
static HCURSOR LoadCursor(LPCTSTR pszFileName)
Loads a cursor from a file.
IResProvider * GetHeadResProvider() SCONST OVERRIDE
Retrieves the first resource provider in the list.
void RemoveResProvider(IResProvider *pResProvider) OVERRIDE
Removes a resource provider.
void AddResProviderA(IResProvider *pResProvider, LPCSTR pszUidef="uidef:xml_init") OVERRIDE
Adds a resource provider with a specified UI definition (ANSI version).
IBitmapS * LoadImage2(const SStringW &strImgID)
Loads an image using a type:name formatted string.
void SetFilePrefix(LPCTSTR pszFilePrefix) OVERRIDE
Sets the file prefix for resource paths.
IResProvider * GetMatchResProvider(LPCTSTR pszType, LPCTSTR pszResName)
Finds the resource provider that contains the specified resource type and name.
LPCTSTR SysCursorName2ID(LPCTSTR pszCursorName)
Converts a system cursor name to its corresponding ID.
BOOL IsFileType(LPCTSTR pszType)
Checks if the resource type is an external file.
void AddResProvider(IResProvider *pResProvider, LPCTSTR pszUidef=_T("uidef:xml_init")) OVERRIDE
Adds a resource provider with a specified UI definition.
void RemoveAll() OVERRIDE
Removes all resource providers.
IResProvider * GetTailResProvider() SCONST OVERRIDE
Retrieves the last resource provider in the list.
HICON LoadIcon2(const SStringW &strIconID)
Loads an icon using a name:size formatted string.
SResProviderMgr(void)
Constructor.
BOOL LoadRawBuffer(LPCTSTR pszType, LPCTSTR pszResName, IResProvider *pResProvider, SAutoBuf &buf)
Loads the raw buffer for a resource using a specified resource provider.
size_t GetRawBufferSize(LPCTSTR pszType, LPCTSTR pszResName) OVERRIDE
Retrieves the size of the raw buffer for a resource.
HICON LoadIcon(LPCTSTR pszResName, int cx=0, int cy=0, BOOL bFromFile=FALSE) OVERRIDE
Loads an icon resource.
BOOL HasResource(LPCTSTR pszType, LPCTSTR pszResName) OVERRIDE
Checks if a resource exists.
IBitmapS * LoadImage(LPCTSTR pszType, LPCTSTR pszResName) OVERRIDE
Loads an image resource as an IBitmapS object.
~SResProviderMgr(void)
Destructor.
HCURSOR LoadCursor(LPCTSTR pszResName, BOOL bFromFile=FALSE) OVERRIDE
Loads a cursor resource.
IImgX * LoadImgX(LPCTSTR pszType, LPCTSTR pszResName) OVERRIDE
Loads an image resource as an IImgX object.
HBITMAP LoadBitmap(LPCTSTR pszResName, BOOL bFromFile=FALSE) OVERRIDE
Loads a bitmap resource.
BOOL GetRawBuffer(LPCTSTR pszType, LPCTSTR pszResName, LPVOID pBuf, size_t size) OVERRIDE
Retrieves the raw buffer for a resource.
A class representing an ASCII string.
Definition sstringw.h:96
Bitmap object interface.
Definition SRender-i.h:420
Interface for image data.
ResProvider对象
IImgX * LoadImgX(LPCTSTR pszType, LPCTSTR pszResName) PURE
从资源中创建一个IImgX对象
IBitmapS * LoadImage(LPCTSTR pszType, LPCTSTR pszResName) PURE
从资源加载一个IBitmap对象
HICON LoadIcon(LPCTSTR pszResName, int cx, int cy) PURE
从资源中加载ICON
void EnumResource(EnumResCallback funEnumCB, LPARAM lp) PURE
枚举资源
HCURSOR LoadCursor(LPCTSTR pszResName) PURE
从资源中加载光标
BOOL GetRawBuffer(LPCTSTR pszType, LPCTSTR pszResName, LPVOID pBuf, size_t size) PURE
获得资源内存块
HBITMAP LoadBitmap(LPCTSTR pszResName) PURE
从资源中加载HBITMAP
BOOL HasResource(LPCTSTR pszType, LPCTSTR pszResName) PURE
查询一个资源是否存在
size_t GetRawBufferSize(LPCTSTR pszType, LPCTSTR pszResName) PURE
获得资源数据大小
long AddRef() PURE
添加引用
long Release() PURE
释放引用