1
0

imageCache.cpp 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357
  1. #include "./imageCache.h"
  2. #include "./imageLoader.h"
  3. #include "./graphics.h"
  4. #include "./loginBox.h"
  5. #include <api/service/waservicefactory.h>
  6. #include "../../ombrowser/ifc_omutility.h"
  7. #include "../../ombrowser/ifc_omcachemanager.h"
  8. #include "../../ombrowser/ifc_omcachegroup.h"
  9. #include "../../ombrowser/ifc_omcacherecord.h"
  10. #include "../api.h"
  11. LoginImageCache::LoginImageCache(HWND hLoginbox)
  12. : ref(1), hwnd(hLoginbox), group(NULL)
  13. {
  14. InitializeCriticalSection(&lock);
  15. }
  16. LoginImageCache::~LoginImageCache()
  17. {
  18. if (NULL != group)
  19. {
  20. group->Release();
  21. }
  22. DeleteCriticalSection(&lock);
  23. }
  24. HRESULT LoginImageCache::CreateInstance(HWND hLoginbox, LoginImageCache **instance)
  25. {
  26. if (NULL == instance)
  27. return E_POINTER;
  28. *instance = NULL;
  29. if (NULL == hLoginbox) return E_INVALIDARG;
  30. *instance = new LoginImageCache(hLoginbox);
  31. if (NULL == *instance) return E_OUTOFMEMORY;
  32. return S_OK;
  33. }
  34. size_t LoginImageCache::AddRef()
  35. {
  36. return InterlockedIncrement((LONG*)&ref);
  37. }
  38. size_t LoginImageCache::Release()
  39. {
  40. if (0 == ref)
  41. return ref;
  42. LONG r = InterlockedDecrement((LONG*)&ref);
  43. if (0 == r)
  44. delete(this);
  45. return r;
  46. }
  47. int LoginImageCache::QueryInterface(GUID interface_guid, void **object)
  48. {
  49. if (NULL == object) return E_POINTER;
  50. if (IsEqualIID(interface_guid, IFC_OmCacheCallback))
  51. *object = static_cast<ifc_omcachecallback*>(this);
  52. else
  53. {
  54. *object = NULL;
  55. return E_NOINTERFACE;
  56. }
  57. if (NULL == *object)
  58. return E_UNEXPECTED;
  59. AddRef();
  60. return S_OK;
  61. }
  62. void LoginImageCache::PathChanged(ifc_omcacherecord *record)
  63. {
  64. HWND hLoginbox;
  65. EnterCriticalSection(&lock);
  66. hLoginbox = hwnd;
  67. LeaveCriticalSection(&lock);
  68. if (NULL != hLoginbox && FALSE != IsWindow(hLoginbox))
  69. {
  70. IMAGECACHERESULT result;
  71. result.imageCache = this;
  72. result.cacheRecord = record;
  73. SendMessage(hLoginbox, NLBM_IMAGECACHED, 0, (LPARAM)&result);
  74. }
  75. }
  76. void LoginImageCache::Finish()
  77. {
  78. EnterCriticalSection(&lock);
  79. ifc_omcachegroup *groupCopy = group;
  80. if (NULL != groupCopy)
  81. groupCopy->AddRef();
  82. LeaveCriticalSection(&lock);
  83. if (NULL != groupCopy)
  84. {
  85. groupCopy->Clear();
  86. WCHAR szGroup[64] = {0};
  87. if (SUCCEEDED(groupCopy->GetName(szGroup, ARRAYSIZE(szGroup))))
  88. {
  89. waServiceFactory *serviceFactory = WASABI_API_SVC->service_getServiceByGuid(IFC_OmUtility);
  90. if (NULL != serviceFactory)
  91. {
  92. ifc_omutility *omUtility = (ifc_omutility*)serviceFactory->getInterface();
  93. if (NULL != omUtility)
  94. {
  95. ifc_omcachemanager *cacheManager;
  96. if (SUCCEEDED(omUtility->GetCacheManager(&cacheManager)))
  97. {
  98. cacheManager->Delete(szGroup);
  99. cacheManager->Release();
  100. }
  101. omUtility->Release();
  102. }
  103. }
  104. }
  105. groupCopy->Release();
  106. }
  107. }
  108. HRESULT LoginImageCache::InitGroup()
  109. {
  110. HRESULT hr;
  111. EnterCriticalSection(&lock);
  112. if (NULL != group)
  113. {
  114. hr = S_FALSE;
  115. }
  116. else
  117. {
  118. hr = S_OK;
  119. waServiceFactory *serviceFactory = WASABI_API_SVC->service_getServiceByGuid(IFC_OmUtility);
  120. if (NULL != serviceFactory)
  121. {
  122. ifc_omutility *omUtility = (ifc_omutility*)serviceFactory->getInterface();
  123. if (NULL != omUtility)
  124. {
  125. ifc_omcachemanager *cacheManager;
  126. if (SUCCEEDED(omUtility->GetCacheManager(&cacheManager)))
  127. {
  128. if (FAILED(cacheManager->Find(L"loginBox", TRUE, &group, NULL)))
  129. group = NULL;
  130. cacheManager->Release();
  131. }
  132. omUtility->Release();
  133. }
  134. }
  135. if (NULL == group)
  136. hr = E_NOINTERFACE;
  137. }
  138. LeaveCriticalSection(&lock);
  139. return hr;
  140. }
  141. HRESULT LoginImageCache::GetImageListIndex(LPCWSTR pszPath, HIMAGELIST himl, UINT *index, UINT *indexActive, UINT *indexDisabled)
  142. {
  143. if (NULL == pszPath || L'\0' == *pszPath)
  144. return E_INVALIDARG;
  145. HRESULT hr;
  146. WCHAR szBuffer[2048] = {0};
  147. EnterCriticalSection(&lock);
  148. BOOL fCreated = FALSE;
  149. hr = InitGroup();
  150. if (SUCCEEDED(hr))
  151. {
  152. ifc_omcacherecord *record;
  153. hr = group->Find(pszPath, TRUE, &record, &fCreated);
  154. if (S_OK != hr)
  155. {
  156. if (S_FALSE == hr)
  157. hr = E_PENDING;
  158. }
  159. else
  160. {
  161. record->RegisterCallback(this);
  162. hr = record->GetPath(szBuffer, ARRAYSIZE(szBuffer));
  163. record->Release();
  164. }
  165. }
  166. LeaveCriticalSection(&lock);
  167. if (FAILED(hr))
  168. return hr;
  169. return GetImageListIndexLocal(szBuffer, himl, index, indexActive, indexDisabled);
  170. }
  171. HRESULT LoginImageCache::GetImageListIndexLocal(LPCWSTR pszPath, HIMAGELIST himl, UINT *index, UINT *indexActive, UINT *indexDisabled)
  172. {
  173. if (NULL == himl || NULL == pszPath || L'\0' == *pszPath)
  174. return E_INVALIDARG;
  175. if (NULL == index && NULL == indexActive && NULL == indexDisabled)
  176. return E_INVALIDARG;
  177. INT destWidth, destHeight;
  178. if (0 == ImageList_GetIconSize(himl, &destWidth, &destHeight))
  179. return E_FAIL;
  180. INT imageWidth, imageHeight;
  181. HBITMAP hbmp = ImageLoader_LoadBitmap(NULL, pszPath, FALSE, &imageWidth, &imageHeight);
  182. if (NULL == hbmp)
  183. return E_FAIL;
  184. HRESULT hr = S_OK;
  185. RECT imageRect;
  186. SetRect(&imageRect, 0, 0, imageWidth, imageHeight);
  187. if (NULL != indexActive)
  188. {
  189. *indexActive = ImageList_Add(himl, hbmp, NULL);
  190. if (((UINT)-1) == *indexActive) hr = E_FAIL;
  191. }
  192. if (NULL != index)
  193. {
  194. Image_AdjustSaturationAlpha(hbmp, &imageRect, -150, -100);
  195. *index = ImageList_Add(himl, hbmp, NULL);
  196. if (((UINT)-1) == *index) hr = E_FAIL;
  197. }
  198. if (NULL != indexDisabled)
  199. {
  200. Image_AdjustSaturationAlpha(hbmp, &imageRect, -600, -600);
  201. *indexDisabled = ImageList_Add(himl, hbmp, NULL);
  202. if (((UINT)-1) == *indexDisabled) hr = E_FAIL;
  203. }
  204. if (NULL != hbmp)
  205. DeleteObject(hbmp);
  206. return hr;
  207. }
  208. HBITMAP LoginImageCache::AdjustBitmapSize(HBITMAP hBitmap, INT forceWidth, INT forceHeight)
  209. {
  210. BITMAP bm;
  211. if (sizeof(BITMAP) != GetObject(hBitmap, sizeof(bm), &bm))
  212. return NULL;
  213. if (bm.bmHeight < 0) bm.bmHeight = -bm.bmHeight;
  214. if (bm.bmWidth == forceWidth && bm.bmHeight == forceHeight)
  215. return hBitmap;
  216. HDC hdc, hdcSrc, hdcDst;
  217. hdc = GetDCEx(NULL, NULL, DCX_CACHE | DCX_WINDOW | DCX_NORESETATTRS);
  218. if (NULL == hdc) return NULL;
  219. hdcSrc = CreateCompatibleDC(hdc);
  220. hdcDst = CreateCompatibleDC(hdc);
  221. BITMAPINFOHEADER bhi;
  222. ZeroMemory(&bhi, sizeof(bhi));
  223. bhi.biSize = sizeof(bhi);
  224. bhi.biCompression = BI_RGB;
  225. bhi.biBitCount = 32;
  226. bhi.biPlanes = 1;
  227. bhi.biWidth = forceWidth;
  228. bhi.biHeight = -forceHeight;
  229. UINT *pixelData;
  230. HBITMAP hbmpDst = CreateDIBSection(NULL, (LPBITMAPINFO)&bhi, DIB_RGB_COLORS, (void**)&pixelData, NULL, 0);
  231. if (NULL != hbmpDst)
  232. {
  233. for (INT i = 0; i < forceWidth * forceHeight; i++)
  234. pixelData[i] = 0x00FFFFFF;
  235. }
  236. ReleaseDC(NULL, hdc);
  237. if (NULL != hdcSrc && NULL != hdcDst && NULL != hbmpDst)
  238. {
  239. HBITMAP hbmpSrcOrig = (HBITMAP)SelectObject(hdcSrc, hBitmap);
  240. HBITMAP hbmpDstOrig = (HBITMAP)SelectObject(hdcDst, hbmpDst);
  241. BOOL result;
  242. if (bm.bmWidth <= forceWidth && bm.bmHeight <= forceHeight)
  243. {
  244. BLENDFUNCTION bf;
  245. bf.BlendOp = AC_SRC_OVER;
  246. bf.BlendFlags = 0;
  247. bf.SourceConstantAlpha = 255;
  248. bf.AlphaFormat = AC_SRC_ALPHA;
  249. result = GdiAlphaBlend(hdcDst, (forceWidth - bm.bmWidth)/2, (forceHeight - bm.bmHeight)/2,
  250. bm.bmWidth, bm.bmHeight, hdcSrc, 0, 0, bm.bmWidth, bm.bmHeight, bf);
  251. }
  252. else
  253. {
  254. SetStretchBltMode(hdcDst, HALFTONE);
  255. result = StretchBlt(hdcDst, 0, 0, forceWidth, forceHeight,
  256. hdcSrc, 0, 0, bm.bmWidth, bm.bmHeight, SRCCOPY);
  257. }
  258. if(FALSE != result)
  259. {
  260. hBitmap = hbmpDst;
  261. hbmpDst = NULL;
  262. }
  263. else
  264. hBitmap = NULL;
  265. SelectObject(hdcSrc, hbmpSrcOrig);
  266. SelectObject(hdcDst, hbmpDstOrig);
  267. }
  268. else
  269. {
  270. hBitmap = NULL;
  271. }
  272. if (NULL != hdcDst) DeleteDC(hdcDst);
  273. if (NULL != hdcSrc) DeleteDC(hdcSrc);
  274. if (NULL != hbmpDst) DeleteObject(hbmpDst);
  275. return hBitmap;
  276. }
  277. #define CBCLASS LoginImageCache
  278. START_DISPATCH;
  279. CB(ADDREF, AddRef)
  280. CB(RELEASE, Release)
  281. CB(QUERYINTERFACE, QueryInterface)
  282. VCB(API_PATHCHANGED, PathChanged)
  283. END_DISPATCH;
  284. #undef CBCLASS