XTPImageManager.cpp
上传用户:szled88
上传日期:2015-04-09
资源大小:43957k
文件大小:103k
源码类别:

对话框与窗口

开发平台:

Visual C++

  1. // XTPImageManager.cpp : implementation of the CXTPImageManager class.
  2. //
  3. // This file is a part of the XTREME TOOLKIT PRO MFC class library.
  4. // (c)1998-2008 Codejock Software, All Rights Reserved.
  5. //
  6. // THIS SOURCE FILE IS THE PROPERTY OF CODEJOCK SOFTWARE AND IS NOT TO BE
  7. // RE-DISTRIBUTED BY ANY MEANS WHATSOEVER WITHOUT THE EXPRESSED WRITTEN
  8. // CONSENT OF CODEJOCK SOFTWARE.
  9. //
  10. // THIS SOURCE CODE CAN ONLY BE USED UNDER THE TERMS AND CONDITIONS OUTLINED
  11. // IN THE XTREME TOOLKIT PRO LICENSE AGREEMENT. CODEJOCK SOFTWARE GRANTS TO
  12. // YOU (ONE SOFTWARE DEVELOPER) THE LIMITED RIGHT TO USE THIS SOFTWARE ON A
  13. // SINGLE COMPUTER.
  14. //
  15. // CONTACT INFORMATION:
  16. // support@codejock.com
  17. // http://www.codejock.com
  18. //
  19. /////////////////////////////////////////////////////////////////////////////
  20. #include "stdafx.h"
  21. #include <math.h>
  22. #include "XTPVC80Helpers.h"
  23. #include "XTPColorManager.h"
  24. #include "XTPDrawHelpers.h"
  25. #include "XTPSystemHelpers.h"
  26. #include "XTPMacros.h"
  27. #include "XTPPropExchange.h"
  28. #include "XTPImageManager.h"
  29. #include "XTPResourceManager.h"
  30. #ifdef _XTP_INCLUDE_GRAPHICLIBRARY
  31. #include "GraphicLibrary/XTPGraphicBitmapPng.h"
  32. #endif
  33. #ifdef _DEBUG
  34. #define new DEBUG_NEW
  35. #undef THIS_FILE
  36. static char THIS_FILE[] = __FILE__;
  37. #endif
  38. #define DESTROYICON(hIcon) if (hIcon) { ::DestroyIcon(hIcon); hIcon = 0; }
  39. #define FREE(hHandle) if (hHandle) { free(hHandle); hHandle = 0; }
  40. double CXTPImageManager::m_dDisabledAlphaFactor = 1.0;
  41. double CXTPImageManager::m_dDisabledBrightnessFactor = 0.5;
  42. BOOL CXTPImageManager::m_bAutoResample = FALSE;
  43. CLIPFORMAT CXTPImageManager::m_nImageClipFormat = (CLIPFORMAT)RegisterClipboardFormat(_T("Xtreme ToolBar Image"));
  44. CLIPFORMAT CXTPImageManager::m_nAlphaClipFormat = (CLIPFORMAT)RegisterClipboardFormat(_T("Alpha Bitmap Image"));
  45. #ifndef NOMIRRORBITMAP
  46. #define NOMIRRORBITMAP      (DWORD)0x80000000 /* Do not Mirror the bitmap in this call */
  47. #endif
  48. //---------------------------------------------------------------------------
  49. //    Should be a prime number:
  50. // 37, 53, 79 , 101, 127, 199, 503, 1021, 1511, 2003, 3001, 4001, 5003, 6007, 8009, 12007, 16001, 32003, 48017, 64007
  51. #define XTP_IMAGEMAN_HASH_TABLE_SIZE 127
  52. //////////////////////////////////////////////////////////////////////////
  53. // Common
  54. BOOL CXTPImageManager::BitmapsCompatible(LPBITMAP lpbm1, LPBITMAP lpbm2) const
  55. {
  56. if (lpbm1->bmBitsPixel != lpbm2->bmBitsPixel)
  57. return FALSE;
  58. if (lpbm1->bmPlanes != lpbm2->bmPlanes)
  59. return FALSE;
  60. if (lpbm1->bmWidth != lpbm2->bmWidth)
  61. return FALSE;
  62. if (lpbm1->bmHeight != lpbm2->bmHeight)
  63. return FALSE;
  64. return TRUE;
  65. }
  66. BOOL CXTPImageManager::McTransparentBlt(HDC hdcDest, int nXOriginDest, int nYOriginDest,
  67. int nWidthDest, int nHeightDest, HDC hdcSrc,
  68. int nXOriginSrc, int nYOriginSrc, int nWidthSrc,
  69. int nHeightSrc, UINT crTransparent) const
  70. {
  71. BOOL bResult = FALSE;
  72. if (!hdcDest || !hdcSrc)
  73. return FALSE;
  74. HDC hdcMask = NULL;
  75. HDC hdcTmpSrc = NULL;
  76. HBITMAP hbmTransMask = NULL;
  77. HBITMAP oldhbmTransMask = NULL;
  78. HBITMAP hbmTmpSrc = NULL;
  79. HBITMAP oldhbmTmpSrc = NULL;
  80. COLORREF OldBkColor = ::SetBkColor(hdcDest, RGB(255, 255, 255));
  81. COLORREF OldTextColor = ::SetTextColor(hdcDest, RGB(0, 0, 0));
  82. if ((hdcMask = ::CreateCompatibleDC(hdcDest)) == NULL)
  83. {
  84. goto ClearUp;
  85. }
  86. if ((hdcTmpSrc = ::CreateCompatibleDC(hdcSrc))==NULL)
  87. {
  88. goto ClearUp;
  89. }
  90. if ((hbmTmpSrc = ::CreateCompatibleBitmap(hdcDest,nWidthSrc,nHeightSrc))==NULL)
  91. {
  92. goto ClearUp;
  93. }
  94. oldhbmTmpSrc = (HBITMAP)::SelectObject(hdcTmpSrc,hbmTmpSrc);
  95. if (!::BitBlt(hdcTmpSrc, 0, 0, nWidthSrc, nHeightSrc, hdcSrc, nXOriginSrc, nYOriginSrc, SRCCOPY))
  96. {
  97. goto ClearUp;
  98. }
  99. if ((hbmTransMask = ::CreateBitmap(nWidthSrc, nHeightSrc, 1, 1, NULL)) == NULL)
  100. {
  101. goto ClearUp;
  102. }
  103. oldhbmTransMask = (HBITMAP)::SelectObject(hdcMask,hbmTransMask);
  104. ::SetBkColor(hdcTmpSrc,crTransparent);
  105. if (!::BitBlt(hdcMask, 0, 0, nWidthSrc, nHeightSrc, hdcTmpSrc, 0, 0, SRCCOPY))
  106. {
  107. goto ClearUp;
  108. }
  109. if (crTransparent != RGB(0, 0, 0))
  110. {
  111. ::SetBkColor(hdcTmpSrc, RGB(0, 0, 0));
  112. ::SetTextColor(hdcTmpSrc, RGB(255, 255, 255));
  113. if (!::BitBlt(hdcTmpSrc, 0, 0, nWidthSrc, nHeightSrc, hdcMask, 0, 0, SRCAND))
  114. {
  115. goto ClearUp;
  116. }
  117. }
  118. if ((nWidthDest == nWidthSrc) && (nHeightDest == nHeightSrc))
  119. {
  120. if (!::BitBlt(hdcDest, nXOriginDest, nYOriginDest, nWidthSrc, nHeightSrc, hdcMask, 0, 0, SRCAND))
  121. {
  122. goto ClearUp;
  123. }
  124. if (!::BitBlt(hdcDest, nXOriginDest, nYOriginDest, nWidthSrc, nHeightSrc, hdcTmpSrc, 0, 0, SRCPAINT))
  125. {
  126. goto ClearUp;
  127. }
  128. }
  129. else
  130. {
  131. if (!::StretchBlt(hdcDest, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest, hdcMask, 0, 0, nWidthSrc, nHeightSrc,SRCAND))
  132. {
  133. goto ClearUp;
  134. }
  135. if (!::StretchBlt(hdcDest, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest, hdcTmpSrc, 0, 0,  nWidthSrc, nHeightSrc,SRCPAINT))
  136. {
  137. goto ClearUp;
  138. }
  139. }
  140. bResult = TRUE;
  141. ClearUp:
  142. if (hdcMask)
  143. {
  144. if (oldhbmTransMask)
  145. ::SelectObject(hdcMask,oldhbmTransMask);
  146. ::DeleteDC(hdcMask);
  147. }
  148. if (hbmTmpSrc)
  149. {
  150. if (oldhbmTmpSrc)
  151. ::SelectObject(hdcTmpSrc,oldhbmTmpSrc);
  152. ::DeleteObject(hbmTmpSrc);
  153. }
  154. if (hdcTmpSrc)
  155. ::DeleteDC(hdcTmpSrc);
  156. if (hbmTransMask)
  157. ::DeleteObject(hbmTransMask);
  158. ::SetBkColor(hdcDest, OldBkColor);
  159. ::SetTextColor(hdcDest,OldTextColor);
  160. return bResult;
  161. }
  162. BOOL CXTPImageManager::IsWindow2000() const
  163. {
  164. return XTPSystemVersion()->IsWin2KOrGreater();
  165. }
  166. BOOL CXTPImageManager::TransparentBlt(HDC hdcDest, const CRect& rcDest,HDC hdcSrc,
  167. const CRect& rcSrc, UINT crTransparent) const
  168. {
  169. if (IsWindow2000() && XTPDrawHelpers()->m_pfnTransparentBlt)
  170. {
  171. return XTPDrawHelpers()->m_pfnTransparentBlt(hdcDest, rcDest.left, rcDest.top, rcDest.Width(), rcDest.Height(),
  172. hdcSrc, rcSrc.left, rcSrc.top, rcSrc.Width(), rcSrc.Height(), crTransparent);
  173. }
  174. return McTransparentBlt(hdcDest, rcDest.left, rcDest.top, rcDest.Width(), rcDest.Height(),
  175. hdcSrc, rcSrc.left, rcSrc.top, rcSrc.Width(), rcSrc.Height(), crTransparent);
  176. }
  177. BOOL CXTPImageManager::BlendImages(HBITMAP hbmSrc1, BOOL bRTL1, HBITMAP hbmSrc2, BOOL bRTL2, HBITMAP hbmDst) const
  178. {
  179. BITMAP bmSrc1, bmSrc2, bmDst;
  180. RGBQUAD *lprgbSrc1, *lprgbSrc2, *lprgbDst;
  181. DWORD dwWidthBytes;
  182. int x, y;
  183. // Get weighting value for second source image.
  184. // Get information about the surfaces you were passed.
  185. if (!GetObject(hbmSrc1, sizeof(BITMAP), &bmSrc1)) return FALSE;
  186. if (!GetObject(hbmSrc2, sizeof(BITMAP), &bmSrc2)) return FALSE;
  187. if (!GetObject(hbmDst,  sizeof(BITMAP), &bmDst))  return FALSE;
  188. // Make sure you have data that meets your requirements.
  189. if (!BitmapsCompatible(&bmSrc1, &bmSrc2)) return FALSE;
  190. if (!BitmapsCompatible(&bmSrc1, &bmDst))  return FALSE;
  191. if (bmSrc1.bmBitsPixel != 32) return FALSE;
  192. if (bmSrc1.bmPlanes != 1) return FALSE;
  193. if (!bmSrc1.bmBits || !bmSrc2.bmBits || !bmDst.bmBits) return FALSE;
  194. dwWidthBytes = bmDst.bmWidthBytes;
  195. // Initialize the surface pointers.
  196. lprgbSrc1 = (RGBQUAD*)bmSrc1.bmBits;
  197. lprgbSrc2 = (RGBQUAD*)bmSrc2.bmBits;
  198. lprgbDst  = (RGBQUAD*)bmDst.bmBits;
  199. #define F(a)  BYTE(gbSrc1.##a + (255 - gbSrc1.rgbReserved) * gbSrc2.##a / 255)
  200. for (y = 0; y < bmDst.bmHeight; y++)
  201. {
  202. for (x = 0; x < bmDst.bmWidth; x++)
  203. {
  204. RGBQUAD& gbSrc1 = bRTL1 ? lprgbSrc1[bmDst.bmWidth - 1 - x] : lprgbSrc1[x];
  205. RGBQUAD& gbSrc2 = bRTL2 ? lprgbSrc2[bmDst.bmWidth - 1 - x] : lprgbSrc2[x];
  206. lprgbDst[x].rgbRed   = F(rgbRed);
  207. lprgbDst[x].rgbGreen = F(rgbGreen);
  208. lprgbDst[x].rgbBlue  = F(rgbBlue);
  209. }
  210. // Move to next scan line.
  211. lprgbSrc1 = (RGBQUAD *)((LPBYTE)lprgbSrc1 + dwWidthBytes);
  212. lprgbSrc2 = (RGBQUAD *)((LPBYTE)lprgbSrc2 + dwWidthBytes);
  213. lprgbDst  = (RGBQUAD *)((LPBYTE)lprgbDst  + dwWidthBytes);
  214. }
  215. return TRUE;
  216. }
  217. HBITMAP AFX_CDECL CXTPImageManager::Create32BPPDIBSection(HDC hDC, int iWidth, int iHeight, LPBYTE* lpBits)
  218. {
  219. BITMAPINFO bmi;
  220. HBITMAP hbm;
  221. LPBYTE pBits;
  222. // Initialize header to 0s.
  223. ZeroMemory(&bmi, sizeof(bmi));
  224. // Fill out the fields you care about.
  225. bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
  226. bmi.bmiHeader.biWidth = iWidth;
  227. bmi.bmiHeader.biHeight = iHeight;
  228. bmi.bmiHeader.biPlanes = 1;
  229. bmi.bmiHeader.biBitCount = 32;
  230. bmi.bmiHeader.biCompression = BI_RGB;
  231. // Create the surface.
  232. hbm = CreateDIBSection(hDC, &bmi, DIB_RGB_COLORS, (LPVOID*)&pBits, NULL, 0);
  233. if (lpBits)
  234. {
  235. *lpBits = pBits;
  236. }
  237. return(hbm);
  238. }
  239. BOOL CXTPImageManager::DoAlphaBlend(HDC hdcDest,                 // Handle to destination DC.
  240. int nXOriginDest,            // X-coord of upper-left corner.
  241. int nYOriginDest,            // Y-coord of upper-left corner.
  242. int nWidthDest,              // Destination width.
  243. int nHeightDest,             // Destination height.
  244. HDC hdcSrc,                  // Handle to source DC.
  245. int nXOriginSrc,             // X-coord of upper-left corner.
  246. int nYOriginSrc,             // Y-coord of upper-left corner.
  247. int nWidthSrc,               // Source width.
  248. int nHeightSrc              // Source height.
  249. ) const
  250. {
  251. HDC      hdcSrc1 = NULL;
  252. HDC      hdcSrc2 = NULL;
  253. HBITMAP  hbmSrc1 = NULL, hbmOldSrc1 = NULL;
  254. HBITMAP  hbmSrc2 = NULL, hbmOldSrc2 = NULL;
  255. HBITMAP  hbmDst  = NULL;
  256. BOOL     bReturn = FALSE;
  257. BOOL     bRTLSrc    = XTPDrawHelpers()->IsContextRTL(hdcSrc);
  258. BOOL     bRTLDest   = XTPDrawHelpers()->IsContextRTL(hdcDest);
  259. // Create surfaces for sources and destination images.
  260. hbmSrc1 = CXTPImageManager::Create32BPPDIBSection(hdcDest, nWidthDest,nHeightDest);
  261. if (!hbmSrc1) goto HANDLEERROR;
  262. hbmSrc2 = CXTPImageManager::Create32BPPDIBSection(hdcDest, nWidthDest,nHeightDest);
  263. if (!hbmSrc2) goto HANDLEERROR;
  264. hbmDst  = CXTPImageManager::Create32BPPDIBSection(hdcDest, nWidthDest,nHeightDest);
  265. if (!hbmDst) goto HANDLEERROR;
  266. // Create HDCs to hold our surfaces.
  267. hdcSrc1 = CreateCompatibleDC(hdcSrc);
  268. if (!hdcSrc1) goto HANDLEERROR;
  269. hdcSrc2 = CreateCompatibleDC(hdcSrc);
  270. if (!hdcSrc2) goto HANDLEERROR;
  271. XTPDrawHelpers()->SetContextRTL(hdcSrc2, FALSE);
  272. XTPDrawHelpers()->SetContextRTL(hdcSrc1, FALSE);
  273. // Prepare the surfaces for drawing.
  274. hbmOldSrc1 = (HBITMAP)SelectObject(hdcSrc1, hbmSrc1);
  275. hbmOldSrc2 = (HBITMAP)SelectObject(hdcSrc2, hbmSrc2);
  276. SetStretchBltMode(hdcSrc1, COLORONCOLOR);
  277. SetStretchBltMode(hdcSrc2, COLORONCOLOR);
  278. // Capture a copy of the source area.
  279. if (!StretchBlt(hdcSrc1, 0,0,nWidthDest,nHeightDest,
  280. hdcSrc,  nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc,
  281. SRCCOPY))
  282. goto HANDLEERROR;
  283. // Capture a copy of the destination area.
  284. if (!BitBlt(hdcSrc2, 0, 0, nWidthDest, nHeightDest,
  285. hdcDest, nXOriginDest, nYOriginDest, SRCCOPY))
  286. goto HANDLEERROR;
  287. SelectObject(hdcSrc1, hbmOldSrc1); hbmOldSrc1 = NULL;
  288. SelectObject(hdcSrc2, hbmOldSrc2); hbmOldSrc2 = NULL;
  289. // Blend the two source areas to create the destination image.
  290. bReturn = BlendImages(hbmSrc1, bRTLSrc, hbmSrc2, bRTLDest, hbmDst);
  291. // Display the blended (destination) image to the target HDC.
  292. if (bReturn)
  293. {
  294. hbmOldSrc1 = (HBITMAP)SelectObject(hdcSrc1, hbmDst);
  295. BitBlt(hdcDest, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest,
  296. hdcSrc1, 0,0, SRCCOPY | (bRTLDest ? NOMIRRORBITMAP : 0));
  297. SelectObject(hdcSrc1, hbmOldSrc1);
  298. hbmOldSrc1 = NULL;
  299. }
  300. // Clean up the rest of the objects you created.
  301. HANDLEERROR:
  302. if (hbmOldSrc1) SelectObject(hdcSrc1, hbmOldSrc1);
  303. if (hbmOldSrc2) SelectObject(hdcSrc2, hbmOldSrc2);
  304. if (hdcSrc1) DeleteDC(hdcSrc1);
  305. if (hdcSrc2) DeleteDC(hdcSrc2);
  306. if (hbmSrc1) DeleteObject(hbmSrc1);
  307. if (hbmSrc2) DeleteObject(hbmSrc2);
  308. if (hbmDst) DeleteObject(hbmDst);
  309. return bReturn;
  310. }
  311. BOOL CXTPImageManager::AlphaBlend(HDC hdcDest, const CRect& rcDest, HDC hdcSrc, const CRect& rcSrc) const
  312. {
  313. if (XTPDrawHelpers()->IsContextRTL(hdcDest) && XTPSystemVersion()->IsWin9x())
  314. {
  315. return DoAlphaBlend(hdcDest, rcDest.left, rcDest.top, rcDest.Width(), rcDest.Height(),
  316. hdcSrc, rcSrc.left, rcSrc.top, rcSrc.Width(), rcSrc.Height());
  317. }
  318. if (XTPDrawHelpers()->m_pfnAlphaBlend && (IsWindow2000() || (rcSrc.top == 0 && rcSrc.left == 0 && rcDest.top >= 0)))
  319. {
  320. BLENDFUNCTION bf;
  321. ZeroMemory(&bf, sizeof(BLENDFUNCTION));
  322. bf.AlphaFormat  = 0x01;
  323. bf.SourceConstantAlpha = 255;
  324. bf.BlendOp = AC_SRC_OVER;
  325. return XTPDrawHelpers()->m_pfnAlphaBlend(hdcDest, rcDest.left, rcDest.top, rcDest.Width(), rcDest.Height(),
  326. hdcSrc, rcSrc.left, rcSrc.top, rcSrc.Width(), rcSrc.Height(), bf);
  327. }
  328. return DoAlphaBlend(hdcDest, rcDest.left, rcDest.top, rcDest.Width(), rcDest.Height(),
  329. hdcSrc, rcSrc.left, rcSrc.top, rcSrc.Width(), rcSrc.Height());
  330. }
  331. BOOL CXTPImageManager::AlphaBlend2(HDC hdcDest, const CRect& rcDest, HDC hdcSrc, const CRect& rcSrc, BYTE Transparency) const
  332. {
  333. if (XTPDrawHelpers()->IsContextRTL(hdcDest) && XTPSystemVersion()->IsWin9x())
  334. {
  335. return DoAlphaBlend(hdcDest, rcDest.left, rcDest.top, rcDest.Width(), rcDest.Height(),
  336. hdcSrc, rcSrc.left, rcSrc.top, rcSrc.Width(), rcSrc.Height());
  337. }
  338. if (XTPDrawHelpers()->m_pfnAlphaBlend && (IsWindow2000() || (rcSrc.top == 0 && rcSrc.left == 0)))
  339. {
  340. BLENDFUNCTION bf;
  341. ZeroMemory(&bf, sizeof(BLENDFUNCTION));
  342. bf.AlphaFormat  = 0;
  343. bf.SourceConstantAlpha = Transparency;
  344. bf.BlendOp = AC_SRC_OVER;
  345. return XTPDrawHelpers()->m_pfnAlphaBlend(hdcDest, rcDest.left, rcDest.top, rcDest.Width(), rcDest.Height(),
  346. hdcSrc, rcSrc.left, rcSrc.top, rcSrc.Width(), rcSrc.Height(), bf);
  347. }
  348. return DoAlphaBlend(hdcDest, rcDest.left, rcDest.top, rcDest.Width(), rcDest.Height(),
  349. hdcSrc, rcSrc.left, rcSrc.top, rcSrc.Width(), rcSrc.Height());
  350. }
  351. //////////////////////////////////////////////////////////////////////////
  352. // CXTPImageManagerImageList
  353. CXTPImageManagerImageList::CXTPImageManagerImageList()
  354. {
  355. m_hImageList = NULL;
  356. m_bDestroyImageList = FALSE;
  357. m_nBaseCommand = 0;
  358. m_pImageManager = NULL;
  359. }
  360. CXTPImageManagerImageList::~CXTPImageManagerImageList()
  361. {
  362. if (m_hImageList && m_bDestroyImageList)
  363. {
  364. ImageList_Destroy(m_hImageList);
  365. }
  366. RemoveAll();
  367. }
  368. void CXTPImageManagerImageList::RemoveAll()
  369. {
  370. UINT nCommand;
  371. CXTPImageManagerIcon* pIcon;
  372. POSITION pos = m_mapIcons.GetStartPosition();
  373. while (pos)
  374. {
  375. m_mapIcons.GetNextAssoc(pos, nCommand, pIcon);
  376. pIcon->InternalRelease();
  377. }
  378. m_mapIcons.RemoveAll();
  379. }
  380. BOOL CXTPImageManagerImageList::Lookup(UINT nCommand)
  381. {
  382. return ((nCommand >= m_nBaseCommand) &&
  383. (nCommand < m_nBaseCommand + ImageList_GetImageCount(m_hImageList)));
  384. }
  385. CSize CXTPImageManagerImageList::GetIconSize() const
  386. {
  387. int nWidth = 0, nHeight = 0;
  388. VERIFY(ImageList_GetIconSize(m_hImageList, &nWidth, &nHeight));
  389. return CSize(nWidth, nHeight);
  390. }
  391. CXTPImageManagerIcon* CXTPImageManagerImageList::GetIcon(UINT nCommand)
  392. {
  393. CXTPImageManagerIcon* pImage = NULL;
  394. if (m_mapIcons.Lookup(nCommand, pImage))
  395. {
  396. return pImage;
  397. }
  398. CSize sz = GetIconSize();
  399. pImage = new CXTPImageManagerIcon(nCommand, sz.cx, sz.cy, this);
  400. m_mapIcons.SetAt(nCommand, pImage);
  401. return pImage;
  402. }
  403. void CXTPImageManagerImageList::Draw(CDC* pDC, CPoint pt, CXTPImageManagerIcon* pIcon, CSize szIcon)
  404. {
  405. ImageList_DrawEx(m_hImageList, pIcon->GetID() - m_nBaseCommand, pDC->GetSafeHdc(),
  406. pt.x, pt.y, szIcon.cx, szIcon.cy, CLR_NONE, CLR_NONE, ILD_TRANSPARENT | ILD_NORMAL);
  407. }
  408. //////////////////////////////////////////////////////////////////////////
  409. // CXTPImageManagerIcon
  410. struct CXTPImageManagerIcon::ICONIMAGE
  411. {
  412. BITMAPINFOHEADER    icHeader;   // DIB header
  413. RGBQUAD             icColors[1];// Color table
  414. BYTE                icXOR[1];   // DIB bits for XOR mask
  415. BYTE                icAND[1];   // DIB bits for AND mask
  416. };
  417. #pragma pack(push, 2)
  418. // resources are WORD-aligned
  419. struct CXTPImageManagerIcon::ICONDIRENTRY
  420. {
  421. BYTE        bWidth;             // Width, in pixels, of the image
  422. BYTE        bHeight;            // Height, in pixels, of the image
  423. BYTE        bColorCount;        // Number of colors in image (0 if >= 8bpp)
  424. BYTE        bReserved;          // Reserved (must be 0)
  425. WORD        wPlanes;            // Color Planes
  426. WORD        wBitCount;          // Bits per pixel
  427. DWORD       dwBytesInRes;       // How many bytes in this resource ?
  428. DWORD       dwImageOffset;      // Where in the file is this image ?
  429. };
  430. struct CXTPImageManagerIcon::ICONDIRHEADER
  431. {
  432. WORD            idReserved;     // Reserved (must be 0)
  433. WORD            idType;         // Resource Type (1 for icons)
  434. WORD            idCount;        // How many images ?
  435. };
  436. struct CXTPImageManagerIcon::GRPICONDIRENTRY
  437. {
  438. BYTE   bWidth;                  // Width, in pixels, of the image
  439. BYTE   bHeight;                 // Height, in pixels, of the image
  440. BYTE   bColorCount;             // Number of colors in image (0 if >= 8bpp)
  441. BYTE   bReserved;               // Reserved
  442. WORD   wPlanes;                 // Color Planes
  443. WORD   wBitCount;               // Bits per pixel
  444. DWORD  dwBytesInRes;            // how many bytes in this resource ?
  445. WORD   nID;                     // the ID
  446. };
  447. struct CXTPImageManagerIcon::GRPICONDIR
  448. {
  449. WORD              idReserved;   // Reserved (must be 0)
  450. WORD              idType;       // Resource type (1 for icons)
  451. WORD              idCount;      // How many images ?
  452. GRPICONDIRENTRY   idEntries[1]; // The entries for each image
  453. };
  454. #pragma pack(pop)
  455. BOOL CXTPImageManagerIcon::IsAlphaBitmapFile(LPCTSTR pszFileName)
  456. {
  457. HANDLE hFile = CreateFile(pszFileName, GENERIC_READ, 0, NULL,
  458. OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
  459. if (hFile == INVALID_HANDLE_VALUE)
  460. {
  461. return FALSE;
  462. }
  463. DWORD dwBytesRead;
  464. BITMAPFILEHEADER fileHeader;
  465. if (!ReadFile(hFile, &fileHeader, sizeof(BITMAPFILEHEADER), &dwBytesRead, 0) || dwBytesRead != sizeof(BITMAPFILEHEADER))
  466. {
  467. CloseHandle(hFile);
  468. return FALSE;
  469. }
  470. BITMAPINFOHEADER infoHeader;
  471. if (!ReadFile(hFile, &infoHeader, sizeof(BITMAPINFOHEADER), &dwBytesRead, 0) || dwBytesRead != sizeof(BITMAPINFOHEADER))
  472. {
  473. CloseHandle(hFile);
  474. return FALSE;
  475. }
  476. BOOL bResult = infoHeader.biBitCount == 32;
  477. CloseHandle(hFile);
  478. return bResult;
  479. }
  480. BOOL CXTPImageManagerIcon::IsPngBitmapFile(LPCTSTR pszFileName)
  481. {
  482. HANDLE hFile = CreateFile(pszFileName, GENERIC_READ, 0, NULL,
  483. OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
  484. if (hFile == INVALID_HANDLE_VALUE)
  485. {
  486. return FALSE;
  487. }
  488. DWORD dwBytesRead;
  489. BYTE fileHeader[4];
  490. BYTE png_signature[4] = {137, 80, 78, 71};
  491. if (!ReadFile(hFile, &fileHeader, sizeof(fileHeader), &dwBytesRead, 0) || dwBytesRead != sizeof(fileHeader))
  492. {
  493. CloseHandle(hFile);
  494. return FALSE;
  495. }
  496. BOOL bResult = memcmp(&fileHeader, &png_signature, 4) == 0;
  497. CloseHandle(hFile);
  498. return bResult;
  499. }
  500. HBITMAP AFX_CDECL CXTPImageManagerIcon::LoadBitmapFromFile(LPCTSTR lpszFileName, BOOL* lbAlphaBitmap)
  501. {
  502. #ifdef _XTP_INCLUDE_GRAPHICLIBRARY
  503. BOOL bPngBitmap = CXTPImageManagerIcon::IsPngBitmapFile(lpszFileName);
  504. if (bPngBitmap)
  505. {
  506. CXTPGraphicBitmapPng bmp;
  507. if (!bmp.LoadFromFile(lpszFileName))
  508. return NULL;
  509. if (lbAlphaBitmap)
  510. {
  511. *lbAlphaBitmap = bmp.IsAlpha();
  512. }
  513. return (HBITMAP)bmp.Detach();
  514. }
  515. #endif
  516. BOOL bAlphaBitmap = CXTPImageManagerIcon::IsAlphaBitmapFile(lpszFileName);
  517. HBITMAP hBmp = (HBITMAP)LoadImage(0, lpszFileName,
  518. IMAGE_BITMAP, 0, 0, LR_DEFAULTSIZE | (bAlphaBitmap ? LR_CREATEDIBSECTION : 0) | LR_LOADFROMFILE);
  519. if (lbAlphaBitmap)
  520. {
  521. *lbAlphaBitmap = bAlphaBitmap;
  522. }
  523. return hBmp;
  524. }
  525. BOOL AFX_CDECL CXTPImageManagerIcon::IsPngBitmapResource(HMODULE hModule, LPCTSTR lpBitmapName)
  526. {
  527. BYTE png_signature[4] = {137, 80, 78, 71};
  528. HRSRC hResource = ::FindResource(hModule, lpBitmapName, _T("PNG"));
  529. if (hResource == NULL)
  530. return FALSE;
  531. HGLOBAL hGlobal = LoadResource(hModule, hResource);
  532. if (hGlobal == NULL)
  533. return FALSE;
  534. LPBYTE pBitmapInfoHeader = (LPBYTE)::LockResource(hGlobal);
  535. BOOL bPngBitmap = memcmp(pBitmapInfoHeader, &png_signature, 4) == 0;
  536. UnlockResource(hGlobal);
  537. FreeResource(hGlobal);
  538. return (bPngBitmap);
  539. }
  540. BOOL AFX_CDECL CXTPImageManagerIcon::IsAlphaBitmapResource(HMODULE hModule, LPCTSTR lpBitmapName)
  541. {
  542. HRSRC hResource = ::FindResource(hModule, lpBitmapName, RT_BITMAP);
  543. if (hResource == NULL)
  544. return FALSE;
  545. HGLOBAL hGlobal = LoadResource(hModule, hResource);
  546. if (hGlobal == NULL)
  547. return FALSE;
  548. LPBITMAPINFOHEADER pBitmapInfoHeader = (LPBITMAPINFOHEADER)::LockResource(hGlobal);
  549. ASSERT(pBitmapInfoHeader != NULL);
  550. if (!pBitmapInfoHeader)
  551. return FALSE;
  552. BOOL bAlpahBitmap = pBitmapInfoHeader->biBitCount == 32;
  553. UnlockResource(hGlobal);
  554. FreeResource(hGlobal);
  555. return (bAlpahBitmap);
  556. }
  557. HBITMAP AFX_CDECL CXTPImageManagerIcon::LoadBitmapFromResource(LPCTSTR lpszResource, BOOL* lbAlphaBitmap)
  558. {
  559. HMODULE hModule;
  560. #ifdef _XTP_INCLUDE_GRAPHICLIBRARY
  561. hModule = AfxFindResourceHandle(lpszResource, _T("PNG"));
  562. BOOL bPngBitmap = IsPngBitmapResource(hModule, lpszResource);
  563. if (bPngBitmap)
  564. {
  565. CXTPGraphicBitmapPng bmpIcons;
  566. HRSRC hResource = ::FindResource(hModule, lpszResource, _T("PNG"));
  567. if (!bmpIcons.LoadFromResource(hModule, hResource))
  568. return NULL;
  569. if (lbAlphaBitmap)
  570. {
  571. *lbAlphaBitmap = bmpIcons.IsAlpha();
  572. }
  573. return (HBITMAP)bmpIcons.Detach();
  574. }
  575. #endif
  576. hModule = AfxFindResourceHandle(lpszResource, RT_BITMAP);
  577. CBitmap bmpIcons;
  578. BOOL bAlphaBitmap = IsAlphaBitmapResource(hModule, lpszResource);
  579. if (lbAlphaBitmap)
  580. {
  581. *lbAlphaBitmap = bAlphaBitmap;
  582. }
  583. if (bAlphaBitmap)
  584. {
  585. return LoadAlphaBitmap(hModule, lpszResource);
  586. }
  587. return (HBITMAP)LoadImage(hModule, lpszResource, IMAGE_BITMAP, 0, 0, LR_DEFAULTSIZE);
  588. }
  589. HBITMAP AFX_CDECL CXTPImageManagerIcon::LoadBitmapFromResource(HMODULE hModule, LPCTSTR lpszResource, BOOL* lbAlphaBitmap)
  590. {
  591. #ifdef _XTP_INCLUDE_GRAPHICLIBRARY
  592. BOOL bPngBitmap = IsPngBitmapResource(hModule, lpszResource);
  593. if (bPngBitmap)
  594. {
  595. CXTPGraphicBitmapPng bmpIcons;
  596. HRSRC hResource = ::FindResource(hModule, lpszResource, _T("PNG"));
  597. if (!bmpIcons.LoadFromResource(hModule, hResource))
  598. return NULL;
  599. if (lbAlphaBitmap)
  600. {
  601. *lbAlphaBitmap = bmpIcons.IsAlpha();
  602. }
  603. return (HBITMAP)bmpIcons.Detach();
  604. }
  605. #endif
  606. CBitmap bmpIcons;
  607. BOOL bAlphaBitmap = IsAlphaBitmapResource(hModule, lpszResource);
  608. if (lbAlphaBitmap)
  609. {
  610. *lbAlphaBitmap = bAlphaBitmap;
  611. }
  612. if (bAlphaBitmap)
  613. {
  614. return LoadAlphaBitmap(hModule, lpszResource);
  615. }
  616. return (HBITMAP)LoadImage(hModule, lpszResource, IMAGE_BITMAP, 0, 0, LR_DEFAULTSIZE);
  617. }
  618. HBITMAP CXTPImageManagerIcon::LoadAlphaBitmap(UINT nIDResource)
  619. {
  620. return LoadAlphaBitmap(AfxFindResourceHandle(MAKEINTRESOURCE(nIDResource), RT_BITMAP),
  621. MAKEINTRESOURCE(nIDResource));
  622. }
  623. HBITMAP CXTPImageManagerIcon::LoadAlphaBitmap(HMODULE hModule, LPCTSTR lpszResource)
  624. {
  625. HRSRC hResource = ::FindResource(hModule, lpszResource, RT_BITMAP);
  626. if (hResource == NULL)
  627. return NULL;
  628. HGLOBAL hGlobal = LoadResource(hModule, hResource);
  629. if (hGlobal == NULL)
  630. return NULL;
  631. LPBITMAPINFO pResourceInfo = (LPBITMAPINFO)::LockResource(hGlobal);
  632. ASSERT(pResourceInfo != NULL);
  633. if (!pResourceInfo)
  634. return NULL;
  635. int biSizeImage = pResourceInfo->bmiHeader.biHeight * pResourceInfo->bmiHeader.biWidth * 4;
  636. HBITMAP hbmResult = NULL;
  637. if (pResourceInfo->bmiHeader.biBitCount == 32 &&
  638. SizeofResource(hModule, hResource) >= int(biSizeImage + sizeof(BITMAPINFOHEADER)))
  639. {
  640. CDC dcSrc;
  641. dcSrc.CreateCompatibleDC(NULL);
  642. PBITMAPINFO pBitmapInfo = (PBITMAPINFO)malloc(sizeof(BITMAPINFOHEADER) + sizeof(COLORREF) * 3);
  643. ASSERT(pBitmapInfo != NULL);
  644. if (!pBitmapInfo)
  645. return NULL;
  646. MEMCPY_S(pBitmapInfo, &pResourceInfo->bmiHeader, sizeof(BITMAPINFOHEADER));
  647. pBitmapInfo->bmiHeader.biSizeImage = biSizeImage;
  648. BYTE* pDestBits = NULL;
  649. HBITMAP hBmp = CreateDIBSection(dcSrc, pBitmapInfo, DIB_RGB_COLORS, (void**)&pDestBits, NULL, 0);
  650. if (hBmp && pDestBits)
  651. {
  652. MEMCPY_S(pDestBits, &pResourceInfo->bmiColors, biSizeImage);
  653. hbmResult = hBmp;
  654. }
  655. FREE(pBitmapInfo);
  656. }
  657. UnlockResource(hGlobal);
  658. FreeResource(hGlobal);
  659. return hbmResult;
  660. }
  661. HBITMAP CXTPImageManagerIcon::LoadAlphaIcon(LPCTSTR pszFileName, int nWidth)
  662. {
  663. HANDLE hFile = CreateFile(pszFileName, GENERIC_READ, 0, NULL,
  664. OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
  665. if (hFile == INVALID_HANDLE_VALUE)
  666. {
  667. return NULL;
  668. }
  669. ICONDIRHEADER idh;
  670. DWORD dwBytesRead = 0;
  671. if (!ReadFile(hFile, &idh, sizeof(ICONDIRHEADER) , &dwBytesRead, NULL) || dwBytesRead != sizeof(ICONDIRHEADER))
  672. {
  673. CloseHandle(hFile);
  674. return FALSE;
  675. }
  676. if (idh.idType != 1 || idh.idCount == 0)
  677. {
  678. CloseHandle(hFile);
  679. return FALSE;
  680. }
  681. ICONDIRENTRY* pEntries = (ICONDIRENTRY*)malloc(sizeof(ICONDIRENTRY) * idh.idCount);
  682. if (pEntries == NULL)
  683. {
  684. CloseHandle(hFile);
  685. return FALSE;
  686. }
  687. if (!ReadFile(hFile, pEntries, idh.idCount * sizeof(ICONDIRENTRY), &dwBytesRead, NULL)
  688. || dwBytesRead != idh.idCount * sizeof(ICONDIRENTRY))
  689. {
  690. free(pEntries);
  691. CloseHandle(hFile);
  692. return FALSE;
  693. }
  694. HBITMAP hBitmap = 0;
  695. for (int i = 0; i < idh.idCount; i++)
  696. {
  697. if (pEntries[i].wBitCount == 32 && (((int)pEntries[i].bWidth == nWidth) || (nWidth == 0)))
  698. {
  699. if (!SetFilePointer(hFile, pEntries[i].dwImageOffset,
  700. NULL, FILE_BEGIN))
  701. continue;
  702. ICONIMAGE* pIconImage = (ICONIMAGE*)malloc(pEntries[i].dwBytesInRes);
  703. if (pIconImage == NULL)
  704. continue;
  705. dwBytesRead = 0;
  706. BOOL bResult = ReadFile(hFile, pIconImage, pEntries[i].dwBytesInRes,
  707. &dwBytesRead, NULL);
  708. if (!bResult || (dwBytesRead != pEntries[i].dwBytesInRes) || (pIconImage->icHeader.biBitCount != 32))
  709. {
  710. free(pIconImage);
  711. continue;
  712. }
  713. CDC dcSrc;
  714. dcSrc.CreateCompatibleDC(NULL);
  715. pIconImage->icHeader.biHeight /= 2;
  716. pIconImage->icHeader.biSizeImage = pIconImage->icHeader.biHeight * pIconImage->icHeader.biWidth * 4;
  717. BYTE* pDest = NULL;
  718. HBITMAP hBmp = CreateDIBSection(dcSrc, (BITMAPINFO*)&pIconImage->icHeader, DIB_RGB_COLORS, (void**)&pDest, NULL, 0);
  719. if (pDest != NULL && hBmp != NULL)
  720. {
  721. MEMCPY_S(pDest, &pIconImage->icColors, pIconImage->icHeader.biSizeImage);
  722. hBitmap = hBmp;
  723. free(pIconImage);
  724. break;
  725. }
  726. free(pIconImage);
  727. }
  728. }
  729. free(pEntries);
  730. CloseHandle(hFile);
  731. return hBitmap;
  732. }
  733. BOOL CXTPImageManager::SetIconFromIcoFile(LPCTSTR pszFileName, UINT nIDCommand, CSize szIcon, XTPImageState imageState)
  734. {
  735. HANDLE hFile = CreateFile(pszFileName, GENERIC_READ, 0, NULL,
  736. OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
  737. if (hFile == INVALID_HANDLE_VALUE)
  738. {
  739. return FALSE;
  740. }
  741. CXTPImageManagerIcon::ICONDIRHEADER idh;
  742. DWORD dwBytesRead = 0;
  743. if (!ReadFile(hFile, &idh, sizeof(CXTPImageManagerIcon::ICONDIRHEADER) , &dwBytesRead, NULL) || dwBytesRead != sizeof(CXTPImageManagerIcon::ICONDIRHEADER))
  744. {
  745. CloseHandle(hFile);
  746. return FALSE;
  747. }
  748. if (idh.idType != 1 || idh.idCount == 0)
  749. {
  750. CloseHandle(hFile);
  751. return FALSE;
  752. }
  753. CXTPImageManagerIcon::ICONDIRENTRY* pEntries = (CXTPImageManagerIcon::ICONDIRENTRY*)malloc(sizeof(CXTPImageManagerIcon::ICONDIRENTRY) * idh.idCount);
  754. if (pEntries == NULL)
  755. {
  756. CloseHandle(hFile);
  757. return FALSE;
  758. }
  759. if (!ReadFile(hFile, pEntries, idh.idCount * sizeof(CXTPImageManagerIcon::ICONDIRENTRY), &dwBytesRead, NULL)
  760. || dwBytesRead != idh.idCount * sizeof(CXTPImageManagerIcon::ICONDIRENTRY))
  761. {
  762. free(pEntries);
  763. CloseHandle(hFile);
  764. return FALSE;
  765. }
  766. BOOL bResult = FALSE;
  767. for (int i = 0; i < idh.idCount; i++)
  768. {
  769. CSize szResourceIcon((int)pEntries[i].bWidth, (int)pEntries[i].bHeight);
  770. CXTPImageManagerIconHandle hIcon;
  771. if ((szIcon == szResourceIcon) || (szIcon == CSize(0, 0)))
  772. {
  773. if (!SetFilePointer(hFile, pEntries[i].dwImageOffset,
  774. NULL, FILE_BEGIN))
  775. continue;
  776. CXTPImageManagerIcon::ICONIMAGE* pIconImage = (CXTPImageManagerIcon::ICONIMAGE*)malloc(pEntries[i].dwBytesInRes);
  777. if (pIconImage == NULL)
  778. continue;
  779. dwBytesRead = 0;
  780. BOOL bReadFile = ReadFile(hFile, pIconImage, pEntries[i].dwBytesInRes,
  781. &dwBytesRead, NULL);
  782. if (!bReadFile || (dwBytesRead != pEntries[i].dwBytesInRes))
  783. {
  784. free(pIconImage);
  785. continue;
  786. }
  787. if (pIconImage->icHeader.biBitCount == 32)
  788. {
  789. CDC dcSrc;
  790. dcSrc.CreateCompatibleDC(NULL);
  791. pIconImage->icHeader.biHeight /= 2;
  792. pIconImage->icHeader.biSizeImage = pIconImage->icHeader.biHeight * pIconImage->icHeader.biWidth * 4;
  793. BYTE* pDest = NULL;
  794. HBITMAP hBitmap = CreateDIBSection(dcSrc, (BITMAPINFO*)&pIconImage->icHeader, DIB_RGB_COLORS, (void**)&pDest, NULL, 0);
  795. if (pDest != NULL && hBitmap != NULL)
  796. {
  797. MEMCPY_S(pDest, &pIconImage->icColors, pIconImage->icHeader.biSizeImage);
  798. hIcon = hBitmap;
  799. }
  800. }
  801. else
  802. {
  803. hIcon = CreateIconFromResourceEx((PBYTE)pIconImage, pEntries[i].dwBytesInRes, TRUE,
  804. 0x00030000, szResourceIcon.cx, szResourceIcon.cy, LR_DEFAULTCOLOR);
  805. }
  806. if (!hIcon.IsEmpty())
  807. {
  808. SetIcon(hIcon, nIDCommand, szResourceIcon, imageState);
  809. bResult = TRUE;
  810. }
  811. free(pIconImage);
  812. }
  813. }
  814. free(pEntries);
  815. CloseHandle(hFile);
  816. return bResult;
  817. }
  818. //////////////////////////////////////////////////////////////////////////
  819. // CXTPImageManagerResource
  820. CXTPImageManagerResource::CXTPImageManagerResource(CXTPImageManager* pImageManager, CSize szIcon)
  821. {
  822. m_pImageManager = pImageManager;
  823. m_szIcon = szIcon;
  824. m_pBits = NULL;
  825. m_nAllocWidth = 0;
  826. m_hbmpImage = 0;
  827. m_hbmpMask = 0;
  828. HDC hdcScreen = ::GetDC(HWND_DESKTOP);
  829. m_dc.Attach(::CreateCompatibleDC(hdcScreen));
  830. ReleaseDC(HWND_DESKTOP, hdcScreen);
  831. ::InitializeCriticalSection(&m_cs);
  832. }
  833. CXTPImageManagerResource::~CXTPImageManagerResource()
  834. {
  835. RemoveAll();
  836. ::DeleteCriticalSection(&m_cs);
  837. }
  838. void CXTPImageManagerResource::RemoveAll()
  839. {
  840. int i;
  841. for (i = 0; i < (int)m_arrIcons.GetSize(); i++)
  842. {
  843. delete m_arrIcons[i];
  844. }
  845. m_arrIcons.RemoveAll();
  846. for (i = 0; i < (int)m_arrAlloc.GetSize(); i++)
  847. {
  848. delete m_arrAlloc[i];
  849. }
  850. m_arrAlloc.RemoveAll();
  851. if (m_hbmpImage)
  852. {
  853. DeleteObject(m_hbmpImage);
  854. m_hbmpImage = NULL;
  855. }
  856. if (m_hbmpMask)
  857. {
  858. DeleteObject(m_hbmpMask);
  859. m_hbmpMask = NULL;
  860. }
  861. m_nAllocWidth = 0;
  862. m_pBits = NULL;
  863. }
  864. CXTPImageManagerResource* CXTPImageManager::GetResource(CSize szIcon)
  865. {
  866. DWORD dwSize = MAKELONG(szIcon.cx, szIcon.cy);
  867. CXTPImageManagerResource* pResource = NULL;
  868. if (m_mapResources.Lookup(dwSize, pResource))
  869. return pResource;
  870. pResource = new CXTPImageManagerResource(this, szIcon);
  871. m_mapResources.SetAt(dwSize, pResource);
  872. return pResource;
  873. }
  874. XTP_IMAGERESOURCE_INFO* CXTPImageManagerResource::AllocBitmap()
  875. {
  876. if (m_arrAlloc.GetSize() > 0)
  877. {
  878. XTP_IMAGERESOURCE_INFO* pRInfo = m_arrAlloc[m_arrAlloc.GetSize() - 1];
  879. m_arrAlloc.RemoveAt(m_arrAlloc.GetSize() - 1);
  880. m_arrIcons.Add(pRInfo);
  881. return pRInfo;
  882. }
  883. if (!m_hbmpImage && !m_hbmpMask)
  884. {
  885. m_hbmpImage = CXTPImageManager::Create32BPPDIBSection(NULL, m_szIcon.cx, m_szIcon.cy, &m_pBits);
  886. m_hbmpMask = CreateBitmap(m_szIcon.cx, m_szIcon.cy, 1, 1, NULL);
  887. m_nAllocWidth = m_szIcon.cx;
  888. if (!m_hbmpImage || !m_hbmpMask)
  889. return NULL;
  890. XTP_IMAGERESOURCE_INFO* pRInfo = new XTP_IMAGERESOURCE_INFO();
  891. pRInfo->pResource = this;
  892. pRInfo->bAlpha = FALSE;
  893. pRInfo->rc = CRect(0, 0, m_szIcon.cx, m_szIcon.cy);
  894. m_arrIcons.Add(pRInfo);
  895. return pRInfo;
  896. }
  897. LPBYTE pBits = NULL;
  898. HBITMAP hbmpImage = CXTPImageManager::Create32BPPDIBSection(NULL, m_szIcon.cx + m_nAllocWidth, m_szIcon.cy, &pBits);
  899. HBITMAP hbmpMask = CreateBitmap(m_szIcon.cx + m_nAllocWidth, m_szIcon.cy, 1, 1, NULL);
  900. if (hbmpImage && pBits)
  901. {
  902. LPBYTE pBitsI = pBits;
  903. for (int y = 0; y < m_szIcon.cy; y++)
  904. {
  905. memcpy(pBitsI, m_pBits, m_nAllocWidth * 4);
  906. m_pBits += m_nAllocWidth * 4;
  907. pBitsI += (m_szIcon.cx + m_nAllocWidth) * 4;
  908. }
  909. }
  910. else
  911. {
  912. return NULL;
  913. }
  914. if (hbmpMask)
  915. {
  916. m_dc.SetBitmap(hbmpMask);
  917. m_dc.DrawState(CPoint(0, 0), CSize(0, 0), m_hbmpMask, 0, 0);
  918. m_dc.SetBitmap(NULL);
  919. }
  920. else
  921. {
  922. return NULL;
  923. }
  924. DeleteObject(m_hbmpImage);
  925. DeleteObject(m_hbmpMask);
  926. m_hbmpImage = hbmpImage;
  927. m_hbmpMask = hbmpMask;
  928. m_pBits = pBits;
  929. XTP_IMAGERESOURCE_INFO* pRInfo = new XTP_IMAGERESOURCE_INFO();
  930. pRInfo->pResource = this;
  931. pRInfo->bAlpha = FALSE;
  932. pRInfo->rc = CRect(m_nAllocWidth, 0, m_nAllocWidth + m_szIcon.cx, m_szIcon.cy);
  933. m_arrIcons.Add(pRInfo);
  934. m_nAllocWidth += m_szIcon.cx;
  935. return pRInfo;
  936. }
  937. void CXTPImageManagerResource::Clear(XTP_IMAGERESOURCE_INFO* pRInfo)
  938. {
  939. CXTPLockGuard lock(m_cs);
  940. for (int i = 0; i < (int)m_arrIcons.GetSize(); i++)
  941. {
  942. if (m_arrIcons[i] == pRInfo)
  943. {
  944. m_arrIcons.RemoveAt(i);
  945. m_arrAlloc.Add(pRInfo);
  946. if (m_arrAlloc.GetSize() * m_szIcon.cx == m_nAllocWidth)
  947. {
  948. ASSERT(m_arrIcons.GetSize() == 0);
  949. RemoveAll();
  950. }
  951. return;
  952. }
  953. }
  954. }
  955. XTP_IMAGERESOURCE_INFO* CXTPImageManagerResource::Add(const CXTPImageManagerIconHandle& hHandle)
  956. {
  957. CXTPLockGuard lock(m_cs);
  958. ASSERT(hHandle.m_pRInfo == NULL);
  959. ASSERT(!hHandle.IsEmpty());
  960. if (hHandle.IsEmpty())
  961. return NULL;
  962. if (hHandle.GetExtent() != GetExtent())
  963. return NULL;
  964. if (!hHandle.m_hIcon && !hHandle.m_hBitmap)
  965. return NULL;
  966. XTP_IMAGERESOURCE_INFO* pRInfo = AllocBitmap();
  967. if (pRInfo == NULL)
  968. return NULL;
  969. if (hHandle.m_hIcon)
  970. {
  971. ICONINFO iconInfo;
  972. if (CXTPImageManager::IsAlphaIconsImageListSupported() && GetIconInfo(hHandle.m_hIcon, &iconInfo))
  973. {
  974. LPBYTE pBitsI = NULL;
  975. BOOL bAlpha = -1;
  976. HBITMAP hBitmap = CXTPImageManagerIcon::PreMultiplyAlphaBitmap(iconInfo.hbmColor, &bAlpha, &pBitsI);
  977. DeleteObject(iconInfo.hbmColor);
  978. DeleteObject(iconInfo.hbmMask);
  979. if (bAlpha == TRUE && pBitsI)
  980. {
  981. for (int y = 0; y < m_szIcon.cy; y++)
  982. {
  983. LPBYTE pBitsRow = m_pBits + ((y * m_nAllocWidth + pRInfo->rc.left) * 4);
  984. memcpy(pBitsRow, pBitsI, m_szIcon.cx * 4);
  985. pBitsI += m_szIcon.cx * 4;
  986. }
  987. pRInfo->bAlpha = TRUE;
  988. DeleteObject(hBitmap);
  989. return pRInfo;
  990. }
  991. if (hBitmap) DeleteObject(hBitmap);
  992. }
  993. if (m_hbmpImage)
  994. {
  995. m_dc.SetBitmap(m_hbmpImage);
  996. m_dc.FillSolidRect(pRInfo->rc, 0);
  997. DrawIconEx(m_dc, pRInfo->rc.left, pRInfo->rc.top, hHandle.m_hIcon, 0, 0, 0, NULL, DI_NORMAL);
  998. m_dc.SetBitmap(NULL);
  999. }
  1000. if (m_hbmpMask)
  1001. {
  1002. m_dc.SetBitmap(m_hbmpMask);
  1003. m_dc.FillSolidRect(pRInfo->rc, 0);
  1004. DrawIconEx(m_dc, pRInfo->rc.left, pRInfo->rc.top, hHandle.m_hIcon, 0, 0, 0, NULL, DI_MASK);
  1005. m_dc.SetBitmap(NULL);
  1006. }
  1007. pRInfo->bAlpha = FALSE;
  1008. }
  1009. else
  1010. {
  1011. LPBYTE pBitsI = ((CXTPImageManagerIconHandle&)hHandle).PreMultiply();
  1012. if (!pBitsI)
  1013. return NULL;
  1014. for (int y = 0; y < m_szIcon.cy; y++)
  1015. {
  1016. LPBYTE pBitsRow = m_pBits + ((y * m_nAllocWidth + pRInfo->rc.left) * 4);
  1017. memcpy(pBitsRow, pBitsI, m_szIcon.cx * 4);
  1018. pBitsI += m_szIcon.cx * 4;
  1019. }
  1020. pRInfo->bAlpha = TRUE;
  1021. }
  1022. return pRInfo;
  1023. }
  1024. BOOL CXTPImageManager::IsDrawReverted(CDC* pDC) const
  1025. {
  1026. if (m_bDrawReverted == 1)
  1027. return TRUE;
  1028. if (m_bDrawReverted == 2)
  1029. return CXTPDrawHelpers::IsContextRTL(pDC);
  1030. return FALSE;
  1031. }
  1032. void CXTPImageManagerResource::CreateIcon(CXTPImageManagerIconHandle& hHandle, XTP_IMAGERESOURCE_INFO* pRInfo)
  1033. {
  1034. CXTPLockGuard lock(m_cs);
  1035. hHandle.Clear();
  1036. HBITMAP hBitmap = 0;
  1037. LPBYTE pBits = 0;
  1038. {
  1039. hBitmap = CXTPImageManager::Create32BPPDIBSection(NULL, m_szIcon.cx, m_szIcon.cy, &pBits);
  1040. if (!hBitmap || !pBits)
  1041. return;
  1042. LPBYTE pBitsI = pBits;
  1043. for (int y = 0; y < m_szIcon.cy; y++)
  1044. {
  1045. LPBYTE pBitsRow = m_pBits + ((y * m_nAllocWidth + pRInfo->rc.left) * 4);
  1046. memcpy(pBitsI, pBitsRow, m_szIcon.cx * 4);
  1047. pBitsI += m_szIcon.cx * 4;
  1048. }
  1049. }
  1050. if (pRInfo->bAlpha)
  1051. {
  1052. hHandle.m_hBitmap = hBitmap;
  1053. hHandle.m_pBits = pBits;
  1054. }
  1055. else
  1056. {
  1057. HBITMAP hbmpMask = CreateBitmap(m_szIcon.cx, m_szIcon.cy, 1, 1, NULL);
  1058. {
  1059. CXTPCompatibleDC dc(0, hbmpMask);
  1060. m_dc.SetBitmap(m_hbmpMask);
  1061. dc.BitBlt(0, 0, m_szIcon.cx, m_szIcon.cy, &m_dc, pRInfo->rc.left, 0, SRCCOPY);
  1062. m_dc.SetBitmap(NULL);
  1063. }
  1064. ICONINFO ii;
  1065. ii.fIcon    = TRUE;
  1066. ii.xHotspot = 0;
  1067. ii.yHotspot = 0;
  1068. ii.hbmColor = hBitmap;
  1069. ii.hbmMask  = hbmpMask;
  1070. hHandle.m_hIcon = CreateIconIndirect(&ii);
  1071. DeleteObject(hBitmap);
  1072. DeleteObject(hbmpMask);
  1073. }
  1074. hHandle.m_bClearHandles = TRUE;
  1075. }
  1076. void CXTPImageManagerResource::DrawIconComposited(CDC* pDC, XTP_IMAGERESOURCE_INFO* pRInfo, CPoint pt, CSize szIcon)
  1077. {
  1078. CBitmap bmp;
  1079. LPDWORD lpBits = 0;
  1080. bmp.Attach(CXTPImageManager::Create32BPPDIBSection(pDC->GetSafeHdc(), szIcon.cx, szIcon.cy, (LPBYTE*)&lpBits));
  1081. if (!lpBits)
  1082. return;
  1083. CXTPCompatibleDC dc(&m_dc, &bmp);
  1084. dc.SetBkColor(0xFFFFFF);
  1085. dc.SetTextColor(0);
  1086. if (m_hbmpMask)
  1087. {
  1088. m_dc.SetBitmap(m_hbmpMask);
  1089. StretchBlt(dc, 0, 0, szIcon.cx, szIcon.cy, m_dc, pRInfo->rc.left, 0, m_szIcon.cx, m_szIcon.cy, SRCCOPY);
  1090. m_dc.SetBitmap(NULL);
  1091. }
  1092. for (int i = 0; i < szIcon.cx * szIcon.cy; i++)
  1093. {
  1094. *lpBits =  (*lpBits == 0) ? 0xFF000000 : 0;
  1095. lpBits++;
  1096. }
  1097. if (m_hbmpImage)
  1098. {
  1099. m_dc.SetBitmap(m_hbmpImage);
  1100. StretchBlt(dc, 0, 0, szIcon.cx, szIcon.cy, m_dc, pRInfo->rc.left, 0, m_szIcon.cx, m_szIcon.cy, SRCINVERT);
  1101. m_dc.SetBitmap(NULL);
  1102. }
  1103. XTPImageManager()->AlphaBlend(*pDC, CRect(pt, szIcon), dc, CRect(0, 0, szIcon.cx, szIcon.cy));
  1104. }
  1105. void CXTPImageManagerResource::Draw(CDC* pDC, XTP_IMAGERESOURCE_INFO* pRInfo, CPoint pt, CSize szIcon, BOOL bDrawComposited)
  1106. {
  1107. CXTPLockGuard lock(m_cs);
  1108. if (!pRInfo->bAlpha)
  1109. {
  1110. if (bDrawComposited)
  1111. {
  1112. DrawIconComposited(pDC, pRInfo, pt, szIcon);
  1113. return;
  1114. }
  1115. if (m_pImageManager->IsDrawReverted(pDC))
  1116. {
  1117. pt.x += szIcon.cx;
  1118. szIcon.cx = -szIcon.cx;
  1119. }
  1120. if (m_hbmpMask)
  1121. {
  1122. m_dc.SetBitmap(m_hbmpMask);
  1123. m_dc.SetTextColor(0);
  1124. m_dc.SetBkColor(0xFFFFFF);
  1125. COLORREF clrOldText = pDC->SetTextColor(0);
  1126. COLORREF clrOldBk = pDC->SetBkColor(0xFFFFFF);
  1127. StretchBlt(pDC->GetSafeHdc(), pt.x, pt.y, szIcon.cx, szIcon.cy, m_dc, pRInfo->rc.left,  0,  m_szIcon.cx, m_szIcon.cy, SRCAND);
  1128. pDC->SetBkColor(clrOldBk);
  1129. pDC->SetTextColor(clrOldText);
  1130. m_dc.SetBitmap(NULL);
  1131. }
  1132. if (m_hbmpImage)
  1133. {
  1134. m_dc.SetBitmap(m_hbmpImage);
  1135. StretchBlt(pDC->GetSafeHdc(), pt.x, pt.y, szIcon.cx, szIcon.cy, m_dc, pRInfo->rc.left,  0,  m_szIcon.cx, m_szIcon.cy, SRCINVERT);
  1136. m_dc.SetBitmap(NULL);
  1137. }
  1138. }
  1139. else
  1140. {
  1141. m_dc.SetBitmap(m_hbmpImage);
  1142. XTPImageManager()->AlphaBlend(pDC->GetSafeHdc(), CRect(pt, szIcon),
  1143. m_dc, CRect(pRInfo->rc.TopLeft(), m_szIcon));
  1144. m_dc.SetBitmap(NULL);
  1145. }
  1146. }
  1147. CSize CXTPImageManagerResource::GetExtent() const
  1148. {
  1149. return m_szIcon;
  1150. }
  1151. //////////////////////////////////////////////////////////////////////////
  1152. // CXTPImageManagerIconHandle
  1153. void CXTPImageManagerIconHandle::Init()
  1154. {
  1155. m_hIcon = NULL;
  1156. m_hBitmap = NULL;
  1157. m_pBits = NULL;
  1158. m_bClearHandles = FALSE;
  1159. m_pImageManager = NULL;
  1160. m_pRInfo = NULL;
  1161. m_szIcon = CSize(0, 0);
  1162. m_bUseResources = TRUE;
  1163. }
  1164. CXTPImageManagerIconHandle::CXTPImageManagerIconHandle()
  1165. {
  1166. Init();
  1167. }
  1168. CXTPImageManagerIconHandle::CXTPImageManagerIconHandle(HICON hIcon, BOOL bUseResources)
  1169. {
  1170. Init();
  1171. m_hIcon = hIcon;
  1172. m_bClearHandles = FALSE;
  1173. m_szIcon = _GetExtent();
  1174. m_bUseResources = bUseResources;
  1175. }
  1176. CXTPImageManagerIconHandle::CXTPImageManagerIconHandle(HBITMAP hBitmap)
  1177. {
  1178. Init();
  1179. m_hBitmap = hBitmap;
  1180. m_bClearHandles = FALSE;
  1181. m_szIcon = _GetExtent();
  1182. }
  1183. CXTPImageManagerIconHandle::CXTPImageManagerIconHandle(const CXTPImageManagerIconHandle& hHandle)
  1184. {
  1185. Init();
  1186. m_hIcon = hHandle.m_hIcon;
  1187. m_hBitmap = hHandle.m_hBitmap;
  1188. m_pBits = hHandle.m_pBits;
  1189. m_pRInfo = hHandle.m_pRInfo;
  1190. m_pImageManager = hHandle.m_pImageManager;
  1191. m_bUseResources = hHandle.m_bUseResources;
  1192. m_bClearHandles = FALSE;
  1193. m_szIcon = hHandle.GetExtent();
  1194. }
  1195. void CXTPImageManagerIconHandle::CopyHandle(HBITMAP hBitmap)
  1196. {
  1197. Clear();
  1198. m_hBitmap = CXTPImageManagerIcon::CopyAlphaBitmap(hBitmap);
  1199. m_szIcon = _GetExtent();
  1200. m_bClearHandles = TRUE;
  1201. }
  1202. void CXTPImageManagerIconHandle::CopyHandle(const CXTPImageManagerIconHandle& hHandle)
  1203. {
  1204. Clear();
  1205. if (m_pImageManager && !hHandle.IsEmpty() && m_pImageManager->m_bUseResources && hHandle.m_bUseResources)
  1206. {
  1207. CXTPImageManagerResource* pResource = m_pImageManager->GetResource(hHandle.GetExtent());
  1208. if (hHandle.m_pRInfo == NULL)
  1209. {
  1210. m_pRInfo = pResource->Add(hHandle);
  1211. }
  1212. else
  1213. {
  1214. CXTPImageManagerIconHandle iconClear;
  1215. iconClear.CopyHandle(hHandle);
  1216. m_pRInfo = pResource->Add(iconClear);
  1217. }
  1218. }
  1219. else
  1220. {
  1221. if (hHandle.m_hIcon) m_hIcon = CopyIcon(hHandle.m_hIcon);
  1222. if (hHandle.m_hBitmap) m_hBitmap = CXTPImageManagerIcon::CopyAlphaBitmap(hHandle.m_hBitmap, hHandle.m_pBits ? &m_pBits : NULL);
  1223. if (hHandle.m_pRInfo)
  1224. {
  1225. hHandle.m_pRInfo->pResource->CreateIcon(*this, hHandle.m_pRInfo);
  1226. }
  1227. }
  1228. m_bUseResources = hHandle.m_bUseResources;
  1229. m_bClearHandles = TRUE;
  1230. m_szIcon = hHandle.GetExtent();
  1231. }
  1232. const CXTPImageManagerIconHandle& CXTPImageManagerIconHandle::operator=(const HICON hIcon)
  1233. {
  1234. Clear();
  1235. m_hIcon = hIcon;
  1236. m_bClearHandles = TRUE;
  1237. m_szIcon = _GetExtent();
  1238. return *this;
  1239. }
  1240. const CXTPImageManagerIconHandle& CXTPImageManagerIconHandle::operator=(const HBITMAP hBitmap)
  1241. {
  1242. Clear();
  1243. m_hBitmap = hBitmap;
  1244. m_bClearHandles = TRUE;
  1245. m_szIcon = _GetExtent();
  1246. return *this;
  1247. }
  1248. CXTPImageManagerIconHandle::~CXTPImageManagerIconHandle()
  1249. {
  1250. Clear();
  1251. }
  1252. BOOL CXTPImageManagerIconHandle::IsEmpty() const
  1253. {
  1254. return (m_hIcon == 0 && m_hBitmap == 0 && m_pRInfo == NULL) || (m_szIcon == CSize(0, 0));
  1255. }
  1256. BOOL CXTPImageManagerIconHandle::IsAlpha() const
  1257. {
  1258. return m_hBitmap != 0 || (m_pRInfo && m_pRInfo->bAlpha);
  1259. }
  1260. HBITMAP CXTPImageManagerIconHandle::GetBitmap() const
  1261. {
  1262. ASSERT(IsAlpha());
  1263. return m_hBitmap;
  1264. }
  1265. HICON CXTPImageManagerIconHandle::GetIcon() const
  1266. {
  1267. return m_hIcon;
  1268. }
  1269. void CXTPImageManagerIconHandle::Clear()
  1270. {
  1271. if (m_bClearHandles)
  1272. {
  1273. if (m_hIcon)
  1274. {
  1275. DestroyIcon(m_hIcon);
  1276. }
  1277. if (m_hBitmap)
  1278. {
  1279. DeleteObject(m_hBitmap);
  1280. }
  1281. if (m_pRInfo)
  1282. {
  1283. m_pRInfo->pResource->Clear(m_pRInfo);
  1284. m_pRInfo = NULL;
  1285. }
  1286. }
  1287. m_hIcon = 0;
  1288. m_hBitmap = 0;
  1289. m_pBits = 0;
  1290. m_pRInfo = NULL;
  1291. m_bClearHandles = FALSE;
  1292. }
  1293. CSize CXTPImageManagerIconHandle::GetExtent() const
  1294. {
  1295. return m_szIcon;
  1296. }
  1297. CSize CXTPImageManagerIconHandle::_GetExtent() const
  1298. {
  1299. if (m_pRInfo != NULL)
  1300. return m_pRInfo->pResource->GetExtent();
  1301. if (m_hIcon)
  1302. return CXTPImageManagerIcon::GetExtent(m_hIcon);
  1303. if (m_hBitmap)
  1304. {
  1305. BITMAP bmpinfo;
  1306. if (::GetObject(m_hBitmap, sizeof(bmpinfo), &bmpinfo))
  1307. {
  1308. return CSize((int)bmpinfo.bmWidth, (int)bmpinfo.bmHeight);
  1309. }
  1310. }
  1311. return 0;
  1312. }
  1313. void CXTPImageManagerIconHandle::Draw(CDC* pDC, CPoint pt, CSize szIcon, BOOL bDrawComposited)
  1314. {
  1315. if (IsEmpty())
  1316. return;
  1317. if (m_pRInfo)
  1318. {
  1319. m_pRInfo->pResource->Draw(pDC, m_pRInfo, pt, szIcon, bDrawComposited);
  1320. }
  1321. else if (!IsAlpha())
  1322. {
  1323. CXTPImageManager* pImageManager = m_pImageManager ? m_pImageManager : XTPImageManager();
  1324. if (pImageManager->IsDrawReverted(pDC))
  1325. {
  1326. pt.x += szIcon.cx;
  1327. szIcon.cx = -szIcon.cx;
  1328. }
  1329. if (!bDrawComposited)
  1330. {
  1331. DrawIconEx(pDC->GetSafeHdc(), pt.x, pt.y, GetIcon(), szIcon.cx, szIcon.cy, 0, 0, DI_NORMAL);
  1332. }
  1333. else
  1334. {
  1335. CXTPImageManagerIcon::DrawIconComposited(pDC, pt, szIcon, GetIcon());
  1336. }
  1337. }
  1338. else if (PreMultiply())
  1339. {
  1340. if (pt.y < 0 && (szIcon.cy == (int)m_szIcon.cy))
  1341. {
  1342. if (pt.y + m_szIcon.cy > 0)
  1343. {
  1344. CXTPImageManagerIcon::DrawAlphaBitmap(pDC, m_hBitmap, CPoint(pt.x, 0),
  1345. CSize(szIcon.cx, m_szIcon.cy + pt.y), CPoint(0, -pt.y), CSize(m_szIcon.cx, m_szIcon.cy + pt.y));
  1346. }
  1347. }
  1348. else
  1349. {
  1350. CXTPImageManagerIcon::DrawAlphaBitmap(pDC, m_hBitmap, pt, szIcon, CPoint(0, 0), m_szIcon);
  1351. }
  1352. }
  1353. }
  1354. BOOL CXTPImageManagerIconHandle::CreateIconFromResource(LPCTSTR lpszResourceName, CSize szIcon, BOOL bGroupResource)
  1355. {
  1356. if (bGroupResource)
  1357. {
  1358. HINSTANCE hInst = AfxFindResourceHandle(lpszResourceName, RT_GROUP_ICON);
  1359. if (hInst)
  1360. return CreateIconFromResource(hInst, lpszResourceName, szIcon, TRUE);
  1361. }
  1362. HINSTANCE hInst = AfxFindResourceHandle(lpszResourceName, RT_ICON);
  1363. if (hInst)
  1364. return CreateIconFromResource(hInst, lpszResourceName, szIcon, FALSE);
  1365. return FALSE;
  1366. }
  1367. BOOL CXTPImageManagerIconHandle::CreateIconFromResource(HINSTANCE hInst, LPCTSTR lpszResourceName, CSize szIcon, BOOL bGroupResource)
  1368. {
  1369. HRSRC hRsrc = ::FindResource(hInst, lpszResourceName, RT_GROUP_ICON);
  1370. if (hRsrc != NULL && bGroupResource)
  1371. {
  1372. // Load and Lock to get a pointer to a GRPICONDIR
  1373. HGLOBAL hGlobal = LoadResource(hInst, hRsrc);
  1374. if (!hGlobal)
  1375. return FALSE;
  1376. CXTPImageManagerIcon::GRPICONDIR* lpGrpIconDir = (CXTPImageManagerIcon::GRPICONDIR*)LockResource(hGlobal);
  1377. if (!lpGrpIconDir)
  1378. return FALSE;
  1379. for (int i = (int)lpGrpIconDir->idCount - 1; i >= 0; i--)
  1380. {
  1381. if (lpGrpIconDir->idEntries[i].bWidth == szIcon.cx && lpGrpIconDir->idEntries[i].bHeight == szIcon.cy)
  1382. {
  1383. if (CreateIconFromResource(hInst, MAKEINTRESOURCE(lpGrpIconDir->idEntries[i].nID), szIcon, FALSE))
  1384. return TRUE;
  1385. }
  1386. }
  1387. return FALSE;
  1388. }
  1389. hRsrc = ::FindResource(hInst, lpszResourceName, RT_ICON);
  1390. if (hRsrc == NULL)
  1391. return FALSE;
  1392. HGLOBAL hGlobal = LoadResource(hInst, hRsrc);
  1393. if (!hGlobal)
  1394. return FALSE;
  1395. CXTPImageManagerIcon::ICONIMAGE* lpIconImage = (CXTPImageManagerIcon::ICONIMAGE*)LockResource(hGlobal);
  1396. if (lpIconImage == NULL)
  1397. return FALSE;
  1398. DWORD dwResourceSize = SizeofResource(hInst, hRsrc);
  1399. if (lpIconImage->icHeader.biBitCount == 32)
  1400. {
  1401. CDC dcSrc;
  1402. dcSrc.CreateCompatibleDC(0);
  1403. BITMAPINFOHEADER* pBitmapInfo = (BITMAPINFOHEADER*)malloc(sizeof(BITMAPINFOHEADER) + sizeof(COLORREF) * 3);
  1404. if (!pBitmapInfo)
  1405. return FALSE;
  1406. *pBitmapInfo = lpIconImage->icHeader;
  1407. pBitmapInfo->biHeight /= 2;
  1408. pBitmapInfo->biSizeImage = pBitmapInfo->biHeight * pBitmapInfo->biWidth * 4;
  1409. BYTE* pDest = NULL;
  1410. HBITMAP hBitmap = CreateDIBSection(dcSrc, (BITMAPINFO*)pBitmapInfo, DIB_RGB_COLORS, (void**)&pDest, NULL, 0);
  1411. if (pDest == NULL || hBitmap == NULL)
  1412. {
  1413. free(pBitmapInfo);
  1414. return FALSE;
  1415. }
  1416. ASSERT(pBitmapInfo->biSizeImage <= dwResourceSize - sizeof(BITMAPINFOHEADER));
  1417. MEMCPY_S(pDest, &lpIconImage->icColors, pBitmapInfo->biSizeImage);
  1418. *this = hBitmap; // NOTE: it call DeleteObejct in destructor
  1419. free(pBitmapInfo);
  1420. }
  1421. else
  1422. {
  1423. *this = CreateIconFromResourceEx((PBYTE)lpIconImage, dwResourceSize, TRUE,
  1424. 0x00030000, szIcon.cx, szIcon.cy, LR_DEFAULTCOLOR);
  1425. }
  1426. return !IsEmpty();
  1427. }
  1428. LPBYTE CXTPImageManagerIconHandle::PreMultiply()
  1429. {
  1430. if (m_pBits != NULL)
  1431. return m_pBits;
  1432. if (m_hBitmap == 0)
  1433. return NULL;
  1434. LPBYTE pBits = NULL;
  1435. HBITMAP hBitmapAlpha =  CXTPImageManagerIcon::PreMultiplyAlphaBitmap(m_hBitmap, NULL, &pBits);
  1436. if (!hBitmapAlpha || (pBits == NULL))
  1437. return NULL;
  1438. Clear();
  1439. m_hBitmap = hBitmapAlpha;
  1440. m_pBits = pBits;
  1441. m_bClearHandles = TRUE;
  1442. m_szIcon = _GetExtent();
  1443. return m_pBits;
  1444. }
  1445. BOOL CXTPImageManagerIcon::IsAlpha() const
  1446. {
  1447. return m_hIcon.IsAlpha();
  1448. }
  1449. HBITMAP CXTPImageManagerIcon::InvertAlphaBitmap(HBITMAP hBitmap)
  1450. {
  1451. CDC dcSrc;
  1452. dcSrc.CreateCompatibleDC(NULL);
  1453. DWORD* pBits = 0;
  1454. PBITMAPINFO pBitmapInfo = 0;
  1455. HBITMAP hBitmapAlpha = 0;
  1456. TRY
  1457. {
  1458. UINT nSize;
  1459. if (!GetBitmapBits(dcSrc, hBitmap, pBitmapInfo, (LPVOID&)pBits, nSize))
  1460. return 0;
  1461. DWORD* pDest = NULL;
  1462. hBitmapAlpha = CreateDIBSection(dcSrc, pBitmapInfo, DIB_RGB_COLORS, (void**)&pDest, NULL, 0);
  1463. if (pDest == NULL || hBitmapAlpha == NULL)
  1464. AfxThrowMemoryException();
  1465. int cy = pBitmapInfo->bmiHeader.biHeight;
  1466. int cx = pBitmapInfo->bmiHeader.biWidth;
  1467. for (int y = 0; y < cy; y++)
  1468. {
  1469. DWORD* pBitsRow = &pBits[y * cx + cx - 1];
  1470. for (int x = 0; x < cx; x++)
  1471. {
  1472. *pDest++ = *pBitsRow--;
  1473. }
  1474. }
  1475. }
  1476. CATCH (CMemoryException, e)
  1477. {
  1478. TRACE(_T("Failed -- Memory exception thrown."));
  1479. }
  1480. END_CATCH
  1481. FREE(pBits);
  1482. FREE(pBitmapInfo);
  1483. return hBitmapAlpha;
  1484. }
  1485. HBITMAP CXTPImageManagerIcon::PreMultiplyAlphaBitmap(HBITMAP hBitmap, BOOL* pbAlpha, LPBYTE* lpBits)
  1486. {
  1487. if (lpBits) *lpBits = NULL;
  1488. CDC dcSrc;
  1489. dcSrc.CreateCompatibleDC(NULL);
  1490. PBYTE pBitsSrc = 0;
  1491. PBITMAPINFO pBitmapInfo = 0;
  1492. HBITMAP hBitmapAlpha = 0;
  1493. TRY
  1494. {
  1495. UINT nSize;
  1496. if (!GetBitmapBits(dcSrc, hBitmap, pBitmapInfo, (LPVOID&)pBitsSrc, nSize))
  1497. return 0;
  1498. BYTE* pBitsDest = NULL;
  1499. hBitmapAlpha = CreateDIBSection(dcSrc, pBitmapInfo, DIB_RGB_COLORS, (void**)&pBitsDest, NULL, 0);
  1500. if (pBitsDest == NULL || hBitmapAlpha == NULL)
  1501. AfxThrowMemoryException();
  1502. MEMCPY_S(pBitsDest, pBitsSrc, nSize);
  1503. BOOL bAlpha0Found = FALSE;
  1504. BYTE* pBitsI = pBitsDest;
  1505. UINT nCount = nSize / 4;
  1506. for (UINT i = 0; i < nCount; i++)
  1507. {
  1508. int nAlpha = pBitsI[3];
  1509. pBitsI[0] = BYTE(pBitsI[0] * nAlpha / 255);
  1510. pBitsI[1] = BYTE(pBitsI[1] * nAlpha / 255);
  1511. pBitsI[2] = BYTE(pBitsI[2] * nAlpha / 255);
  1512. if (pbAlpha)
  1513. {
  1514. if (nAlpha == 0)
  1515. bAlpha0Found = TRUE;
  1516. if ((nAlpha != 255 && nAlpha != 0) || (nAlpha == 255 && bAlpha0Found) || (nAlpha == 255 && *pbAlpha == -1))
  1517. *pbAlpha = TRUE;
  1518. }
  1519. pBitsI += 4;
  1520. }
  1521. if (pbAlpha && (*pbAlpha == FALSE))
  1522. {
  1523. MEMCPY_S(pBitsDest, pBitsSrc, nSize);
  1524. }
  1525. if (lpBits)
  1526. {
  1527. *lpBits = pBitsDest;
  1528. }
  1529. }
  1530. CATCH (CMemoryException, e)
  1531. {
  1532. TRACE(_T("Failed -- Memory exception thrown."));
  1533. }
  1534. END_CATCH
  1535. FREE(pBitsSrc);
  1536. FREE(pBitmapInfo);
  1537. return hBitmapAlpha;
  1538. }
  1539. BOOL CXTPImageManagerIcon::GetBitmapBits(CDC& dcSrc, HBITMAP hBitmap, PBITMAPINFO& pBitmapInfo, LPVOID& pBits, UINT& nSize)
  1540. {
  1541. if (hBitmap == 0)
  1542. return FALSE;
  1543. BITMAPINFO  bmi;
  1544. memset(&bmi, 0, sizeof(bmi));
  1545. bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
  1546. if (GetDIBits(dcSrc, hBitmap, 0, 0, NULL, (BITMAPINFO*)&bmi, DIB_RGB_COLORS) == 0)
  1547. return FALSE;
  1548. if (bmi.bmiHeader.biBitCount != 32)
  1549. return FALSE;
  1550. nSize = bmi.bmiHeader.biHeight * bmi.bmiHeader.biWidth * 4;
  1551. pBits = (PBYTE)malloc(nSize);
  1552. if (pBits == NULL)
  1553. return FALSE;
  1554. if ((pBitmapInfo = (PBITMAPINFO)malloc(sizeof(BITMAPINFOHEADER) + 3 * sizeof(COLORREF))) == NULL)
  1555. {
  1556. FREE(pBits);
  1557. return FALSE;
  1558. }
  1559. MEMCPY_S(pBitmapInfo, &bmi, sizeof(BITMAPINFOHEADER));
  1560. if (GetDIBits(dcSrc, hBitmap, 0, bmi.bmiHeader.biHeight, pBits, pBitmapInfo, DIB_RGB_COLORS) == NULL)
  1561. {
  1562. FREE(pBits);
  1563. FREE(pBitmapInfo);
  1564. return FALSE;
  1565. }
  1566. return TRUE;
  1567. }
  1568. HBITMAP CXTPImageManagerIcon::CopyAlphaBitmap(HBITMAP hBitmap, LPBYTE* lpBits)
  1569. {
  1570. CDC dcSrc;
  1571. dcSrc.CreateCompatibleDC(NULL);
  1572. PBYTE pBitsSrc = 0;
  1573. PBITMAPINFO pBitmapInfo = 0;
  1574. UINT nSize;
  1575. if (!GetBitmapBits(dcSrc, hBitmap, pBitmapInfo, (LPVOID&)pBitsSrc, nSize))
  1576. return 0;
  1577. BYTE* pBitsDest = NULL;
  1578. HBITMAP hBmp = CreateDIBSection(dcSrc, pBitmapInfo, DIB_RGB_COLORS, (void**)&pBitsDest, NULL, 0);
  1579. if (pBitsDest != NULL && hBmp != NULL)
  1580. {
  1581. MEMCPY_S(pBitsDest, pBitsSrc, nSize);
  1582. }
  1583. FREE(pBitsSrc);
  1584. FREE(pBitmapInfo);
  1585. if (lpBits)
  1586. {
  1587. *lpBits = pBitsDest;
  1588. }
  1589. return hBmp;
  1590. }
  1591. //////////////////////////////////////////////////////////////////////////
  1592. // CXTPImageManagerIcon
  1593. CXTPImageManagerIcon::CXTPImageManagerIcon(UINT nID, int nWidth, int nHeight, CXTPImageManagerIconSet* pIconSet)
  1594. : m_nID(nID)
  1595. , m_nWidth(nWidth)
  1596. , m_nHeight(nHeight)
  1597. , m_pIconSet(pIconSet)
  1598. , m_pImageList(NULL)
  1599. {
  1600. m_bDrawComposited = FALSE;
  1601. if (m_pIconSet)
  1602. {
  1603. m_hIcon.m_pImageManager = m_pIconSet->m_pImageManager;
  1604. m_hFaded.m_pImageManager = m_pIconSet->m_pImageManager;
  1605. m_hShadow.m_pImageManager = m_pIconSet->m_pImageManager;
  1606. m_hHot.m_pImageManager = m_pIconSet->m_pImageManager;
  1607. m_hChecked.m_pImageManager = m_pIconSet->m_pImageManager;
  1608. m_hPressed.m_pImageManager = m_pIconSet->m_pImageManager;
  1609. m_hDisabled.m_pImageManager = m_pIconSet->m_pImageManager;
  1610. m_hDisabledAuto.m_pImageManager = m_pIconSet->m_pImageManager;
  1611. }
  1612. }
  1613. CXTPImageManagerIcon::CXTPImageManagerIcon(UINT nID, int nWidth, int nHeight, CXTPImageManagerImageList* pImageList)
  1614. : m_nID(nID)
  1615. , m_nWidth(nWidth)
  1616. , m_nHeight(nHeight)
  1617. , m_pIconSet(NULL)
  1618. , m_pImageList(pImageList)
  1619. {
  1620. }
  1621. CXTPImageManagerIcon::~CXTPImageManagerIcon()
  1622. {
  1623. Clear(TRUE);
  1624. }
  1625. UINT CXTPImageManagerIcon::GetID() const
  1626. {
  1627. return m_nID;
  1628. }
  1629. int CXTPImageManagerIcon::GetHeight() const
  1630. {
  1631. return m_nHeight;
  1632. }
  1633. int CXTPImageManagerIcon::GetWidth() const
  1634. {
  1635. return m_nWidth;
  1636. }
  1637. void CXTPImageManagerIcon::Clear(BOOL bIcon /* = FALSE */)
  1638. {
  1639. if (bIcon)
  1640. {
  1641. m_hIcon.Clear();
  1642. }
  1643. m_hFaded.Clear();
  1644. m_hShadow.Clear();
  1645. m_hHot.Clear();
  1646. m_hChecked.Clear();
  1647. m_hPressed.Clear();
  1648. m_hDisabled.Clear();
  1649. m_hDisabledAuto.Clear();
  1650. }
  1651. void CXTPImageManagerIcon::Refresh()
  1652. {
  1653. m_hFaded.Clear();
  1654. m_hShadow.Clear();
  1655. m_hDisabledAuto.Clear();
  1656. }
  1657. CXTPImageManagerIconHandle& CXTPImageManagerIcon::GetIcon()
  1658. {
  1659. return m_hIcon;
  1660. }
  1661. CXTPImageManagerIconHandle& CXTPImageManagerIcon::GetIcon(XTPImageState imageState)
  1662. {
  1663. return imageState == xtpImageDisabled ? GetDisabledIcon() : imageState == xtpImageHot? GetHotIcon() :
  1664. imageState == xtpImageChecked? GetCheckedIcon() : imageState == xtpImagePressed? GetPressedIcon() : GetIcon();
  1665. }
  1666. CXTPImageManagerIconHandle& CXTPImageManagerIcon::GetFadedIcon()
  1667. {
  1668. if (m_hFaded.IsEmpty())
  1669. {
  1670. CreateFadedIcon();
  1671. }
  1672. return m_hFaded.IsEmpty() ? m_hIcon : m_hFaded;
  1673. }
  1674. CXTPImageManagerIconHandle& CXTPImageManagerIcon::GetShadowIcon()
  1675. {
  1676. if (m_hShadow.IsEmpty())
  1677. {
  1678. CreateShadowIcon();
  1679. }
  1680. return m_hShadow;
  1681. }
  1682. CXTPImageManagerIconHandle& CXTPImageManagerIcon::GetHotIcon()
  1683. {
  1684. return !m_hHot.IsEmpty() ? m_hHot : m_hIcon;
  1685. }
  1686. CXTPImageManagerIconHandle& CXTPImageManagerIcon::GetCheckedIcon()
  1687. {
  1688. return !m_hChecked.IsEmpty() ? m_hChecked : GetHotIcon();
  1689. }
  1690. CXTPImageManagerIconHandle& CXTPImageManagerIcon::GetPressedIcon()
  1691. {
  1692. return !m_hPressed.IsEmpty() ? m_hPressed : GetHotIcon();
  1693. }
  1694. BOOL CXTPImageManagerIcon::HasDisabledIcon() const
  1695. {
  1696. if (!m_hDisabled.IsEmpty())
  1697. return TRUE;
  1698. if (!m_hDisabledAuto.IsEmpty())
  1699. return TRUE;
  1700. return FALSE;
  1701. }
  1702. CXTPImageManagerIconHandle& CXTPImageManagerIcon::GetDisabledIcon(BOOL bCreateIfNotExists /*= TRUE*/)
  1703. {
  1704. if (!m_hDisabled.IsEmpty())
  1705. return m_hDisabled;
  1706. if (!m_hDisabledAuto.IsEmpty())
  1707. return m_hDisabledAuto;
  1708. if (bCreateIfNotExists)
  1709. {
  1710. CreateDisabledIcon();
  1711. }
  1712. return m_hDisabledAuto;
  1713. }
  1714. BOOL CXTPImageManagerIcon::SetIcon(const CXTPImageManagerIconHandle& iconHandle, XTPImageState imageState)
  1715. {
  1716. switch(imageState)
  1717. {
  1718. case xtpImageNormal:
  1719. SetNormalIcon(iconHandle);
  1720. break;
  1721. case xtpImageHot:
  1722. SetHotIcon(iconHandle);
  1723. break;
  1724. case xtpImageChecked:
  1725. SetCheckedIcon(iconHandle);
  1726. break;
  1727. case xtpImageDisabled:
  1728. SetDisabledIcon(iconHandle);
  1729. break;
  1730. case xtpImagePressed:
  1731. SetPressedIcon(iconHandle);
  1732. break;
  1733. default:
  1734. return FALSE;
  1735. }
  1736. return TRUE;
  1737. }
  1738. BOOL CXTPImageManagerIcon::SetIcon(const CXTPImageManagerIconHandle& hIcon)
  1739. {
  1740. ASSERT(!hIcon.IsEmpty());
  1741. Clear(TRUE);
  1742. m_hIcon.CopyHandle(hIcon);
  1743. CSize sz = GetExtent();
  1744. m_nHeight = sz.cy;
  1745. m_nWidth = sz.cx;
  1746. if (m_pIconSet)
  1747. m_pIconSet->RefreshAll();
  1748. return TRUE;
  1749. }
  1750. BOOL CXTPImageManagerIcon::SetIcon(UINT nIDResourceIcon, int nWidth, int nHeight)
  1751. {
  1752. Clear(TRUE);
  1753. ASSERT(nWidth != 0 && nHeight != 0);
  1754. if (!m_hIcon.CreateIconFromResource(MAKEINTRESOURCE(nIDResourceIcon), CSize(nWidth, nHeight)))
  1755. return FALSE;
  1756. m_nHeight = nHeight;
  1757. m_nWidth = nWidth;
  1758. return TRUE;
  1759. }
  1760. void CXTPImageManagerIcon::SetNormalIcon(const CXTPImageManagerIconHandle& hIcon)
  1761. {
  1762. ASSERT(!hIcon.IsEmpty());
  1763. Refresh();
  1764. m_hIcon.CopyHandle(hIcon);
  1765. #ifdef _DEBUG
  1766. CSize sz = GetExtent();
  1767. ASSERT((int)m_nHeight == sz.cy);
  1768. ASSERT((int)m_nWidth == sz.cx);
  1769. #endif
  1770. }
  1771. void CXTPImageManagerIcon::SetHotIcon(const CXTPImageManagerIconHandle& hIcon)
  1772. {
  1773. Refresh();
  1774. m_hHot.CopyHandle(hIcon);
  1775. }
  1776. void CXTPImageManagerIcon::SetCheckedIcon(const CXTPImageManagerIconHandle& hIcon)
  1777. {
  1778. Refresh();
  1779. m_hChecked.CopyHandle(hIcon);
  1780. }
  1781. void CXTPImageManagerIcon::SetPressedIcon(const CXTPImageManagerIconHandle& hIcon)
  1782. {
  1783. Refresh();
  1784. m_hPressed.CopyHandle(hIcon);
  1785. }
  1786. void CXTPImageManagerIcon::SetDisabledIcon(const CXTPImageManagerIconHandle& hIcon)
  1787. {
  1788. Refresh();
  1789. m_hDisabled.CopyHandle(hIcon);
  1790. }
  1791. COLORREF CXTPImageManagerIcon::LightenColor(COLORREF clr, double factor)
  1792. {
  1793. return RGB(
  1794. factor * 255 + (1.0 - factor) * GetRValue(clr),
  1795. factor * 255 + (1.0 - factor) * GetGValue(clr),
  1796. factor * 255 + (1.0 - factor) * GetBValue(clr)) ;
  1797. }
  1798. void CXTPImageManagerIcon::CreateFadedIcon()
  1799. {
  1800. ASSERT(m_hFaded.IsEmpty());
  1801. if (!m_hIcon.m_bUseResources)
  1802. return;
  1803. CXTPImageManagerIconHandle hFaded;
  1804. hFaded.CopyHandle(m_hIcon);
  1805. if (!hFaded.IsAlpha())
  1806. {
  1807. ICONINFO info;
  1808. if (GetIconInfo(hFaded.GetIcon(), &info))
  1809. {
  1810. if (!CXTPDrawHelpers::IsLowResolution())
  1811. {
  1812. CXTPCompatibleDC dc(NULL, CBitmap::FromHandle(info.hbmColor));
  1813. CXTPCompatibleDC dcMask(NULL, CBitmap::FromHandle(info.hbmMask));
  1814. BITMAP bmp;
  1815. ::GetObject(info.hbmColor, sizeof(BITMAP), &bmp);
  1816. for (int i = 0; i < bmp.bmWidth; i++)
  1817. for (int j = 0; j < bmp.bmHeight; j++)
  1818. {
  1819. COLORREF clr = dc.GetPixel(i, j);
  1820. COLORREF clrMask = dcMask.GetPixel(i, j);
  1821. if (clrMask == 0)
  1822. dc.SetPixel(i, j, LightenColor(clr, .3));
  1823. }
  1824. }
  1825. hFaded = CreateIconIndirect(&info);
  1826. ::DeleteObject(info.hbmColor);
  1827. ::DeleteObject(info.hbmMask);
  1828. }
  1829. }
  1830. else if (hFaded.PreMultiply())
  1831. {
  1832. PBYTE pBits = hFaded.PreMultiply();
  1833. CSize szIcon = hFaded.GetExtent();
  1834. UINT nCount = szIcon.cx * szIcon.cy;
  1835. for (UINT i = 0; i < nCount; i++)
  1836. {
  1837. int nAlpha = pBits[3];
  1838. if (nAlpha != 0)
  1839. {
  1840. pBits[0] = BYTE(.3 * nAlpha + (1.0 - .3) * pBits[0]);
  1841. pBits[1] = BYTE(.3 * nAlpha + (1.0 - .3) * pBits[1]);
  1842. pBits[2] = BYTE(.3 * nAlpha + (1.0 - .3) * pBits[2]);
  1843. }
  1844. pBits += 4;
  1845. }
  1846. }
  1847. m_hFaded.CopyHandle(hFaded);
  1848. }
  1849. void CXTPImageManagerIcon::CreateShadowIcon()
  1850. {
  1851. ASSERT(m_hShadow.IsEmpty());
  1852. if (!m_hIcon.m_bUseResources)
  1853. return;
  1854. COLORREF clrBackground = GetXtremeColor(XPCOLOR_HIGHLIGHT);
  1855. COLORREF clrShadow = RGB(GetRValue(clrBackground) * .75, GetGValue(clrBackground) * .75, GetBValue(clrBackground) * .75);
  1856. CXTPImageManagerIconHandle hShadow;
  1857. hShadow.CopyHandle(GetHotIcon());
  1858. if (!hShadow.IsAlpha())
  1859. {
  1860. ICONINFO info;
  1861. if (GetIconInfo(hShadow.GetIcon(), &info))
  1862. {
  1863. {
  1864. CXTPCompatibleDC dc(NULL, CBitmap::FromHandle(info.hbmColor));
  1865. CXTPCompatibleDC dcMask(NULL, CBitmap::FromHandle(info.hbmMask));
  1866. BITMAP bmp;
  1867. ::GetObject(info.hbmColor, sizeof(BITMAP), &bmp);
  1868. for (int i = 0; i < bmp.bmWidth; i++)
  1869. for (int j = 0; j < bmp.bmHeight; j++)
  1870. {
  1871. COLORREF clrMask = dcMask.GetPixel(i, j);
  1872. if (clrMask == 0)
  1873. dc.SetPixel(i, j, clrShadow);
  1874. }
  1875. }
  1876. hShadow = CreateIconIndirect(&info);
  1877. ::DeleteObject(info.hbmMask);
  1878. ::DeleteObject(info.hbmColor);
  1879. }
  1880. }
  1881. else if (hShadow.PreMultiply())
  1882. {
  1883. PBYTE pBits = hShadow.PreMultiply();
  1884. CSize szIcon = hShadow.GetExtent();
  1885. UINT nCount = szIcon.cx * szIcon.cy;
  1886. for (UINT i = 0; i < nCount; i++)
  1887. {
  1888. int nAlpha = pBits[3];
  1889. pBits[0] = BYTE(GetRValue(clrShadow) * nAlpha / 255);
  1890. pBits[1] = BYTE(GetGValue(clrShadow) * nAlpha / 255);
  1891. pBits[2] = BYTE(GetBValue(clrShadow) * nAlpha / 255);
  1892. pBits += 4;
  1893. }
  1894. }
  1895. m_hShadow.CopyHandle(hShadow);
  1896. }
  1897. void CXTPImageManagerIcon::CreateDisabledIcon(COLORREF clrDisabledLight /*= (COLORREF)-1*/, COLORREF clrDisabledDark /*= (COLORREF)-1*/)
  1898. {
  1899. if (!m_hDisabledAuto.IsEmpty())
  1900. return;
  1901. BOOL bOfficeDisabledIcons = clrDisabledLight != (COLORREF)-1 && clrDisabledDark != (COLORREF)-1;
  1902. CXTPImageManagerIconHandle hDisabled;
  1903. hDisabled.CopyHandle(m_hIcon);
  1904. if (!hDisabled.IsAlpha())
  1905. {
  1906. ICONINFO info;
  1907. if (GetIconInfo(hDisabled.GetIcon(), &info))
  1908. {
  1909. {
  1910. CXTPCompatibleDC dc(NULL, CBitmap::FromHandle(info.hbmColor));
  1911. CXTPCompatibleDC dcMask(NULL, CBitmap::FromHandle(info.hbmMask));
  1912. BITMAP bmp;
  1913. ::GetObject(info.hbmColor, sizeof(BITMAP), &bmp);
  1914. for (int i = 0; i < bmp.bmWidth; i++)
  1915. for (int j = 0; j < bmp.bmHeight; j++)
  1916. {
  1917. COLORREF clrMask = dcMask.GetPixel(i, j);
  1918. COLORREF clr = dc.GetPixel(i, j);
  1919. if (clrMask == 0)
  1920. {
  1921. if (bOfficeDisabledIcons)
  1922. {
  1923. double dGray = (GetRValue(clr) * 0.299 + GetGValue(clr) * 0.587 + GetBValue(clr) * 0.114)/255;
  1924. double dLight = 1.0 - dGray;
  1925. clr = RGB(dLight * GetRValue(clrDisabledDark) + dGray * GetRValue(clrDisabledLight),
  1926. dLight * GetGValue(clrDisabledDark) + dGray * GetGValue(clrDisabledLight),
  1927. dLight * GetBValue(clrDisabledDark) + dGray * GetBValue(clrDisabledLight));
  1928. dc.SetPixel(i, j, clr);
  1929. }
  1930. else
  1931. {
  1932. double dGray = GetRValue(clr) * 0.299 + GetGValue(clr) * 0.587 + GetBValue(clr) * 0.114;
  1933. int nGray = (BYTE)(pow(dGray / 255.0, CXTPImageManager::m_dDisabledBrightnessFactor) * 255.0);
  1934. dc.SetPixel(i, j, RGB(nGray, nGray, nGray));
  1935. }
  1936. }
  1937. }
  1938. }
  1939. hDisabled = CreateIconIndirect(&info);
  1940. ::DeleteObject(info.hbmMask);
  1941. ::DeleteObject(info.hbmColor);
  1942. }
  1943. }
  1944. else if (hDisabled.PreMultiply())
  1945. {
  1946. PBYTE pBits = hDisabled.PreMultiply();
  1947. CSize szIcon = hDisabled.GetExtent();
  1948. UINT nCount = szIcon.cx * szIcon.cy;
  1949. for (UINT i = 0; i < nCount; i++)
  1950. {
  1951. int nAlpha = pBits[3];
  1952. if (nAlpha != 0)
  1953. {
  1954. int R = pBits[0] * 255 / nAlpha;
  1955. int G = pBits[1] * 255 / nAlpha;
  1956. int B = pBits[2] * 255 / nAlpha;
  1957. if (bOfficeDisabledIcons)
  1958. {
  1959. double dGray = (R * 0.114 + G * 0.587 + B * 0.299)/255.0;
  1960. double dLight = 1.0 - dGray;
  1961. R = BYTE(dLight * GetBValue(clrDisabledDark) + dGray * GetBValue(clrDisabledLight));
  1962. G = BYTE(dLight * GetGValue(clrDisabledDark) + dGray * GetGValue(clrDisabledLight));
  1963. B = BYTE(dLight * GetRValue(clrDisabledDark) + dGray * GetRValue(clrDisabledLight));
  1964. }
  1965. else
  1966. {
  1967. double dGray = R * 0.114 + G * 0.587 + B * 0.299;
  1968. R = G = B = (BYTE)(pow(dGray / 255.0, CXTPImageManager::m_dDisabledBrightnessFactor) * 255.0);
  1969. nAlpha = BYTE(nAlpha / CXTPImageManager::m_dDisabledAlphaFactor);
  1970. }
  1971. pBits[0] = BYTE(R * nAlpha / 255);
  1972. pBits[1] = BYTE(G * nAlpha / 255);
  1973. pBits[2] = BYTE(B * nAlpha / 255);
  1974. }
  1975. pBits += 4;
  1976. }
  1977. }
  1978. m_hDisabledAuto.CopyHandle(hDisabled);
  1979. }
  1980. CSize CXTPImageManagerIcon::GetExtent() const
  1981. {
  1982. return m_hIcon.GetExtent();
  1983. }
  1984. CSize CXTPImageManagerIcon::GetExtent(HICON hIcon)
  1985. {
  1986. ASSERT(hIcon);
  1987. CSize extent(0);
  1988. if (hIcon)
  1989. {
  1990. ICONINFO iconinfo;
  1991. if (::GetIconInfo(hIcon, &iconinfo))
  1992. {
  1993. BITMAP bmpinfo;
  1994. if (::GetObject(iconinfo.hbmMask, sizeof(bmpinfo), &bmpinfo))
  1995. {
  1996. extent.cx = (int)bmpinfo.bmWidth;
  1997. extent.cy = (int)bmpinfo.bmHeight;
  1998. if (!iconinfo.hbmColor)
  1999. {
  2000. // b/w icons have double size for XOR and AND masks
  2001. extent.cy /= 2;
  2002. }
  2003. }
  2004. // cleanup GDI
  2005. if (iconinfo.hbmMask) ::DeleteObject(iconinfo.hbmMask);
  2006. if (iconinfo.hbmColor) ::DeleteObject(iconinfo.hbmColor);
  2007. }
  2008. }
  2009. return extent;
  2010. }
  2011. HICON CXTPImageManagerIcon::ScaleToFit(HICON hIcon, CSize szExtent, int nWidth)
  2012. {
  2013. if (nWidth == 0 || szExtent == CSize(0))
  2014. {
  2015. // invalid arg
  2016. return NULL;
  2017. }
  2018. if (nWidth == szExtent.cx)
  2019. return ::CopyIcon(hIcon);
  2020. CSize szDesiredExtent(nWidth, MulDiv(szExtent.cy, nWidth, szExtent.cx));
  2021. // scale the icon
  2022. CImageList images;
  2023. VERIFY(images.Create(szDesiredExtent.cx, szDesiredExtent.cy, ILC_COLOR32 | ILC_MASK, 1, 1));
  2024. images.Add(hIcon);
  2025. return images.ExtractIcon(0);
  2026. }
  2027. BOOL CXTPImageManagerIcon::GetDIBBitmap(HBITMAP hBitmap, PBYTE& pBits, UINT& nBitsSize, PBITMAPINFO& pBitmapInfo, UINT& nBitmapInfoSize)
  2028. {
  2029. pBits = 0;
  2030. pBitmapInfo = 0;
  2031. BITMAPINFO  bmi;
  2032. memset(&bmi, 0, sizeof(bmi));
  2033. bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
  2034. CDC dcSrc;
  2035. dcSrc.CreateCompatibleDC(NULL);
  2036. TRY
  2037. {
  2038. if (GetDIBits(dcSrc, hBitmap, 0, 0, NULL, (BITMAPINFO*)&bmi, DIB_RGB_COLORS) == 0)
  2039. AfxThrowMemoryException();
  2040. nBitsSize = bmi.bmiHeader.biSizeImage != 0? bmi.bmiHeader.biSizeImage :
  2041. bmi.bmiHeader.biHeight * bmi.bmiHeader.biWidth * 4;
  2042. pBits = (PBYTE)malloc(nBitsSize);
  2043. if (pBits == NULL)
  2044. AfxThrowMemoryException();
  2045. int nColorTableSize = bmi.bmiHeader.biBitCount == 4 ? 16 : bmi.bmiHeader.biBitCount == 8 ? 256 : 3;
  2046. nBitmapInfoSize = sizeof(BITMAPINFOHEADER) + nColorTableSize * sizeof(COLORREF);
  2047. if ((pBitmapInfo = (PBITMAPINFO)malloc(nBitmapInfoSize)) == NULL)
  2048. AfxThrowMemoryException();
  2049. MEMCPY_S(pBitmapInfo, &bmi, sizeof(BITMAPINFOHEADER));
  2050. if (GetDIBits(dcSrc, hBitmap, 0, bmi.bmiHeader.biHeight, pBits, pBitmapInfo, DIB_RGB_COLORS) == NULL)
  2051. AfxThrowMemoryException();
  2052. }
  2053. CATCH (CMemoryException, e)
  2054. {
  2055. TRACE(_T("Failed -- Memory exception thrown."));
  2056. return FALSE;
  2057. }
  2058. END_CATCH
  2059. return TRUE;
  2060. }
  2061. HBITMAP CXTPImageManagerIcon::ReadDIBBitmap(CArchive& ar, LPBYTE* lpBits)
  2062. {
  2063. PBITMAPINFO pBitmapInfo = 0;
  2064. PBYTE pBitsSrc = 0;
  2065. DWORD dwCount = (DWORD) ar.ReadCount();
  2066. DWORD dwBitsCount = 0;
  2067. if (dwCount > 0)
  2068. {
  2069. pBitmapInfo = (PBITMAPINFO)malloc(dwCount);
  2070. ar.Read(pBitmapInfo, dwCount);
  2071. dwBitsCount = (DWORD) ar.ReadCount();
  2072. pBitsSrc = (PBYTE)malloc(dwBitsCount);
  2073. ar.Read(pBitsSrc, dwBitsCount);
  2074. }
  2075. else
  2076. {
  2077. return NULL;
  2078. }
  2079. if (!pBitmapInfo || dwBitsCount == 0)
  2080. {
  2081. FREE(pBitsSrc);
  2082. FREE(pBitmapInfo);
  2083. return NULL;
  2084. }
  2085. CDC dcSrc;
  2086. dcSrc.CreateCompatibleDC(NULL);
  2087. if (pBitmapInfo->bmiHeader.biSizeImage == 0)
  2088. {
  2089. pBitmapInfo->bmiHeader.biSizeImage = dwBitsCount;
  2090. }
  2091. BYTE* pBitsDest = NULL;
  2092. HBITMAP hBmp = CreateDIBSection(dcSrc, pBitmapInfo, DIB_RGB_COLORS, (void**)&pBitsDest, NULL, 0);
  2093. if (!pBitsDest || !hBmp)
  2094. {
  2095. FREE(pBitsSrc);
  2096. FREE(pBitmapInfo);
  2097. return NULL;
  2098. }
  2099. MEMCPY_S(pBitsDest, pBitsSrc, min(dwBitsCount, pBitmapInfo->bmiHeader.biSizeImage));
  2100. FREE(pBitsSrc);
  2101. FREE(pBitmapInfo);
  2102. if (lpBits)
  2103. {
  2104. *lpBits = pBitsDest;
  2105. }
  2106. return hBmp;
  2107. }
  2108. void CXTPImageManagerIcon::WriteDIBBitmap(CArchive& ar, HBITMAP hBitmap)
  2109. {
  2110. PBYTE pBits = 0;
  2111. PBITMAPINFO pBitmapInfo = 0;
  2112. UINT nBitsSize;
  2113. UINT nBitmapInfoSize;
  2114. if (GetDIBBitmap(hBitmap, pBits, nBitsSize, pBitmapInfo, nBitmapInfoSize))
  2115. {
  2116. ar.WriteCount(nBitmapInfoSize);
  2117. ar.Write(pBitmapInfo, nBitmapInfoSize);
  2118. ar.WriteCount(nBitsSize);
  2119. ar.Write(pBits, nBitsSize);
  2120. }
  2121. else
  2122. {
  2123. ar.WriteCount(0);
  2124. }
  2125. FREE(pBits);
  2126. FREE(pBitmapInfo);
  2127. }
  2128. void CXTPImageManagerIcon::SerializeIcon(CXTPImageManagerIconHandle& hIcon, CArchive& ar, long nSchema)
  2129. {
  2130. if (ar.IsStoring())
  2131. {
  2132. CXTPImageManagerIconHandle hHandle;
  2133. hHandle.CopyHandle(hIcon);
  2134. hHandle.PreMultiply();
  2135. ICONINFO info;
  2136. if (!hHandle.IsEmpty())
  2137. {
  2138. if (hHandle.IsAlpha())
  2139. {
  2140. WriteDIBBitmap(ar, hHandle.GetBitmap());
  2141. ar.WriteCount(0);
  2142. }
  2143. else if (GetIconInfo(hHandle.GetIcon(), &info))
  2144. {
  2145. WriteDIBBitmap(ar, info.hbmColor);
  2146. WriteDIBBitmap(ar, info.hbmMask);
  2147. ::DeleteObject(info.hbmColor);
  2148. ::DeleteObject(info.hbmMask);
  2149. }
  2150. else
  2151. {
  2152. ar.WriteCount(0);
  2153. ar.WriteCount(0);
  2154. }
  2155. }
  2156. else
  2157. {
  2158. ar.WriteCount(0);
  2159. ar.WriteCount(0);
  2160. }
  2161. }
  2162. else
  2163. {
  2164. CXTPImageManagerIconHandle hHandle;
  2165. LPBYTE lpBits = NULL;
  2166. HBITMAP hbmColor = ReadDIBBitmap(ar, &lpBits);
  2167. HBITMAP hbmMask = ReadDIBBitmap(ar, NULL);
  2168. if (hbmColor)
  2169. {
  2170. if (hbmMask == 0)
  2171. {
  2172. hHandle = hbmColor;
  2173. if (nSchema > _XTP_SCHEMA_112)
  2174. {
  2175. hHandle.m_pBits = lpBits;
  2176. }
  2177. hbmColor = 0;
  2178. }
  2179. else
  2180. {
  2181. BITMAP bmp;
  2182. ::GetObject(hbmColor, sizeof(BITMAP), &bmp);
  2183. CImageList il;
  2184. il.Create(bmp.bmWidth, bmp.bmHeight, ILC_COLOR24 | ILC_MASK, 0, 1);
  2185. il.Add(CBitmap::FromHandle(hbmColor), hbmMask == 0 ? (CBitmap*)NULL : CBitmap::FromHandle(hbmMask));
  2186. hHandle = il.ExtractIcon(0);
  2187. }
  2188. if (hbmColor) ::DeleteObject(hbmColor);
  2189. if (hbmMask) ::DeleteObject(hbmMask);
  2190. }
  2191. hIcon.CopyHandle(hHandle);
  2192. }
  2193. }
  2194. void CXTPImageManagerIcon::Serialize(CArchive& ar)
  2195. {
  2196. long nSchema = _XTP_SCHEMA_CURRENT;
  2197. if (ar.IsStoring())
  2198. {
  2199. ar << m_nHeight;
  2200. ar << nSchema;
  2201. }
  2202. else
  2203. {
  2204. ar >> m_nHeight;
  2205. ar >> nSchema;
  2206. }
  2207. SerializeIcon(m_hIcon, ar, nSchema);
  2208. SerializeIcon(m_hDisabled, ar, nSchema);
  2209. SerializeIcon(m_hHot, ar, nSchema);
  2210. if (nSchema > _XTP_SCHEMA_875)
  2211. {
  2212. SerializeIcon(m_hChecked, ar, nSchema);
  2213. }
  2214. if (nSchema > _XTP_SCHEMA_98)
  2215. {
  2216. SerializeIcon(m_hPressed, ar, nSchema);
  2217. }
  2218. }
  2219. void CXTPImageManagerIcon::Copy(CXTPImageManagerIcon* pIcon)
  2220. {
  2221. ASSERT(m_nID == pIcon->GetID());
  2222. m_nWidth = pIcon->m_nWidth;
  2223. m_nHeight = pIcon->m_nHeight;
  2224. m_hIcon.CopyHandle(pIcon->m_hIcon);
  2225. m_hDisabled.CopyHandle(pIcon->m_hDisabled);
  2226. m_hHot.CopyHandle(pIcon->m_hHot);
  2227. m_hChecked.CopyHandle(pIcon->m_hChecked);
  2228. m_hPressed.CopyHandle(pIcon->m_hPressed);
  2229. m_hFaded.Clear();
  2230. m_hShadow.Clear();
  2231. m_hDisabledAuto.Clear();
  2232. }
  2233. void CXTPImageManagerIcon::DrawAlphaBitmap(CDC* pDC, HBITMAP hBitmap, CPoint ptDest, CSize szDest, CPoint ptSrc, CSize szSrc)
  2234. {
  2235. if (szSrc == CSize(0))
  2236. szSrc = szDest;
  2237. CXTPCompatibleDC dc(NULL, CBitmap::FromHandle(hBitmap));
  2238. XTPImageManager()->AlphaBlend(pDC->GetSafeHdc(), CRect(ptDest, szDest),
  2239. dc, CRect(ptSrc, szSrc));
  2240. }
  2241. CXTPImageManager* CXTPImageManagerIcon::GetImageManager() const
  2242. {
  2243. if (m_pIconSet)
  2244. {
  2245. ASSERT(m_pIconSet->m_pImageManager);
  2246. return m_pIconSet->m_pImageManager;
  2247. }
  2248. return XTPImageManager();
  2249. }
  2250. void CXTPImageManagerIcon::DrawMono(CDC* pDC, CPoint pt, CXTPImageManagerIconHandle& hIcon, CSize szIcon, COLORREF clrBrush)
  2251. {
  2252. if (hIcon.IsAlpha())
  2253. return;
  2254. if (szIcon.cx == 0)
  2255. szIcon.cx = m_nWidth;
  2256. if (szIcon.cy == 0)
  2257. szIcon.cy = m_nHeight * szIcon.cx / m_nWidth;
  2258. CBitmap bmp;
  2259. bmp.CreateCompatibleBitmap(pDC, szIcon.cx, szIcon.cy);
  2260. {
  2261. CXTPCompatibleDC dc(pDC, &bmp);
  2262. dc.FillSolidRect(0, 0, szIcon.cx, szIcon.cy, 0xFFFFFF);
  2263. Draw(&dc, CPoint(0, 0), hIcon, szIcon);
  2264. }
  2265. pDC->DrawState(pt, szIcon, bmp, (UINT)DSS_MONO, CBrush(clrBrush));
  2266. }
  2267. void CXTPImageManagerIcon::Draw(CDC* pDC, CPoint pt, CSize szIcon)
  2268. {
  2269. Draw(pDC, pt, GetIcon(), szIcon);
  2270. }
  2271. void CXTPImageManagerIcon::Draw(CDC* pDC, CPoint pt)
  2272. {
  2273. Draw(pDC, pt, GetIcon());
  2274. }
  2275. void CXTPImageManagerIcon::DrawIconComposited(CDC* pDC, CPoint pt, CSize szIcon, HICON hIcon)
  2276. {
  2277. CRect rcDest;
  2278. if (szIcon.cx < 0)
  2279. {
  2280. rcDest.SetRect(pt.x + szIcon.cx, pt.y, pt.x, pt.y + szIcon.cy);
  2281. }
  2282. else
  2283. {
  2284. rcDest.SetRect(pt.x, pt.y, pt.x + szIcon.cx, pt.y + szIcon.cy);
  2285. }
  2286. CSize sz(rcDest.Width(), rcDest.Height());
  2287. CBitmap bmp;
  2288. LPDWORD lpBits;
  2289. bmp.Attach(CXTPImageManager::Create32BPPDIBSection(pDC->GetSafeHdc(), sz.cx, sz.cy, (LPBYTE*)&lpBits));
  2290. CXTPCompatibleDC dc(pDC, &bmp);
  2291. CRect rcDestOrig(0, 0, sz.cx, sz.cy);
  2292. dc.FillSolidRect(rcDestOrig, 0xFF00FF);
  2293. DrawIconEx(dc, szIcon.cx > 0 ? 0 : -szIcon.cx, 0, hIcon, szIcon.cx, szIcon.cy, 0, 0, DI_NORMAL);
  2294. for (int i = 0; i < sz.cx * sz.cy; i++)
  2295. {
  2296. if (lpBits[0] == 0xFF00FF)
  2297. {
  2298. lpBits[0] = 0;
  2299. }
  2300. else
  2301. {
  2302. lpBits[0] |= 0xFF000000;
  2303. }
  2304. lpBits++;
  2305. }
  2306. XTPImageManager()->AlphaBlend(*pDC, rcDest, dc, rcDestOrig);
  2307. }
  2308. void CXTPImageManagerIcon::Draw(CDC* pDC, CPoint pt, CXTPImageManagerIconHandle& hIcon, CSize szIcon /*= 0*/)
  2309. {
  2310. if (szIcon.cx == 0)
  2311. szIcon.cx = m_nWidth;
  2312. if (szIcon.cy == 0)
  2313. szIcon.cy = m_nHeight * szIcon.cx / m_nWidth;
  2314. if (m_pImageList)
  2315. {
  2316. m_pImageList->Draw(pDC, pt, this, szIcon);
  2317. return;
  2318. }
  2319. hIcon.Draw(pDC, pt, szIcon, m_bDrawComposited);
  2320. }
  2321. //////////////////////////////////////////////////////////////////////////
  2322. // CXTPImageManagerIconSet
  2323. CXTPImageManagerIconSet::CXTPImageManagerIconSet(UINT nID, CXTPImageManager* pImageManager)
  2324. : m_nID(nID)
  2325. {
  2326. ASSERT(pImageManager);
  2327. m_pImageManager = pImageManager;
  2328. }
  2329. CXTPImageManagerIconSet::~CXTPImageManagerIconSet()
  2330. {
  2331. RemoveAll();
  2332. }
  2333. void CXTPImageManagerIconSet::RemoveAll()
  2334. {
  2335. UINT nWidth;
  2336. CXTPImageManagerIcon* pIcon;
  2337. POSITION pos = m_mapIcons.GetStartPosition();
  2338. while (pos)
  2339. {
  2340. m_mapIcons.GetNextAssoc(pos, nWidth, pIcon);
  2341. pIcon->Clear(TRUE);
  2342. pIcon->InternalRelease();
  2343. }
  2344. m_mapIcons.RemoveAll();
  2345. }
  2346. CXTPImageManagerIcon* CXTPImageManagerIconSet::CreateIcon(UINT nWidth)
  2347. {
  2348. CXTPImageManagerIcon* pIcon = 0;
  2349. if (m_mapIcons.Lookup(nWidth, pIcon))
  2350. {
  2351. ASSERT(pIcon->m_nID == m_nID);
  2352. ASSERT(pIcon->m_nWidth == nWidth);
  2353. }
  2354. else
  2355. {
  2356. pIcon = new CXTPImageManagerIcon(m_nID, nWidth, 15, this);
  2357. m_mapIcons.SetAt(nWidth, pIcon);
  2358. }
  2359. ASSERT(pIcon);
  2360. return pIcon;
  2361. }
  2362. void CXTPImageManagerIconSet::SetIcon(const CXTPImageManagerIconHandle& hIcon, UINT nWidth)
  2363. {
  2364. CXTPImageManagerIcon* pIcon = CreateIcon(nWidth);
  2365. pIcon->SetIcon(hIcon);
  2366. }
  2367. void CXTPImageManagerIconSet::SetDisabledIcon(const CXTPImageManagerIconHandle& hIcon, UINT nWidth)
  2368. {
  2369. CXTPImageManagerIcon* pIcon = CreateIcon(nWidth);
  2370. pIcon->SetDisabledIcon(hIcon);
  2371. }
  2372. void CXTPImageManagerIconSet::SetHotIcon(const CXTPImageManagerIconHandle& hIcon, UINT nWidth)
  2373. {
  2374. CXTPImageManagerIcon* pIcon = CreateIcon(nWidth);
  2375. pIcon->SetHotIcon(hIcon);
  2376. }
  2377. void CXTPImageManagerIconSet::SetCheckedIcon(const CXTPImageManagerIconHandle& hIcon, UINT nWidth)
  2378. {
  2379. CXTPImageManagerIcon* pIcon = CreateIcon(nWidth);
  2380. pIcon->SetCheckedIcon(hIcon);
  2381. }
  2382. void CXTPImageManagerIconSet::SetPressedIcon(const CXTPImageManagerIconHandle& hIcon, UINT nWidth)
  2383. {
  2384. CXTPImageManagerIcon* pIcon = CreateIcon(nWidth);
  2385. pIcon->SetPressedIcon(hIcon);
  2386. }
  2387. CXTPImageManagerIcon* CXTPImageManagerIconSet::GetIcon(UINT nWidth, BOOL bScaled)
  2388. {
  2389. ASSERT(m_mapIcons.GetCount() > 0);
  2390. CXTPImageManagerIcon* pIcon = NULL;
  2391. BOOL bSpecial = (nWidth == ICON_BIG) || (nWidth == ICON_SMALL);
  2392. if (!bSpecial)
  2393. {
  2394. if (m_mapIcons.Lookup(nWidth, pIcon))
  2395. {
  2396. return pIcon;
  2397. }
  2398. if (!bScaled)
  2399. return NULL;
  2400. }
  2401. UINT nDelta = 0;
  2402. POSITION pos = m_mapIcons.GetStartPosition();
  2403. while (pos)
  2404. {
  2405. UINT nWidthScale;
  2406. CXTPImageManagerIcon* pIconScale;
  2407. m_mapIcons.GetNextAssoc(pos, nWidthScale, pIconScale);
  2408. if (bSpecial)
  2409. {
  2410. if (((nDelta == 0) || ((nWidth == ICON_SMALL && nWidthScale < nDelta)
  2411. || (nWidth == ICON_BIG && nWidthScale > nDelta))))
  2412. {
  2413. pIcon = pIconScale;
  2414. nDelta = nWidthScale;
  2415. }
  2416. }
  2417. else if (nDelta == 0 || (UINT)abs(int(nWidthScale - nWidth)) < nDelta)
  2418. {
  2419. pIcon = pIconScale;
  2420. nDelta = (UINT)abs(int(nWidthScale - nWidth));
  2421. }
  2422. }
  2423. ASSERT(pIcon != 0);
  2424. if (!pIcon)
  2425. return NULL;
  2426. return pIcon;
  2427. }
  2428. void CXTPImageManagerIconSet::RefreshAll()
  2429. {
  2430. POSITION pos = m_mapIcons.GetStartPosition();
  2431. UINT nWidth;
  2432. CXTPImageManagerIcon* pIcon;
  2433. while (pos)
  2434. {
  2435. m_mapIcons.GetNextAssoc(pos, nWidth, pIcon);
  2436. pIcon->Refresh();
  2437. }
  2438. }
  2439. //////////////////////////////////////////////////////////////////////////
  2440. // CXTPImageManager
  2441. CXTPImageManager::CXTPImageManager()
  2442. {
  2443. m_clrMask = (COLORREF)-1;
  2444. m_nCustomID = 0x10AAA;
  2445. m_mapImages.InitHashTable(XTP_IMAGEMAN_HASH_TABLE_SIZE, FALSE);
  2446. m_bDrawReverted = 2;
  2447. m_bUseResources = TRUE;
  2448. }
  2449. CXTPImageManager* AFX_CDECL XTPImageManager()
  2450. {
  2451. static CXTPImageManager s_managerInstance;
  2452. return &s_managerInstance;
  2453. }
  2454. CXTPImageManager::~CXTPImageManager()
  2455. {
  2456. RemoveAll();
  2457. }
  2458. BOOL CXTPImageManager::LoadToolbar(UINT nIDResourceToolBar, UINT*& pItems, int& nCount, CSize& szIcon) const
  2459. {
  2460. LPCTSTR lpszResourceName = MAKEINTRESOURCE(nIDResourceToolBar);
  2461. struct CToolBarData
  2462. {
  2463. WORD wVersion;
  2464. WORD wWidth;
  2465. WORD wHeight;
  2466. WORD wItemCount;
  2467. WORD* items()
  2468. {
  2469. return (WORD*)(this + 1);
  2470. }
  2471. };
  2472. ASSERT(lpszResourceName != NULL);
  2473. if (!lpszResourceName)
  2474. return FALSE;
  2475. // determine location of the bitmap in resource fork
  2476. HINSTANCE hInst = AfxFindResourceHandle(lpszResourceName, RT_TOOLBAR);
  2477. HRSRC hRsrc = ::FindResource(hInst, lpszResourceName, RT_TOOLBAR);
  2478. if (hRsrc == NULL)
  2479. return FALSE;
  2480. HGLOBAL hGlobal = LoadResource(hInst, hRsrc);
  2481. if (hGlobal == NULL)
  2482. return FALSE;
  2483. CToolBarData* pData = (CToolBarData*)LockResource(hGlobal);
  2484. if (pData == NULL)
  2485. return FALSE;
  2486. ASSERT(pData->wVersion == 1);
  2487. pItems = new UINT[pData->wItemCount];
  2488. nCount = 0;
  2489. for (int i = 0; i < pData->wItemCount; i++)
  2490. if (pData->items()[i]) pItems[nCount++] = pData->items()[i];
  2491. szIcon = CSize(pData->wWidth, pData->wHeight);
  2492. UnlockResource(hGlobal);
  2493. FreeResource(hGlobal);
  2494. return TRUE;
  2495. }
  2496. BOOL CXTPImageManager::SetIcons(UINT nIDResourceToolBar, CBitmap& bmpIcons, XTPImageState imageState)
  2497. {
  2498. UINT* pItems = NULL;
  2499. CSize szIcon(0);
  2500. int nCount = 0;
  2501. BOOL bResult = LoadToolbar(nIDResourceToolBar, pItems, nCount, szIcon);
  2502. if (bResult && !SetIcons(bmpIcons, pItems, nCount, szIcon, imageState))
  2503. bResult = FALSE;
  2504. if (pItems)
  2505. {
  2506. delete[] pItems;
  2507. }
  2508. return bResult;
  2509. }
  2510. BOOL CXTPImageManager::SetIcons(UINT nIDResourceToolBar, UINT nIDResourceBitmap, XTPImageState imageState)
  2511. {
  2512. UINT* pItems = NULL;
  2513. CSize szIcon(0);
  2514. int nCount = 0;
  2515. BOOL bResult = LoadToolbar(nIDResourceToolBar, pItems, nCount, szIcon);
  2516. if (bResult && !SetIcons(nIDResourceBitmap, pItems, nCount, CSize(0, 0), imageState))
  2517. bResult = FALSE;
  2518. if (pItems)
  2519. {
  2520. delete[] pItems;
  2521. }
  2522. return bResult;
  2523. }
  2524. BOOL CXTPImageManager::SetIcons(UINT nIDResourceToolBar, XTPImageState imageState)
  2525. {
  2526. return SetIcons(nIDResourceToolBar, nIDResourceToolBar, imageState);
  2527. }
  2528. BOOL CXTPImageManager::SetIcons(UINT nIDResourceToolBar, CImageList& imlIcons, XTPImageState imageState)
  2529. {
  2530. UINT* pItems = NULL;
  2531. CSize szIcon(0);
  2532. int nCount = 0;
  2533. BOOL bResult = LoadToolbar(nIDResourceToolBar, pItems, nCount, szIcon);
  2534. if (bResult && !SetIcons(imlIcons, pItems, nCount, szIcon, imageState))
  2535. bResult = FALSE;
  2536. if (pItems)
  2537. {
  2538. delete[] pItems;
  2539. }
  2540. return bResult;
  2541. }
  2542. BOOL CXTPImageManager::SetIcon(const CXTPImageManagerIconHandle& hIcon, UINT nIDCommand, CSize szIcon, XTPImageState imageState)
  2543. {
  2544. if (hIcon.IsEmpty())
  2545. return FALSE;
  2546. if (szIcon == CSize(0))
  2547. {
  2548. szIcon = hIcon.GetExtent();
  2549. }
  2550. if (szIcon == CSize(0))
  2551. return FALSE;
  2552. CXTPImageManagerIconSet* pIconSet;
  2553. if (m_mapImages.Lookup(nIDCommand, pIconSet))
  2554. {
  2555. if (imageState == xtpImageNormal) pIconSet->SetIcon(hIcon, szIcon.cx);
  2556. if (imageState == xtpImageDisabled) pIconSet->SetDisabledIcon(hIcon, szIcon.cx);
  2557. if (imageState == xtpImageHot) pIconSet->SetHotIcon(hIcon, szIcon.cx);
  2558. if (imageState == xtpImageChecked) pIconSet->SetCheckedIcon(hIcon, szIcon.cx);
  2559. if (imageState == xtpImagePressed) pIconSet->SetPressedIcon(hIcon, szIcon.cx);
  2560. }
  2561. else if (imageState == xtpImageNormal)
  2562. {
  2563. pIconSet = new CXTPImageManagerIconSet(nIDCommand, this);
  2564. pIconSet->SetIcon(hIcon, szIcon.cx);
  2565. m_mapImages.SetAt(nIDCommand, pIconSet);
  2566. }
  2567. else return FALSE;
  2568. return TRUE;
  2569. }
  2570. BOOL CXTPImageManager::SetIcon(UINT nIDResourceIcon, UINT nIDCommand, CSize szIcon, XTPImageState imageState)
  2571. {
  2572. return SetIcon(MAKEINTRESOURCE(nIDResourceIcon), nIDCommand, szIcon, imageState);
  2573. }
  2574. BOOL CXTPImageManager::SetIcon(LPCTSTR lpszResourceName, UINT nIDCommand, CSize szIcon, XTPImageState imageState)
  2575. {
  2576. // determine location of the bitmap in resource fork
  2577. HINSTANCE hInst = AfxFindResourceHandle(lpszResourceName, RT_GROUP_ICON);
  2578. HRSRC hRsrc = ::FindResource(hInst, lpszResourceName, RT_GROUP_ICON);
  2579. if (hRsrc != NULL)
  2580. {
  2581. // Load and Lock to get a pointer to a GRPICONDIR
  2582. HGLOBAL hGlobal = LoadResource(hInst, hRsrc);
  2583. if (!hGlobal)
  2584. return FALSE;
  2585. CXTPImageManagerIcon::GRPICONDIR* lpGrpIconDir = (CXTPImageManagerIcon::GRPICONDIR*)
  2586. LockResource(hGlobal);
  2587. if (!lpGrpIconDir)
  2588. return FALSE;
  2589. for (WORD i = 0; i < lpGrpIconDir->idCount; i++)
  2590. {
  2591. CXTPImageManagerIconHandle hIcon;
  2592. CSize szResourceIcon(lpGrpIconDir->idEntries[i].bWidth, lpGrpIconDir->idEntries[i].bHeight);
  2593. if ((szIcon == szResourceIcon) || (szIcon == CSize(0, 0)))
  2594. {
  2595. if (!hIcon.CreateIconFromResource(hInst, MAKEINTRESOURCE(lpGrpIconDir->idEntries[i].nID),
  2596. szResourceIcon, FALSE))
  2597. {
  2598. return FALSE;
  2599. }
  2600. if (!SetIcon(hIcon, nIDCommand, szResourceIcon, imageState))
  2601. {
  2602. return FALSE;
  2603. }
  2604. }
  2605. }
  2606. }
  2607. else
  2608. {
  2609. CXTPImageManagerIconHandle hIcon;
  2610. if (!hIcon.CreateIconFromResource(lpszResourceName, szIcon, FALSE))
  2611. {
  2612. return FALSE;
  2613. }
  2614. return SetIcon(hIcon, nIDCommand, szIcon, imageState);
  2615. }
  2616. return TRUE;
  2617. }
  2618. BOOL CXTPImageManager::SetIcons(CImageList& imlIcons, UINT* pCommands, int nCount, CSize szIcon, XTPImageState imageState)
  2619. {
  2620. if (!imlIcons.GetSafeHandle())
  2621. return FALSE;
  2622. if ((nCount == 0) && (pCommands == 0))
  2623. {
  2624. nCount = imlIcons.GetImageCount();
  2625. }
  2626. if (szIcon == CSize(0) && nCount > 0)
  2627. {
  2628. IMAGEINFO imageInfo;
  2629. imlIcons.GetImageInfo(0, &imageInfo);
  2630. szIcon = CRect(imageInfo.rcImage).Size();
  2631. }
  2632. BOOL bIncludeAll = imlIcons.GetImageCount() == nCount;
  2633. int j = 0;
  2634. for (int i = 0; i < nCount; i++)
  2635. {
  2636. if ((pCommands == NULL) || bIncludeAll || (pCommands[i] != 0))
  2637. {
  2638. HICON hIcon = imlIcons.ExtractIcon(j);
  2639. if (hIcon)
  2640. {
  2641. SetIcon(hIcon, pCommands ? pCommands[i]: i, szIcon, imageState);
  2642. DestroyIcon(hIcon);
  2643. }
  2644. else
  2645. {
  2646. return FALSE;
  2647. }
  2648. j++;
  2649. }
  2650. }
  2651. return TRUE;
  2652. }
  2653. BOOL CXTPImageManager::SplitBitmap(HBITMAP hbmSource, int nCount, HBITMAP* pDest) const
  2654. {
  2655. ASSERT(pDest != NULL);
  2656. ASSERT(sizeof(int) == 4);
  2657. if (!pDest)
  2658. return FALSE;
  2659. BITMAPINFO  bmi;
  2660. memset(&bmi, 0, sizeof(bmi));
  2661. bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
  2662. CDC dcSrc;
  2663. dcSrc.CreateCompatibleDC(NULL);
  2664. PINT pBits = 0;
  2665. PBITMAPINFO pBitmapInfo = 0;
  2666. BOOL bResult = TRUE;
  2667. int i;
  2668. TRY
  2669. {
  2670. if (GetDIBits(dcSrc, hbmSource, 0, 0, NULL, (BITMAPINFO*)&bmi, DIB_RGB_COLORS) == 0)
  2671. AfxThrowMemoryException();
  2672. UINT nSize = bmi.bmiHeader.biHeight * bmi.bmiHeader.biWidth * 4;
  2673. pBits = (PINT)malloc(nSize);
  2674. if (pBits == NULL)
  2675. AfxThrowMemoryException();
  2676. if ((pBitmapInfo = (PBITMAPINFO)malloc(sizeof(BITMAPINFOHEADER) + 3 * sizeof(COLORREF))) == NULL)
  2677. AfxThrowMemoryException();
  2678. MEMCPY_S(pBitmapInfo, &bmi, sizeof(BITMAPINFOHEADER));
  2679. if (GetDIBits(dcSrc, hbmSource, 0, bmi.bmiHeader.biHeight, pBits, pBitmapInfo, DIB_RGB_COLORS) == NULL)
  2680. AfxThrowMemoryException();
  2681. ASSERT(pBitmapInfo->bmiHeader.biWidth % nCount == 0);
  2682. pBitmapInfo->bmiHeader.biWidth /= nCount;
  2683. pBitmapInfo->bmiHeader.biSizeImage /= nCount;
  2684. PINT* pDestBits = new PINT[nCount];
  2685. for (i = 0; i < nCount; i++)
  2686. {
  2687. pDest[i] = CreateDIBSection(dcSrc, pBitmapInfo, DIB_RGB_COLORS, (void**)&pDestBits[i], NULL, 0);
  2688. if (!pDest[i])
  2689. {
  2690. for (int j = 0; j < i; j++)
  2691. DeleteObject(pDest[j]);
  2692. delete[] pDestBits;
  2693. AfxThrowMemoryException();
  2694. }
  2695. }
  2696. PINT pBitsIter = pBits;
  2697. for (int y = 0; y < pBitmapInfo->bmiHeader.biHeight; y++)
  2698. {
  2699. for (i = 0; i < nCount; i++)
  2700. {
  2701. for (int x = 0; x < pBitmapInfo->bmiHeader.biWidth; x++)
  2702. {
  2703. *pDestBits[i]++ = *pBitsIter++;
  2704. }
  2705. }
  2706. }
  2707. delete[] pDestBits;
  2708. }
  2709. CATCH (CMemoryException, e)
  2710. {
  2711. TRACE(_T("Failed -- Memory exception thrown."));
  2712. bResult = FALSE;
  2713. }
  2714. END_CATCH
  2715. FREE(pBits);
  2716. FREE(pBitmapInfo);
  2717. return bResult;
  2718. }
  2719. COLORREF CXTPImageManager::GetBitmapMaskColor(CBitmap& bmpIcons, CPoint pt)
  2720. {
  2721. CXTPCompatibleDC dc(NULL, &bmpIcons);
  2722. return dc.GetPixel(pt);
  2723. }
  2724. COLORREF CXTPImageManager::GetBitmapMaskColor(UINT nIDBitmap, CPoint pt)
  2725. {
  2726. CBitmap bmp;
  2727. VERIFY(bmp.LoadBitmap(nIDBitmap));
  2728. return GetBitmapMaskColor(bmp, pt);
  2729. }
  2730. HBITMAP CXTPImageManager::ResampleAlphaLayer(UINT nIDBitmap, COLORREF clrMask)
  2731. {
  2732. HBITMAP hbmAlpha = CXTPImageManagerIcon::LoadAlphaBitmap(nIDBitmap);
  2733. if (!hbmAlpha)
  2734. return 0;
  2735. CBitmap bmp;
  2736. bmp.Attach(hbmAlpha);
  2737. return CXTPImageManager::ResampleAlphaLayer(bmp, clrMask);
  2738. }
  2739. HBITMAP CXTPImageManager::ResampleAlphaLayer(HBITMAP bmpAlpha, COLORREF clrMask)
  2740. {
  2741. CDC dcSrc;
  2742. dcSrc.CreateCompatibleDC(NULL);
  2743. PBYTE pBits = 0;
  2744. PBITMAPINFO pBitmapInfo = 0;
  2745. UINT nSize;
  2746. if (!CXTPImageManagerIcon::GetBitmapBits(dcSrc, bmpAlpha, pBitmapInfo, (LPVOID&)pBits, nSize))
  2747. return 0;
  2748. PBYTE pTarget = NULL;
  2749. PBYTE pSource = pBits;
  2750. pBitmapInfo->bmiHeader.biBitCount = 24;
  2751. pBitmapInfo->bmiHeader.biSizeImage = 0;
  2752. pBitmapInfo->bmiHeader.biCompression = BI_RGB;
  2753. HBITMAP hBitmapResult = CreateDIBSection(dcSrc, pBitmapInfo, DIB_RGB_COLORS, (void**)&pTarget, NULL, 0);
  2754. if (pTarget && pSource && hBitmapResult)
  2755. {
  2756. BYTE byMaskRed = GetRValue(clrMask);
  2757. BYTE byMaskGreen = GetGValue(clrMask);
  2758. BYTE byMaskBlue = GetBValue(clrMask);
  2759. int nCount = pBitmapInfo->bmiHeader.biHeight * pBitmapInfo->bmiHeader.biWidth;
  2760. for (; nCount--;)
  2761. {
  2762. int iAlpha = pSource[3];
  2763. if (iAlpha < 120)
  2764. {
  2765. pTarget[0] = byMaskRed;
  2766. pTarget[1] = byMaskGreen;
  2767. pTarget[2] = byMaskBlue;
  2768. }
  2769. else
  2770. {
  2771. pTarget[0] = (BYTE)((pSource[0] * (255 - iAlpha) + pSource[0] * iAlpha) >> 8);
  2772. pTarget[1] = (BYTE)((pSource[1] * (255 - iAlpha) + pSource[1] * iAlpha) >> 8);
  2773. pTarget[2] = (BYTE)((pSource[2] * (255 - iAlpha) + pSource[2] * iAlpha) >> 8);
  2774. }
  2775. pTarget += 3;
  2776. pSource += 4;
  2777. }
  2778. }
  2779. FREE(pBits);
  2780. FREE(pBitmapInfo);
  2781. return hBitmapResult;
  2782. }
  2783. BOOL CXTPImageManager::SetIcons(CBitmap& bmpIcons, UINT* pCommands, int nCount, CSize szIcon, XTPImageState imageState, BOOL bAlpha)
  2784. {
  2785. if (szIcon == CSize(0) && nCount > 0)
  2786. {
  2787. BITMAP bmpInfo;
  2788. bmpIcons.GetBitmap(&bmpInfo);
  2789. szIcon = CSize(bmpInfo.bmWidth / nCount, bmpInfo.bmHeight);
  2790. }
  2791. if (nCount == 0 && szIcon.cx > 0)
  2792. {
  2793. BITMAP bmpInfo;
  2794. bmpIcons.GetBitmap(&bmpInfo);
  2795. nCount = bmpInfo.bmWidth / szIcon.cx;
  2796. }
  2797. if (szIcon.cx == 0)
  2798. return FALSE;
  2799. if (bAlpha && !IsAlphaIconsSupported() && m_bAutoResample)
  2800. {
  2801. HBITMAP hBitmap = ResampleAlphaLayer(bmpIcons, m_clrMask == COLORREF(-1) ? RGB(0, 0xFF, 0) : m_clrMask);
  2802. if (!hBitmap)
  2803. return FALSE;
  2804. CBitmap bmpResample;
  2805. bmpResample.Attach(hBitmap);
  2806. return SetIcons(bmpResample, pCommands, nCount, szIcon, imageState, FALSE);
  2807. }
  2808. if (bAlpha)
  2809. {
  2810. BITMAP bmpInfo;
  2811. bmpIcons.GetBitmap(&bmpInfo);
  2812. if (bmpInfo.bmWidth % szIcon.cx != 0)
  2813. return FALSE;
  2814. int nIconCount = bmpInfo.bmWidth / szIcon.cx;
  2815. HBITMAP* pDestBitmap = new HBITMAP[nIconCount];
  2816. if (!SplitBitmap(bmpIcons, nIconCount, pDestBitmap))
  2817. {
  2818. delete[] pDestBitmap;
  2819. return FALSE;
  2820. }
  2821. BOOL bIgnoreNulls = (nIconCount == nCount);
  2822. int j = 0;
  2823. for (int i = 0; i < nCount; i++)
  2824. {
  2825. if ((!pCommands || bIgnoreNulls || pCommands[i]) && j < nIconCount)
  2826. {
  2827. SetIcon(pDestBitmap[j], pCommands ? pCommands[i]: i, szIcon, imageState);
  2828. j++;
  2829. }
  2830. }
  2831. for (j = 0; j < nIconCount; j++)
  2832. {
  2833. DeleteObject(pDestBitmap[j]);
  2834. }
  2835. delete[] pDestBitmap;
  2836. return TRUE;
  2837. }
  2838. else
  2839. {
  2840. CImageList imgList;
  2841. if (!imgList.Create(szIcon.cx, szIcon.cy, ILC_COLOR24 | ILC_MASK, 0, 1))
  2842. return FALSE;
  2843. COLORREF clrMask = m_clrMask != (COLORREF)-1 ? m_clrMask : GetBitmapMaskColor(bmpIcons);
  2844. imgList.Add(&bmpIcons, clrMask);
  2845. return SetIcons(imgList, pCommands, nCount, szIcon, imageState);
  2846. }
  2847. }
  2848. BOOL CXTPImageManager::SetIcons(UINT nIDResourceBitmap, UINT* pCommands, int nCount, CSize szIcon, XTPImageState imageState)
  2849. {
  2850. return SetIcons(MAKEINTRESOURCE(nIDResourceBitmap), pCommands, nCount, szIcon, imageState);
  2851. }
  2852. BOOL CXTPImageManager::SetIcons(LPCTSTR lpszResourceBitmap, UINT* pCommands, int nCount, CSize szIcon, XTPImageState imageState)
  2853. {
  2854. BOOL bAlphaBitmap = FALSE;
  2855. CBitmap bmpIcons;
  2856. HBITMAP hBmp = CXTPImageManagerIcon::LoadBitmapFromResource(lpszResourceBitmap, &bAlphaBitmap);
  2857. if (!hBmp)
  2858. return FALSE;
  2859. bmpIcons.Attach(hBmp);
  2860. return SetIcons(bmpIcons, pCommands, nCount, szIcon, imageState, bAlphaBitmap);
  2861. }
  2862. BOOL CXTPImageManager::SetImageList(HIMAGELIST hImageList, int nBaseCommand, BOOL bDestoryImageList)
  2863. {
  2864. if (!hImageList)
  2865. return FALSE;
  2866. CXTPImageManagerImageList* pImageList = new CXTPImageManagerImageList;
  2867. pImageList->m_bDestroyImageList = bDestoryImageList;
  2868. pImageList->m_hImageList = hImageList;
  2869. pImageList->m_nBaseCommand = nBaseCommand;
  2870. pImageList->m_pImageManager = this;
  2871. m_arrImageList.Add(pImageList);
  2872. return TRUE;
  2873. }
  2874. BOOL CXTPImageManager::SetImageList(UINT nBitmap, int cx, int nBaseCommand, COLORREF clrMask)
  2875. {
  2876. BOOL bAlpha = FALSE;
  2877. HBITMAP hBitmap = CXTPImageManagerIcon::LoadBitmapFromResource(MAKEINTRESOURCE(nBitmap), &bAlpha);
  2878. if (!hBitmap)
  2879. return FALSE;
  2880. BITMAP bmpInfo;
  2881. if (!::GetObject(hBitmap, sizeof(BITMAP), &bmpInfo))
  2882. return FALSE;
  2883. if (cx == 0) cx = bmpInfo.bmWidth;
  2884. if (((bmpInfo.bmWidth % cx) != 0))
  2885. return FALSE;
  2886. HIMAGELIST hImageList = ImageList_Create(cx, bmpInfo.bmHeight, (bAlpha ? ILC_COLOR32 : ILC_COLOR24) |
  2887. (clrMask == COLORREF_NULL ? 0 : ILC_MASK), 0, 1);
  2888. if (!hImageList)
  2889. return FALSE;
  2890. if (bAlpha || (clrMask == COLORREF_NULL))
  2891. {
  2892. ImageList_Add(hImageList, hBitmap, NULL);
  2893. }
  2894. else
  2895. {
  2896. ImageList_AddMasked(hImageList, hBitmap, clrMask);
  2897. }
  2898. DeleteObject(hBitmap);
  2899. return SetImageList(hImageList, nBaseCommand, TRUE);
  2900. }
  2901. BOOL CXTPImageManager::IsPngBitmapResource(UINT nIDResourceBitmap)
  2902. {
  2903. return CXTPImageManagerIcon::IsPngBitmapResource(AfxFindResourceHandle(MAKEINTRESOURCE(nIDResourceBitmap), _T("PNG")),
  2904. MAKEINTRESOURCE(nIDResourceBitmap));
  2905. }
  2906. BOOL CXTPImageManager::IsAlphaBitmapResource(UINT nIDResourceBitmap)
  2907. {
  2908. return CXTPImageManagerIcon::IsAlphaBitmapResource(AfxFindResourceHandle(MAKEINTRESOURCE(nIDResourceBitmap), RT_BITMAP),
  2909. MAKEINTRESOURCE(nIDResourceBitmap));
  2910. }
  2911. UINT CXTPImageManager::AddCustomIcon(const CXTPImageManagerIconHandle& hIcon)
  2912. {
  2913. CSize szIcon = hIcon.GetExtent();
  2914. m_nCustomID++;
  2915. CXTPImageManagerIconSet* pIconSet = new CXTPImageManagerIconSet(m_nCustomID, this);
  2916. pIconSet->SetIcon(hIcon, szIcon.cx);
  2917. m_mapImages.SetAt(m_nCustomID, pIconSet);
  2918. return m_nCustomID;
  2919. }
  2920. void CXTPImageManager::CopyImage(UINT nCommand)
  2921. {
  2922. CMemFile memFile;
  2923. CArchive ar (&memFile, CArchive::store);
  2924. Serialize(nCommand, ar);
  2925. ar.Flush();
  2926. DWORD dwCount = (DWORD)memFile.GetPosition();
  2927. BYTE* pControls = memFile.Detach();
  2928. HGLOBAL hGlobal = GlobalAlloc(GMEM_MOVEABLE, dwCount);
  2929. if (hGlobal != NULL)
  2930. {
  2931. LPVOID lpData = GlobalLock(hGlobal);
  2932. MEMCPY_S(lpData, pControls, dwCount);
  2933. GlobalUnlock(hGlobal);
  2934. SetClipboardData(m_nImageClipFormat, hGlobal);
  2935. }
  2936. ar.Close();
  2937. memFile.Close();
  2938. free(pControls);
  2939. }
  2940. UINT CXTPImageManager::PasteCustomImage(COleDataObject& data)
  2941. {
  2942. #ifdef __AFXOLE_H__
  2943. HGLOBAL hGlobal = data.GetGlobalData (m_nImageClipFormat);
  2944. if (hGlobal == NULL) return 0;
  2945. try
  2946. {
  2947. CSharedFile globFile;
  2948. globFile.SetHandle(hGlobal, FALSE);
  2949. CArchive ar (&globFile, CArchive::load);
  2950. m_nCustomID++;
  2951. Serialize(m_nCustomID, ar);
  2952. ar.Close();
  2953. }
  2954. catch (COleException* pEx)
  2955. {
  2956. pEx->Delete ();
  2957. return 0;
  2958. }
  2959. catch (CArchiveException* pEx)
  2960. {
  2961. pEx->Delete ();
  2962. return 0;
  2963. }
  2964. return m_nCustomID;
  2965. #else
  2966. return 0;
  2967. #endif
  2968. }
  2969. BOOL CXTPImageManager::IsPrimaryImageExists(UINT nCommand, int nWidth) const
  2970. {
  2971. CXTPImageManagerIconSet* pIconSet = GetIconSet(nCommand);
  2972. if (pIconSet)
  2973. {
  2974. CXTPImageManagerIcon* pIcon = pIconSet->GetIcon(nWidth, FALSE);
  2975. if (pIcon)
  2976. return TRUE;
  2977. }
  2978. CXTPImageManagerImageList* pImageList = GetImageList(nCommand);
  2979. if (pImageList)
  2980. {
  2981. return nWidth == 0 || pImageList->GetIconSize().cx == nWidth;
  2982. }
  2983. return FALSE;
  2984. }
  2985. CXTPImageManagerIcon* CXTPImageManager::GetImage(UINT nCommand, int nWidth) const
  2986. {
  2987. CXTPImageManagerIconSet* pIconSet = GetIconSet(nCommand);
  2988. if (pIconSet)
  2989. {
  2990. return pIconSet->GetIcon(nWidth);
  2991. }
  2992. CXTPImageManagerImageList* pImageList = GetImageList(nCommand);
  2993. if (pImageList)
  2994. {
  2995. return pImageList->GetIcon(nCommand);
  2996. }
  2997. return NULL;
  2998. }
  2999. BOOL CXTPImageManager::Lookup(UINT nCommand) const
  3000. {
  3001. return (GetIconSet(nCommand) != NULL) || (GetImageList(nCommand) != NULL);
  3002. }
  3003. CXTPImageManagerIconSet* CXTPImageManager::GetIconSet(UINT nCommand) const
  3004. {
  3005. CXTPImageManagerIconSet* pIconSet;
  3006. if (m_mapImages.Lookup(nCommand, pIconSet))
  3007. {
  3008. return pIconSet;
  3009. }
  3010. return NULL;
  3011. }
  3012. CXTPImageManagerImageList* CXTPImageManager::GetImageList(UINT nCommand) const
  3013. {
  3014. for (int i = 0; i < (int)m_arrImageList.GetSize(); i++)
  3015. {
  3016. CXTPImageManagerImageList* pImageList = m_arrImageList[i];
  3017. if (pImageList->Lookup(nCommand))
  3018. return pImageList;
  3019. }
  3020. return NULL;
  3021. }
  3022. void CXTPImageManager::RemoveIcon(UINT nIDCommand)
  3023. {
  3024. CXTPImageManagerIconSet* pIconSet;
  3025. if (m_mapImages.Lookup(nIDCommand, pIconSet))
  3026. {
  3027. m_mapImages.RemoveKey(nIDCommand);
  3028. pIconSet->RemoveAll();
  3029. pIconSet->InternalRelease();
  3030. }
  3031. }
  3032. void CXTPImageManager::RemoveAll()
  3033. {
  3034. POSITION pos = m_mapImages.GetStartPosition();
  3035. UINT nID;
  3036. CXTPImageManagerIconSet* pIconSet;
  3037. while (pos)
  3038. {
  3039. m_mapImages.GetNextAssoc(pos, nID, pIconSet);
  3040. pIconSet->RemoveAll();
  3041. pIconSet->InternalRelease();
  3042. }
  3043. m_mapImages.RemoveAll();
  3044. pos = m_mapResources.GetStartPosition();
  3045. DWORD dwSize;
  3046. CXTPImageManagerResource* pResource;
  3047. while (pos)
  3048. {
  3049. m_mapResources.GetNextAssoc(pos, dwSize, pResource);
  3050. delete pResource;
  3051. }
  3052. m_mapResources.RemoveAll();
  3053. for (int i = 0; i < (int)m_arrImageList.GetSize(); i++)
  3054. {
  3055. delete m_arrImageList[i];
  3056. }
  3057. m_arrImageList.RemoveAll();
  3058. }
  3059. void CXTPImageManager::RefreshAll()
  3060. {
  3061. POSITION pos = m_mapImages.GetStartPosition();
  3062. UINT nID;
  3063. CXTPImageManagerIconSet* pIconSet;
  3064. while (pos)
  3065. {
  3066. m_mapImages.GetNextAssoc(pos, nID, pIconSet);
  3067. pIconSet->RefreshAll();
  3068. }
  3069. for (int i = 0; i < (int)m_arrImageList.GetSize(); i++)
  3070. {
  3071. m_arrImageList[i]->RemoveAll();
  3072. }
  3073. }
  3074. COLORREF CXTPImageManager::SetMaskColor(COLORREF clrMask)
  3075. {
  3076. COLORREF clrReturn = m_clrMask;
  3077. m_clrMask = clrMask;
  3078. return clrReturn;
  3079. }
  3080. COLORREF CXTPImageManager::GetMaskColor() const
  3081. {
  3082. return m_clrMask;
  3083. }
  3084. BOOL CXTPImageManager::IsAlphaIconsSupported() const
  3085. {
  3086. return TRUE;
  3087. }
  3088. BOOL CXTPImageManager::IsAlphaIconsImageListSupported()
  3089. {
  3090. DWORD dwComCtlVersion = XTPSystemVersion()->GetComCtlVersion();
  3091. return HIWORD(dwComCtlVersion) > 5;
  3092. }
  3093. void CXTPImageManager::DoPropExchange(UINT nCommand, CXTPPropExchange* pPX)
  3094. {
  3095. if (nCommand > m_nCustomID) m_nCustomID = nCommand;
  3096. const LPCTSTR lpszCheck = _T("CXTPImageManagerIcons");
  3097. CString strCheck = lpszCheck;
  3098. if (pPX->IsStoring())
  3099. {
  3100. PX_String(pPX, _T("CheckSum"), strCheck, lpszCheck);
  3101. ASSERT(nCommand > 0);
  3102. CXTPImageManagerIconSet* pIconSet = GetIconSet(nCommand);
  3103. ASSERT(pIconSet);
  3104. if (!pIconSet)
  3105. {
  3106. CXTPPropExchangeEnumeratorPtr pEnumerator(pPX->GetEnumerator(_T("Icon")));
  3107. pEnumerator->GetPosition(0);
  3108. return;
  3109. }
  3110. UINT nWidth;
  3111. CXTPImageManagerIcon* pIcon;
  3112. DWORD dwCount =(DWORD)pIconSet->m_mapIcons.GetCount();
  3113. CXTPPropExchangeEnumeratorPtr pEnumerator(pPX->GetEnumerator(_T("Icon")));
  3114. POSITION posEnum = pEnumerator->GetPosition(dwCount);
  3115. POSITION pos = pIconSet->m_mapIcons.GetStartPosition();
  3116. while (pos)
  3117. {
  3118. pIconSet->m_mapIcons.GetNextAssoc(pos, nWidth, pIcon);
  3119. CXTPPropExchangeSection secIcon(pEnumerator->GetNext(posEnum));
  3120. PX_Long(&secIcon, _T("Width"), (long&)nWidth);
  3121. PX_Serialize(&secIcon, _T("Data"), pIcon);
  3122. }
  3123. }
  3124. else
  3125. {
  3126. PX_String(pPX, _T("CheckSum"), strCheck, lpszCheck);
  3127. if (strCheck != lpszCheck)
  3128. AfxThrowArchiveException(CArchiveException::badClass);
  3129. CXTPImageManagerIconSet* pIconSet;
  3130. if (m_mapImages.Lookup(nCommand, pIconSet))
  3131. {
  3132. pIconSet->RemoveAll();
  3133. }
  3134. else
  3135. {
  3136. pIconSet = new CXTPImageManagerIconSet(nCommand, this);
  3137. m_mapImages.SetAt(nCommand, pIconSet);
  3138. }
  3139. CXTPPropExchangeEnumeratorPtr pEnumerator(pPX->GetEnumerator(_T("Icon")));
  3140. POSITION posEnum = pEnumerator->GetPosition();
  3141. while (posEnum)
  3142. {
  3143. CXTPPropExchangeSection secIcon(pEnumerator->GetNext(posEnum));
  3144. UINT nWidth = 16;
  3145. PX_Long(&secIcon, _T("Width"), (long&)nWidth);
  3146. CXTPImageManagerIcon* pIcon = new CXTPImageManagerIcon(nCommand, nWidth, 15, pIconSet);
  3147. PX_Serialize(&secIcon, _T("Data"), pIcon);
  3148. pIconSet->m_mapIcons.SetAt(nWidth, pIcon);
  3149. }
  3150. }
  3151. }
  3152. void CXTPImageManager::Serialize(UINT nCommand, CArchive& ar)
  3153. {
  3154. CXTPPropExchangeArchive px(ar);
  3155. DoPropExchange(nCommand, &px);
  3156. }
  3157. void CXTPImageManager::DoPropExchange(CXTPPropExchange* pPX)
  3158. {
  3159. CMap<UINT, UINT, CXTPImageManagerIconSet*, CXTPImageManagerIconSet*>* pIcons = GetImages();
  3160. CXTPPropExchangeEnumeratorPtr pEnumerator(pPX->GetEnumerator(_T("IconSet")));
  3161. POSITION posEnum = pEnumerator->GetPosition((DWORD)pIcons->GetCount());
  3162. if (pPX->IsStoring())
  3163. {
  3164. UINT nIDCommand;
  3165. CXTPImageManagerIconSet* pIconSet;
  3166. POSITION pos = pIcons->GetStartPosition();
  3167. while (pos)
  3168. {
  3169. pIcons->GetNextAssoc(pos, nIDCommand, pIconSet);
  3170. CXTPPropExchangeSection secIconSet(pEnumerator->GetNext(posEnum));
  3171. PX_Long(&secIconSet, _T("Id"), (long&)nIDCommand);
  3172. DoPropExchange(nIDCommand, &secIconSet);
  3173. }
  3174. }
  3175. else
  3176. {
  3177. RemoveAll();
  3178. while (posEnum)
  3179. {
  3180. CXTPPropExchangeSection secIconSet(pEnumerator->GetNext(posEnum));
  3181. UINT nIDCommand = 0;
  3182. PX_Long(&secIconSet, _T("Id"), (long&)nIDCommand);
  3183. DoPropExchange(nIDCommand, &secIconSet);
  3184. }
  3185. }
  3186. }
  3187. void CXTPImageManager::Serialize(CArchive& ar)
  3188. {
  3189. CXTPPropExchangeArchive px(ar);
  3190. DoPropExchange(&px);
  3191. }
  3192. void CXTPImageManager::AddIcons(CXTPImageManager* pImageManager)
  3193. {
  3194. if (pImageManager == 0)
  3195. return;
  3196. POSITION pos = pImageManager->m_mapImages.GetStartPosition();
  3197. UINT nID;
  3198. CXTPImageManagerIconSet* pIconSet;
  3199. while (pos)
  3200. {
  3201. pImageManager->m_mapImages.GetNextAssoc(pos, nID, pIconSet);
  3202. AddIcons(pIconSet);
  3203. }
  3204. }
  3205. void CXTPImageManager::AddIcons(CXTPImageManagerIconSet* pIconSetAdd)
  3206. {
  3207. int nId = pIconSetAdd->GetID();
  3208. CXTPImageManagerIconSet* pIconSet = NULL;
  3209. if (!m_mapImages.Lookup(nId, pIconSet))
  3210. {
  3211. pIconSet = new CXTPImageManagerIconSet(nId, this);
  3212. m_mapImages.SetAt(nId, pIconSet);
  3213. }
  3214. POSITION pos = pIconSetAdd->m_mapIcons.GetStartPosition();
  3215. UINT nWidth;
  3216. CXTPImageManagerIcon* pIconAdd;
  3217. while (pos)
  3218. {
  3219. pIconSetAdd->m_mapIcons.GetNextAssoc(pos, nWidth, pIconAdd);
  3220. CXTPImageManagerIcon* pIcon = NULL;
  3221. if (!pIconSet->m_mapIcons.Lookup(nWidth, pIcon))
  3222. {
  3223. pIcon  = new CXTPImageManagerIcon(nId, nWidth, pIconAdd->GetHeight());
  3224. pIconSet->m_mapIcons.SetAt(nWidth, pIcon);
  3225. }
  3226. pIcon->Copy(pIconAdd);
  3227. }
  3228. }
  3229. BOOL CXTPImageManager::DoDisableBitmap(HBITMAP hBmp, COLORREF clrDisabledLight, COLORREF clrDisabledDark,
  3230.    int nBlackAndWhiteContrast)
  3231. {
  3232. ASSERT(nBlackAndWhiteContrast == -1 ||
  3233.    (nBlackAndWhiteContrast >= 0 && nBlackAndWhiteContrast <= 255));
  3234. BOOL bOfficeDisabledIcons = clrDisabledLight != (COLORREF)-1 && clrDisabledDark != (COLORREF)-1;
  3235. BITMAP bmBitmap;
  3236. // Get information about the surfaces you were passed.
  3237. if (!GetObject(hBmp,  sizeof(BITMAP), &bmBitmap))  return FALSE;
  3238. // Make sure you have data that meets your requirements.
  3239. if (bmBitmap.bmBitsPixel != 32)
  3240. return FALSE;
  3241. if (bmBitmap.bmPlanes != 1)
  3242. return FALSE;
  3243. if (!bmBitmap.bmBits)
  3244. return FALSE;
  3245. DWORD dwWidthBytes = bmBitmap.bmWidthBytes;
  3246. // Initialize the surface pointers.
  3247. RGBQUAD *lprgbBitmap = (RGBQUAD*)bmBitmap.bmBits;
  3248. //************************************************
  3249. int x, y;
  3250. for (y = 0; y < bmBitmap.bmHeight; y++)
  3251. {
  3252. for (x = 0; x < bmBitmap.bmWidth; x++)
  3253. {
  3254. if (bOfficeDisabledIcons)
  3255. {
  3256. double dGray = (lprgbBitmap[x].rgbBlue * 0.114 + lprgbBitmap[x].rgbGreen * 0.587 + lprgbBitmap[x].rgbRed * 0.299)/255.0;
  3257. double dLight = 1.0 - dGray;
  3258. lprgbBitmap[x].rgbBlue  = BYTE(dLight * GetBValue(clrDisabledDark) + dGray * GetBValue(clrDisabledLight));
  3259. lprgbBitmap[x].rgbGreen = BYTE(dLight * GetGValue(clrDisabledDark) + dGray * GetGValue(clrDisabledLight));
  3260. lprgbBitmap[x].rgbRed   = BYTE(dLight * GetRValue(clrDisabledDark) + dGray * GetRValue(clrDisabledLight));
  3261. }
  3262. else if (nBlackAndWhiteContrast != -1)
  3263. {
  3264. int nGray = (lprgbBitmap[x].rgbBlue * 114 + lprgbBitmap[x].rgbGreen * 587 + lprgbBitmap[x].rgbRed * 299) / 1000;
  3265. nGray = nGray + (255 - nGray) * nBlackAndWhiteContrast / 255;
  3266. nGray = min(nGray, 255);
  3267. lprgbBitmap[x].rgbBlue = BYTE(nGray);
  3268. lprgbBitmap[x].rgbGreen = BYTE(nGray);
  3269. lprgbBitmap[x].rgbRed = BYTE(nGray);
  3270. lprgbBitmap[x].rgbReserved = BYTE(lprgbBitmap[x].rgbReserved / CXTPImageManager::m_dDisabledAlphaFactor);
  3271. }
  3272. else
  3273. {
  3274. double dGray = (lprgbBitmap[x].rgbBlue * 0.114 + lprgbBitmap[x].rgbGreen * 0.587 + lprgbBitmap[x].rgbRed * 0.299)/255.0;
  3275. lprgbBitmap[x].rgbBlue = (BYTE)(pow(dGray, CXTPImageManager::m_dDisabledBrightnessFactor) * 255.0);
  3276. lprgbBitmap[x].rgbGreen = lprgbBitmap[x].rgbBlue;
  3277. lprgbBitmap[x].rgbRed = lprgbBitmap[x].rgbBlue;
  3278. lprgbBitmap[x].rgbReserved = BYTE(lprgbBitmap[x].rgbReserved / CXTPImageManager::m_dDisabledAlphaFactor);
  3279. }
  3280. }
  3281. // Move to next scan line.
  3282. lprgbBitmap = (RGBQUAD *)((LPBYTE)lprgbBitmap + dwWidthBytes);
  3283. }
  3284. return TRUE;
  3285. }
  3286. BOOL CXTPImageManager::DisableBitmap(HDC hDC, const CRect& rcRect, COLORREF clrDisabledLight, COLORREF clrDisabledDark)
  3287. {
  3288. HDC      hdcDst  = NULL;
  3289. HBITMAP  hbmDst  = NULL;
  3290. HBITMAP  hbmpOld = NULL;
  3291. BOOL    bReturn = FALSE;
  3292. // Create surfaces for new image.
  3293. hbmDst  = CXTPImageManager::Create32BPPDIBSection(hDC, rcRect.Width(), rcRect.Height());
  3294. if (!hbmDst) goto HANDLEERROR;
  3295. // Create HDCs to hold our surfaces.
  3296. hdcDst  = CreateCompatibleDC(hDC);
  3297. if (!hdcDst) goto HANDLEERROR;
  3298. // Prepare the surfaces for drawing.
  3299. hbmpOld = (HBITMAP)SelectObject(hdcDst,  hbmDst);
  3300. // Capture a copy of the source area.
  3301. if (!BitBlt(hdcDst, 0, 0, rcRect.Width(), rcRect.Height(),
  3302.  hDC, rcRect.left, rcRect.top, SRCCOPY) )
  3303. goto HANDLEERROR;
  3304. // Modify sourcepixels to create the destination image.
  3305. bReturn = DoDisableBitmap(hbmDst, clrDisabledLight, clrDisabledDark);
  3306. // Display the disabled image to the target HDC.
  3307. if (bReturn)
  3308. {
  3309. BitBlt(hDC, rcRect.left, rcRect.top, rcRect.Width(), rcRect.Height(),
  3310. hdcDst, 0,0, SRCCOPY);
  3311. }
  3312. HANDLEERROR:
  3313. // Clean up the rest of the objects you created.
  3314. if (hbmpOld) SelectObject(hdcDst, hbmpOld);
  3315. if (hdcDst) DeleteDC(hdcDst);
  3316. if (hbmDst) DeleteObject(hbmDst);
  3317. return bReturn;
  3318. }
  3319. BOOL CXTPImageManager::BlackWhiteBitmap(HDC hDC, const CRect& rcRect, int nBlackAndWhiteContrast)
  3320. {
  3321. HDC      hdcDst  = NULL;
  3322. HBITMAP  hbmDst  = NULL;
  3323. HBITMAP  hbmpOld = NULL;
  3324. BOOL    bReturn = FALSE;
  3325. // Create surfaces for new image.
  3326. hbmDst  = CXTPImageManager::Create32BPPDIBSection(hDC, rcRect.Width(), rcRect.Height());
  3327. if (!hbmDst) goto HANDLEERROR;
  3328. // Create HDCs to hold our surfaces.
  3329. hdcDst  = CreateCompatibleDC(hDC);
  3330. if (!hdcDst) goto HANDLEERROR;
  3331. // Prepare the surfaces for drawing.
  3332. hbmpOld = (HBITMAP)SelectObject(hdcDst,  hbmDst);
  3333. // Capture a copy of the source area.
  3334. if (!BitBlt(hdcDst, 0, 0, rcRect.Width(), rcRect.Height(),
  3335.  hDC, rcRect.left, rcRect.top, SRCCOPY) )
  3336. goto HANDLEERROR;
  3337. // Modify sourcepixels to create the destination image.
  3338. bReturn = DoDisableBitmap(hbmDst, (COLORREF)-1, (COLORREF)-1, nBlackAndWhiteContrast);
  3339. // Display the disabled image to the target HDC.
  3340. if (bReturn)
  3341. {
  3342. BitBlt(hDC, rcRect.left, rcRect.top, rcRect.Width(), rcRect.Height(),
  3343. hdcDst, 0,0, SRCCOPY);
  3344. }
  3345. HANDLEERROR:
  3346. // Clean up the rest of the objects you created.
  3347. if (hbmpOld) SelectObject(hdcDst, hbmpOld);
  3348. if (hdcDst) DeleteDC(hdcDst);
  3349. if (hbmDst) DeleteObject(hbmDst);
  3350. return bReturn;
  3351. }