Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

802 lines
26 KiB

  1. /////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (c) 1996-2002 Microsoft Corporation
  4. //
  5. // Module Name:
  6. // Bitmap.cpp
  7. //
  8. // Abstract:
  9. // Implementation of the CMyBitmap class.
  10. //
  11. // Author:
  12. // David Potter (davidp) June 12, 1996
  13. //
  14. // Revision History:
  15. //
  16. /////////////////////////////////////////////////////////////////////////////
  17. #include "stdafx.h"
  18. #include "Bitmap.h"
  19. #include "TraceTag.h"
  20. #include "ExcOper.h"
  21. #ifdef _DEBUG
  22. #define new DEBUG_NEW
  23. #undef THIS_FILE
  24. static char BASED_CODE THIS_FILE[] = __FILE__;
  25. #endif
  26. /////////////////////////////////////////////////////////////////////////////
  27. // Global Variables
  28. /////////////////////////////////////////////////////////////////////////////
  29. #ifdef _DEBUG
  30. CTraceTag g_tagBitmap(_T("Bitmap"), _T("Bitmap"));
  31. CTraceTag g_tagLoadBitmapResource(_T("Bitmap"), _T("LoadBitmapResource"));
  32. #endif
  33. /////////////////////////////////////////////////////////////////////////////
  34. // CMyBitmap
  35. /////////////////////////////////////////////////////////////////////////////
  36. // Array used for restoring the System Palette when a using a Custom Palette Bitmap.
  37. PALETTEENTRY CMyBitmap::s_rgpeSavedSystemPalette[nMaxSavedSystemPaletteEntries];
  38. /////////////////////////////////////////////////////////////////////////////
  39. //++
  40. //
  41. // CMyBitmap::CMyBitmap
  42. //
  43. // Routine Description:
  44. // Default constructor.
  45. //
  46. // Arguments:
  47. // None.
  48. //
  49. // Return Value:
  50. // None.
  51. //
  52. // Exceptions Thrown:
  53. // None.
  54. //--
  55. /////////////////////////////////////////////////////////////////////////////
  56. CMyBitmap::CMyBitmap(void)
  57. {
  58. m_hinst = NULL;
  59. m_pbiNormal = NULL;
  60. m_pbiHighlighted = NULL;
  61. m_pbBitmap = NULL;
  62. m_hPalette = NULL;
  63. m_nSavedSystemPalette = 0;
  64. SetCustomPalette(FALSE);
  65. } //*** CMyBitmap::CMyBitmap()
  66. /////////////////////////////////////////////////////////////////////////////
  67. //++
  68. //
  69. // CMyBitmap::~CMyBitmap
  70. //
  71. // Routine Description:
  72. // Destructor.
  73. //
  74. // Arguments:
  75. // None.
  76. //
  77. // Return Value:
  78. // None.
  79. //
  80. // Exceptions Thrown:
  81. // None.
  82. //--
  83. /////////////////////////////////////////////////////////////////////////////
  84. CMyBitmap::~CMyBitmap(void)
  85. {
  86. delete [] (PBYTE) PbiNormal();
  87. delete [] (PBYTE) PbiHighlighted();
  88. delete [] (PBYTE) PbBitmap();
  89. // If we saved the System Palette Entries, we have a Palette, and the
  90. // number of colors for the Palette() is enough to restore the System
  91. // Palette entries...
  92. if (m_nSavedSystemPalette
  93. && (HPalette() != NULL)
  94. && (NColors() >= m_nSavedSystemPalette))
  95. {
  96. HDC hdcScreen;
  97. UINT nRestoredEntries;
  98. HPALETTE hOldPalette;
  99. Trace(g_tagBitmap, _T("Restoring Screen Palette HPalette()=0x%x..."), HPalette());
  100. Trace(g_tagBitmap, _T("Restoring Screen Palette Entries=%d"), m_nSavedSystemPalette);
  101. // Restore the System Palette Entries
  102. nRestoredEntries = ::SetPaletteEntries(HPalette(), 0, m_nSavedSystemPalette, s_rgpeSavedSystemPalette);
  103. Trace(g_tagBitmap, _T("Restored Screen Palette Entries=%d"), nRestoredEntries);
  104. // Get the Screen's HDC
  105. hdcScreen = ::GetDC(NULL);
  106. // Select the Palette into the Screen's HDC
  107. hOldPalette = ::SelectPalette(hdcScreen, HPalette(), FALSE);
  108. // Unrealize the Palette to insure all the colors are forced into the System Palette
  109. ::UnrealizeObject(HPalette());
  110. // Force the local Palette's colors into the System Palette.
  111. ::RealizePalette(hdcScreen);
  112. // Release the Screen's HDC
  113. ::ReleaseDC(NULL, hdcScreen);
  114. // Invalidate the Screen completely so all windows are redrawn.
  115. ::InvalidateRect(NULL, NULL, TRUE);
  116. }
  117. // Destroy the Handle to the locally created Custom Palette.
  118. if (HPalette() != NULL)
  119. ::DeleteObject(HPalette());
  120. } //*** CMyBitmap::~CMyBitmap()
  121. /////////////////////////////////////////////////////////////////////////////
  122. //++
  123. //
  124. // CMyBitmap::Load
  125. //
  126. // Purpose:
  127. // Loads a bitmap from the resource into memory.
  128. //
  129. // Arguments:
  130. // idBitmap id of the resource to load
  131. //
  132. // Return Value:
  133. // None.
  134. //
  135. // Exceptions Thrown:
  136. // Any exceptions thrown by LoadBitmapResource, CreatePallette,
  137. // CreatePALColorMapping, or new.
  138. //--
  139. /////////////////////////////////////////////////////////////////////////////
  140. void CMyBitmap::Load(ID idBitmap)
  141. {
  142. // Load the Bitmap Header Information, Color Mapping Information, and the Bitmap Image.
  143. LoadBitmapResource(
  144. idBitmap,
  145. Hinst(),
  146. MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL)
  147. );
  148. ASSERT(PbiNormal() != NULL);
  149. ASSERT(PbBitmap() != NULL);
  150. // Start by initializing some internal variables...
  151. m_dx = PbiNormal()->bmiHeader.biWidth;
  152. m_dy = PbiNormal()->bmiHeader.biHeight;
  153. ASSERT(PbiHighlighted() == NULL);
  154. if (BCustomPalette())
  155. {
  156. Trace(g_tagBitmap, _T("Load() - Creating Logical Palette"));
  157. // Save the System Palette Entries for use in the Destructor.
  158. SaveSystemPalette();
  159. // Create a Global HPalette() for use in the Paint() routine.
  160. CreatePalette();
  161. // Re-create the PbiNormal() for DIB_PAL_COLORS in the Paint() routine.
  162. CreatePALColorMapping();
  163. } // if: using a custom pallette
  164. else
  165. {
  166. // Create and Initialize the PbiHighlighted() for 16 color bitmaps.
  167. ASSERT(NColors() <= 16);
  168. Trace(g_tagBitmap, _T("Load() - Allocating PbiHighlighted()"));
  169. m_pbiHighlighted = (BITMAPINFO *) new BYTE[CbBitmapInfo()];
  170. if (m_pbiHighlighted != NULL)
  171. {
  172. ::CopyMemory(PbiHighlighted(), PbiNormal(), CbBitmapInfo());
  173. } // if: bitmapinfo allocated successfully
  174. } // else: not using a custom pallette
  175. } //*** CMyBitmap::Load()
  176. /////////////////////////////////////////////////////////////////////////////
  177. //++
  178. //
  179. // CMyBitmap::LoadBitmapResource
  180. //
  181. // Purpose:
  182. // Load a bitmap resource into the CMyBitmap class. This includes loading (a) bitmap
  183. // header information, (b) color mapping table, and (c) the actual bitmap.
  184. //
  185. // Arguments:
  186. // idbBitmap Resource id of the bitmap to load.
  187. // hinst Handle to the Module Instance
  188. // langid Language specific resource (possibly different bitmaps for localized strings [Japanese, etc.])
  189. //
  190. // Return Value:
  191. // None.
  192. //
  193. // Exceptions Thrown:
  194. // GetLastError from FindResourceEx, LoadResource, LockResource,
  195. // Any exceptions thrown by new.
  196. //
  197. //--
  198. /////////////////////////////////////////////////////////////////////////////
  199. void CMyBitmap::LoadBitmapResource(ID idbBitmap, HINSTANCE hinst, LANGID langid)
  200. {
  201. HRSRC hrsrc = NULL;
  202. HGLOBAL hglbl = NULL;
  203. LPBITMAPINFO pBitmapInfo = NULL;
  204. LPBITMAPINFOHEADER pBitmapInfoHeader = NULL;
  205. LPRGBQUAD pRgbQuad = NULL;
  206. CB cbBitmapData;
  207. BYTE * pbImageBits;
  208. Trace(g_tagLoadBitmapResource, _T("LoadBitmapResource(%d) - Entering"), idbBitmap);
  209. ASSERT(idbBitmap != NULL);
  210. if (hinst == NULL)
  211. hinst = AfxGetApp()->m_hInstance;
  212. // We need to find the bitmap data which includes (a) header info, (b) color, and (c) the bitmap.
  213. hrsrc = ::FindResourceEx(hinst, RT_BITMAP, MAKEINTRESOURCE(idbBitmap), langid);
  214. if (hrsrc == NULL)
  215. {
  216. DWORD dwError = ::GetLastError();
  217. CString strError;
  218. if (dwError == ERROR_RESOURCE_NAME_NOT_FOUND)
  219. strError.Format(_T("Bitmap Resource %d Not Found. NT Error %d Loading Bitmap [Lang=%d, SubLang=%d]"),
  220. idbBitmap, dwError, PRIMARYLANGID(langid), SUBLANGID(langid));
  221. else
  222. strError.Format(_T("NT Error %d Attempting to Load Bitmap Resource %d [Lang=%d, SubLang=%d]"),
  223. dwError, idbBitmap, PRIMARYLANGID(langid), SUBLANGID(langid));
  224. Trace(g_tagAlways, _T("LoadBitmapResource() - Error '%s'"), strError);
  225. ThrowStaticException(dwError);
  226. } // if: error finding the resource
  227. hglbl = ::LoadResource(hinst, hrsrc);
  228. if (hglbl == NULL)
  229. ThrowStaticException(::GetLastError());
  230. pBitmapInfo = (LPBITMAPINFO) ::LockResource(hglbl);
  231. if (pBitmapInfo == NULL)
  232. ThrowStaticException(::GetLastError());
  233. cbBitmapData = ::SizeofResource(hinst, hrsrc);
  234. ASSERT(cbBitmapData != 0);
  235. Trace(g_tagLoadBitmapResource, _T("Bitmap Location = 0x%x"), pBitmapInfo);
  236. Trace(g_tagLoadBitmapResource, _T("Bitmap Data Size = %d bytes"), cbBitmapData);
  237. pBitmapInfoHeader = (LPBITMAPINFOHEADER) &pBitmapInfo->bmiHeader;
  238. ASSERT(pBitmapInfoHeader != NULL);
  239. Trace(g_tagLoadBitmapResource, _T("Bitmap Info Header = 0x%x"), pBitmapInfoHeader);
  240. ASSERT(pBitmapInfoHeader->biSize == sizeof(BITMAPINFOHEADER));
  241. Trace(g_tagLoadBitmapResource, _T("biSize=%d"), pBitmapInfoHeader->biSize);
  242. Trace(g_tagLoadBitmapResource, _T("biWidth=%d"), pBitmapInfoHeader->biWidth); // Width in Pixels
  243. Trace(g_tagLoadBitmapResource, _T("biHeight=%d"), pBitmapInfoHeader->biHeight); // Height in Pixels
  244. Trace(g_tagLoadBitmapResource, _T("biPlanes=%d"), pBitmapInfoHeader->biPlanes);
  245. Trace(g_tagLoadBitmapResource, _T("biBitCount=%d"), pBitmapInfoHeader->biBitCount);
  246. Trace(g_tagLoadBitmapResource, _T("biCompression=%d"), pBitmapInfoHeader->biCompression);
  247. Trace(g_tagLoadBitmapResource, _T("biSizeImage=%d"), pBitmapInfoHeader->biSizeImage);
  248. Trace(g_tagLoadBitmapResource, _T("biXPelsPerMeter=%d"), pBitmapInfoHeader->biXPelsPerMeter);
  249. Trace(g_tagLoadBitmapResource, _T("biYPelsPerMeter=%d"), pBitmapInfoHeader->biYPelsPerMeter);
  250. Trace(g_tagLoadBitmapResource, _T("biClrUsed=%d"), pBitmapInfoHeader->biClrUsed);
  251. Trace(g_tagLoadBitmapResource, _T("biClrImportant=%d"), pBitmapInfoHeader->biClrImportant);
  252. pRgbQuad = (LPRGBQUAD) &pBitmapInfo->bmiColors;
  253. ASSERT(pRgbQuad != NULL);
  254. Trace(g_tagLoadBitmapResource, _T("Bitmap Rgb Quad = 0x%x"), pRgbQuad);
  255. m_nColors = NColorsFromBitCount(pBitmapInfoHeader->biBitCount);
  256. m_cbColorTable = m_nColors * sizeof(RGBQUAD);
  257. m_cbBitmapInfo = sizeof(BITMAPINFOHEADER) + CbColorTable();
  258. Trace(g_tagLoadBitmapResource, _T("NColors()=%d"), NColors());
  259. Trace(g_tagLoadBitmapResource, _T("CbColorTable()=%d"), CbColorTable());
  260. Trace(g_tagLoadBitmapResource, _T("CbBitmapInfo()=%d"), CbBitmapInfo());
  261. ASSERT(PbiNormal() == NULL);
  262. // Allocate the Normal Bitmap Information
  263. m_pbiNormal = (LPBITMAPINFO) new BYTE[CbBitmapInfo()];
  264. if (m_pbiNormal == NULL)
  265. {
  266. return;
  267. } // if: error allocating the bitmapinfo structure
  268. // Fill PbiNormal() with the Loaded Resource (a) Bitmap Information and Color Mapping Table.
  269. ::CopyMemory(PbiNormal(), pBitmapInfo, CbBitmapInfo());
  270. m_cbImageSize = pBitmapInfoHeader->biSizeImage;
  271. if ((m_cbImageSize == 0) && (pBitmapInfoHeader->biCompression == BI_RGB))
  272. m_cbImageSize = cbBitmapData - CbBitmapInfo();
  273. Trace(g_tagLoadBitmapResource, _T("Allocating Bitmap of size CbImageSize()=%d"), CbImageSize());
  274. ASSERT(cbBitmapData == CbBitmapInfo() + CbImageSize());
  275. ASSERT(PbBitmap() == NULL);
  276. // Allocate memory for the Bitmap Image
  277. m_pbBitmap = new BYTE[CbImageSize()];
  278. if (m_pbBitmap == NULL)
  279. {
  280. return;
  281. } // if: error allocating the bitmap image
  282. pbImageBits = (BYTE *) pBitmapInfo + CbBitmapInfo();
  283. Trace(g_tagLoadBitmapResource, _T("Bitmap Location pbImageBits=0x%x"), pbImageBits);
  284. // Copy the Image Bits into the allocated memory.
  285. ::CopyMemory(PbBitmap(), pbImageBits, CbImageSize());
  286. } //*** CMyBitmap::LoadBitmapResource()
  287. /////////////////////////////////////////////////////////////////////////////
  288. //++
  289. //
  290. // CMyBitmap::NColorsFromBitCount
  291. //
  292. // Purpose:
  293. // Compute the number of colors given the number of bits to represent color.
  294. //
  295. // Arguments:
  296. // nBitCount The number of bits used for color representation.
  297. //
  298. // Return Value:
  299. // nColors Number of colors represented with nBitCount bits.
  300. //
  301. //--
  302. /////////////////////////////////////////////////////////////////////////////
  303. int CMyBitmap::NColorsFromBitCount(int nBitCount) const
  304. {
  305. int nColors;
  306. switch (nBitCount)
  307. {
  308. default:
  309. nColors = 0;
  310. break;
  311. case 1:
  312. nColors = 2;
  313. break;
  314. case 4:
  315. nColors = 16;
  316. break;
  317. case 8:
  318. nColors = 256;
  319. break;
  320. }
  321. return nColors;
  322. } //*** CMyBitmap::NColorsFromBitCount()
  323. /////////////////////////////////////////////////////////////////////////////
  324. //++
  325. //
  326. // CMyBitmap::SaveSystemPalette
  327. //
  328. // Purpose:
  329. // To save the System Palette Colors for use when a Custom Palette overwrites
  330. // the System Palette entries. The Saved System Palette (s_rgpeSavedSystemPalette)
  331. // is used in the CMyBitmap's destructor.
  332. //
  333. // Arguments:
  334. // None.
  335. //
  336. // Return Values:
  337. // None.
  338. //
  339. //--
  340. /////////////////////////////////////////////////////////////////////////////
  341. void CMyBitmap::SaveSystemPalette(void)
  342. {
  343. HDC hdcScreen;
  344. int nPaletteEntries;
  345. int nSavedEntries;
  346. // Get the Screen's HDC
  347. hdcScreen = ::GetDC(NULL);
  348. if (hdcScreen == NULL)
  349. {
  350. return;
  351. } // if: couldn't get the screen DC
  352. // Can only save the System Palette Colors when the Device's RC_PALETTE bit is set.
  353. if (::GetDeviceCaps(hdcScreen, RASTERCAPS) & RC_PALETTE)
  354. {
  355. // Get the Number of System Palette Entries
  356. nPaletteEntries = ::GetDeviceCaps(hdcScreen, SIZEPALETTE);
  357. Trace(g_tagBitmap, _T("SaveSystemPalette() - nPaletteEntries=%d"), nPaletteEntries);
  358. if ((nPaletteEntries > 0)
  359. && (nPaletteEntries <= nMaxSavedSystemPaletteEntries))
  360. {
  361. // Get the Current System Palette Entries
  362. nSavedEntries = ::GetSystemPaletteEntries(hdcScreen, 0, nPaletteEntries, s_rgpeSavedSystemPalette);
  363. // Set the number of Saved System Palette Entries list for use in OnDestroy().
  364. if (nSavedEntries == nPaletteEntries)
  365. {
  366. Trace(g_tagBitmap, _T("SaveSystemPalette() - Saved System Palette Entries=%d"), nPaletteEntries);
  367. m_nSavedSystemPalette = nPaletteEntries;
  368. }
  369. }
  370. }
  371. // Release the Screen's HDC
  372. ::ReleaseDC(NULL, hdcScreen);
  373. } //*** CMyBitmap::SaveSystemPalette()
  374. /////////////////////////////////////////////////////////////////////////////
  375. //++
  376. //
  377. // CMyBitmap::CreatePalette
  378. //
  379. // Purpose:
  380. // Create a logical palette from the color mapping table embedded in the
  381. // bitmap resource.
  382. //
  383. // Arguments:
  384. // None.
  385. //
  386. // Return Values:
  387. // None.
  388. //
  389. // Exceptions Thrown:
  390. // GetLastError from CreatePalette.
  391. // Any exceptions thrown by new.
  392. //--
  393. /////////////////////////////////////////////////////////////////////////////
  394. void CMyBitmap::CreatePalette(void)
  395. {
  396. LPLOGPALETTE pLogicalPalette = NULL;
  397. CB cbLogicalPalette;
  398. int nColor;
  399. LPPALETTEENTRY pPaletteEntry;
  400. Trace(g_tagBitmap, _T("CreatePalette() - Entering"));
  401. try
  402. {
  403. // Compute the size of the logical palette.
  404. cbLogicalPalette = sizeof(LOGPALETTE) + (NColors() * sizeof(PALETTEENTRY));
  405. Trace(g_tagBitmap, _T("CreatePalette() - cbLogicalPalette=%d"), cbLogicalPalette);
  406. // Allocate the Logical Palette Memory
  407. pLogicalPalette = (LPLOGPALETTE) new BYTE[cbLogicalPalette];
  408. if (pLogicalPalette == NULL)
  409. {
  410. ThrowStaticException(GetLastError());
  411. return;
  412. } // if: error allocating the Logical Palette Memory
  413. ASSERT(pLogicalPalette != NULL);
  414. ASSERT(PbiNormal() != NULL);
  415. pLogicalPalette->palVersion = 0x300; // Windows 3.0
  416. pLogicalPalette->palNumEntries = (WORD) NColors();
  417. // Fill the Logical Palette's Color Information
  418. for (nColor=0; nColor<NColors(); nColor++)
  419. {
  420. pPaletteEntry = &(pLogicalPalette->palPalEntry[nColor]);
  421. pPaletteEntry->peRed = PbiNormal()->bmiColors[nColor].rgbRed;
  422. pPaletteEntry->peGreen = PbiNormal()->bmiColors[nColor].rgbGreen;
  423. pPaletteEntry->peBlue = PbiNormal()->bmiColors[nColor].rgbBlue;
  424. pPaletteEntry->peFlags = 0;
  425. }
  426. // Create the NT Palette for use in the Paint Routine.
  427. m_hPalette = ::CreatePalette(pLogicalPalette);
  428. if (m_hPalette == NULL)
  429. {
  430. ThrowStaticException(::GetLastError());
  431. }
  432. ASSERT(HPalette() != NULL);
  433. delete [] (PBYTE) pLogicalPalette;
  434. } // try
  435. catch (CException *)
  436. {
  437. delete [] (PBYTE) pLogicalPalette;
  438. throw;
  439. } // catch: anything
  440. } //*** CMyBitmap::CreatePalette()
  441. /////////////////////////////////////////////////////////////////////////////
  442. //++
  443. //
  444. // CMyBitmap::CreatePALColorMapping
  445. //
  446. // Purpose:
  447. // Given BITMAPINFO in PbiNormal(), recreate the PbiNormal() into a
  448. // DIB_PAL_COLORS format.
  449. //
  450. // Arguments:
  451. // None.
  452. //
  453. // Return Value:
  454. // None.
  455. //
  456. // Exceptions Thrown:
  457. // Any exceptions thrown by new.
  458. //--
  459. /////////////////////////////////////////////////////////////////////////////
  460. void CMyBitmap::CreatePALColorMapping(void)
  461. {
  462. LPBITMAPINFO pNewBitmapInfo = NULL;
  463. CB cbNewBitmapInfo;
  464. CB cbNewBitmapHeaderInfo;
  465. BYTE * pbColorTable;
  466. WORD wColor;
  467. ASSERT(PbiNormal() != NULL);
  468. ASSERT(PbiNormal()->bmiHeader.biSize == sizeof(BITMAPINFOHEADER));
  469. // ASSERT(PbiNormal()->bmiHeader.biClrUsed == (UINT) NColors());
  470. try
  471. {
  472. Trace(g_tagBitmap, _T("CreatePALColorMapping() - Entering"));
  473. cbNewBitmapHeaderInfo = sizeof(BITMAPINFOHEADER);
  474. Trace(g_tagBitmap, _T("CreatePALColorMapping() - cbNewBitmapHeaderInfo=%d"), cbNewBitmapHeaderInfo);
  475. // New Bitmap Info is the Info Header plus the Color mapping information.
  476. cbNewBitmapInfo = cbNewBitmapHeaderInfo + (NColors() * sizeof(WORD));
  477. Trace(g_tagBitmap, _T("CreatePALColorMapping() - cbNewBitmapInfo=%d"), cbNewBitmapInfo);
  478. // Allocate the New Bitmap Information
  479. pNewBitmapInfo = (LPBITMAPINFO) new BYTE[cbNewBitmapInfo];
  480. ASSERT(pNewBitmapInfo != NULL);
  481. if (pNewBitmapInfo == NULL)
  482. {
  483. ThrowStaticException(GetLastError());
  484. return;
  485. } // if: error allocating the new bitmapinfo structure
  486. Trace(g_tagBitmap, _T("CreatePALColorMapping() - New Bitmap Info Location=0x%x"), pNewBitmapInfo);
  487. // Copy the Header Information to the allocated memory.
  488. ::CopyMemory(pNewBitmapInfo, PbiNormal(), cbNewBitmapHeaderInfo);
  489. // Create the Color Lookup Table.
  490. pbColorTable = (BYTE *) (pNewBitmapInfo) + cbNewBitmapHeaderInfo;
  491. ASSERT(pbColorTable + (NColors() * sizeof(WORD)) == (BYTE *) (pNewBitmapInfo) + cbNewBitmapInfo);
  492. Trace(g_tagBitmap, _T("CreatePALColorMapping() - Filling %d Color Table at Location 0x%x"), NColors(), pbColorTable);
  493. // Fill the PAL Color Lookup Table
  494. for (wColor = 0 ; wColor < NColors() ; wColor++)
  495. {
  496. ::CopyMemory(pbColorTable, &wColor, sizeof(WORD));
  497. pbColorTable += sizeof(WORD);
  498. }
  499. delete [] (PBYTE) PbiNormal();
  500. m_pbiNormal = pNewBitmapInfo;
  501. m_cbBitmapInfo = cbNewBitmapInfo;
  502. pNewBitmapInfo = NULL;
  503. } // try
  504. catch (CException *)
  505. {
  506. delete [] pNewBitmapInfo;
  507. throw;
  508. } // catch: anything
  509. } //*** CMyBitmap::CreatePALColorMapping()
  510. /////////////////////////////////////////////////////////////////////////////
  511. //++
  512. //
  513. // CMyBitmap::Paint
  514. //
  515. // Purpose:
  516. // Paints a sub-bitmap
  517. //
  518. // Parameters:
  519. // hdc HDC to paint
  520. // prect Where to position the bitmap:
  521. // Only the upperleft corner is used
  522. // bHighlighted Used to select the color map to use.
  523. //
  524. //--
  525. /////////////////////////////////////////////////////////////////////////////
  526. void CMyBitmap::Paint(HDC hdc, RECT * prect, BOOL bHighlighted)
  527. {
  528. LPBITMAPINFO pBitmapInfo;
  529. UINT nColorUse;
  530. HPALETTE hOldPalette = NULL;
  531. ASSERT(hdc != NULL);
  532. ASSERT(prect != NULL);
  533. Trace(g_tagBitmap, _T("bHighlighted = %d"), bHighlighted);
  534. #ifdef _DEBUG
  535. {
  536. int nPlanes;
  537. int nBitsPerPixel;
  538. int nBitCount;
  539. nPlanes = ::GetDeviceCaps(hdc, PLANES);
  540. nBitsPerPixel = ::GetDeviceCaps(hdc, BITSPIXEL);
  541. nBitCount = nPlanes * nBitsPerPixel;
  542. Trace(g_tagBitmap, _T("Paint() - nPlanes=%d"), nPlanes);
  543. Trace(g_tagBitmap, _T("Paint() - nBitsPerPixel=%d"), nBitsPerPixel);
  544. Trace(g_tagBitmap, _T("Paint() - nBitCount=%u"), nBitCount);
  545. }
  546. #endif
  547. try
  548. {
  549. if (BCustomPalette())
  550. {
  551. ASSERT(PbiNormal() != NULL);
  552. ASSERT(HPalette() != NULL);
  553. // Select the Custom Palette into the HDC about to be drawn...
  554. hOldPalette = ::SelectPalette(hdc, HPalette(), FALSE); // FALSE causes the current Screen Palette to be Overwritten
  555. if (hOldPalette == NULL)
  556. ThrowStaticException(::GetLastError());
  557. // Force the Palette colors into the System Palette
  558. if (::RealizePalette(hdc) == GDI_ERROR)
  559. ThrowStaticException(::GetLastError());
  560. pBitmapInfo = PbiNormal();
  561. nColorUse = DIB_PAL_COLORS;
  562. #ifdef NEVER
  563. pBitmapInfo = PbiNormal();
  564. nColorUse = DIB_RGB_COLORS;
  565. #endif
  566. } // if: using a custom palette
  567. else
  568. {
  569. ASSERT(NColors() <= 16);
  570. ASSERT(PbiNormal() != NULL);
  571. ASSERT(PbiHighlighted() != NULL);
  572. pBitmapInfo = (bHighlighted ? PbiHighlighted() : PbiNormal());
  573. nColorUse = DIB_RGB_COLORS;
  574. } // else: not using a custom palette
  575. ::SetDIBitsToDevice(
  576. hdc,
  577. (int) prect->left, // X coordinate on screen.
  578. (int) prect->top, // Y coordinate on screen.
  579. (DWORD) Dx(), // cx to paint
  580. (DWORD) Dy(), // cy to paint
  581. // Note: (0,0) of the DIB is lower-left corner!?!
  582. 0, // In pbi, xLeft to paint
  583. 0, // In pbi, yLower to paint
  584. 0, // Start scan line
  585. Dy(), // Number of scan lines
  586. PbBitmap(), // The buffer description
  587. pBitmapInfo, // Bitmap Information
  588. nColorUse // DIB_RGB_COLORS or DIB_PAL_COLORS
  589. );
  590. } // try
  591. catch (CException * pe)
  592. {
  593. pe->ReportError();
  594. pe->Delete();
  595. } // catch: CException
  596. } //*** CMyBitmap::Paint()
  597. /////////////////////////////////////////////////////////////////////////////
  598. //++
  599. //
  600. // CMyBitmap::LoadColors
  601. //
  602. // Purpose:
  603. // Loads the color maps based on the system settings
  604. //
  605. // Arguments:
  606. // pnColorNormal & pnColorHighlighted
  607. // Arrays of 16 elements:
  608. // -1 Do not remap this color
  609. // COLOR_xxx Remap this color to the system color.
  610. //
  611. //--
  612. /////////////////////////////////////////////////////////////////////////////
  613. void CMyBitmap::LoadColors(int * pnColorNormal, int * pnColorHighlighted)
  614. {
  615. LoadColors(pnColorNormal, PbiNormal());
  616. LoadColors(pnColorHighlighted, PbiHighlighted());
  617. } //*** CMyBitmap::LoadColors(pnColorNormal, pnColorHighlighted)
  618. /////////////////////////////////////////////////////////////////////////////
  619. //++
  620. //
  621. // CMyBitmap::LoadColors
  622. //
  623. // Purpose:
  624. // Similar to above LoadColors except only the PbiNormal() colors are altered.
  625. //
  626. // Arguments:
  627. // pnColorNormal Array of color mapping table.
  628. //
  629. // Returns:
  630. // None.
  631. //
  632. //--
  633. /////////////////////////////////////////////////////////////////////////////
  634. void CMyBitmap::LoadColors(int * pnColorNormal)
  635. {
  636. LoadColors(pnColorNormal, PbiNormal());
  637. } //*** CMyBitmap::LoadColors(pnColorNormal)
  638. /////////////////////////////////////////////////////////////////////////////
  639. //++
  640. //
  641. // CMyBitmap::LoadColors
  642. //
  643. // Purpose:
  644. // Loads one color map based on the system settings
  645. //
  646. // Arguments:
  647. // pnColor
  648. // Arrays of 16 elements:
  649. // -1 Do not remap this color
  650. // COLOR_xxx Remap this color to the system color.
  651. // pbi
  652. // BITMAPINFO structure to adjust
  653. //
  654. //--
  655. /////////////////////////////////////////////////////////////////////////////
  656. void CMyBitmap::LoadColors(int * pnColor, BITMAPINFO * pbi)
  657. {
  658. int inColor;
  659. COLORREF cr;
  660. ASSERT(pbi != NULL);
  661. ASSERT(pbi->bmiHeader.biBitCount <= 4);
  662. ASSERT(NColors() <= 16);
  663. ASSERT(BCustomPalette() == FALSE);
  664. for (inColor = 0; inColor < 16; inColor++)
  665. {
  666. if (pnColor[inColor] == -1)
  667. continue;
  668. cr = GetSysColor(pnColor[inColor]);
  669. pbi->bmiColors[inColor].rgbRed = GetRValue(cr);
  670. pbi->bmiColors[inColor].rgbGreen = GetGValue(cr);
  671. pbi->bmiColors[inColor].rgbBlue = GetBValue(cr);
  672. }
  673. } //*** CMyBitmap::LoadColors(pnColor, pbi)