Source code of Windows XP (NT5)
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.

889 lines
26 KiB

  1. /****************************************************************************
  2. *
  3. * MODULE : DIB.C
  4. *
  5. * DESCRIPTION : Routines for dealing with Device Independent Bitmaps.
  6. *
  7. * FUNCTION :bmfNumDIBColors(HANDLE hDib)
  8. *
  9. * FUNCTION :bmfCreateDIBPalette(HANDLE hDib)
  10. *
  11. * FUNCTION :bmfDIBSize(HANDLE hDIB)
  12. *
  13. * FUNCTION :bmfDIBFromBitmap(HBITMAP hBmp, DWORD biStyle, WORD biBits,
  14. * HPALETTE hPal)
  15. *
  16. * FUNCTION :bmfBitmapFromDIB(HANDLE hDib, HPALETTE hPal)
  17. *
  18. * FUNCTION :bmfBitmapFromIcon (HICON hIcon, DWORD dwColor)
  19. *
  20. * FUNCTION :bmfDrawBitmap(HDC hdc, int xpos, int ypos, HBITMAP hBmp,
  21. * DWORD rop)
  22. *
  23. * FUNCTION :bmfDrawBitmapSize(HDC hdc, int x, int y, int xSize,
  24. * int ySize, HBITMAP hBmp, DWORD rop)
  25. *
  26. * FUNCTION :DIBInfo(HANDLE hbi,LPBITMAPINFOHEADER lpbi)
  27. *
  28. * FUNCTION :CreateBIPalette(LPBITMAPINFOHEADER lpbi)
  29. *
  30. * FUNCTION :PaletteSize(VOID FAR * pv)
  31. *
  32. * FUNCTION :NumDIBColors(VOID FAR * pv)
  33. *
  34. * FUNCTION :LoadUIBitmap(HANDLE hInstance, LPCTSTR szName,
  35. * COLORREF rgbText,
  36. * COLORREF rgbFace, COLORREF rgbShadow,
  37. * COLORREF rgbHighlight, COLORREF rgbWindow,
  38. * COLORREF rgbFrame)
  39. *
  40. ****************************************************************************/
  41. #include <windows.h>
  42. #include <mmsystem.h>
  43. #include <string.h>
  44. #include <stdlib.h>
  45. #include <shellapi.h>
  46. #include "draw.h"
  47. /* global variables */
  48. extern HANDLE ghInstance; //instance handle of DIB.DLL
  49. /***************************************************************************
  50. *
  51. * FUNCTION :bmfNumDIBColors(HANDLE hDib)
  52. *
  53. * PURPOSE :Returns the number of colors required to display the DIB
  54. * indicated by hDib.
  55. *
  56. * RETURNS :The number of colors in the DIB. Possibilities are
  57. * 2, 16, 256, and 0 (0 indicates a 24-bit DIB). In
  58. * the case of an error, -1 is returned.
  59. *
  60. ****************************************************************************/
  61. WORD WINAPI bmfNumDIBColors (HANDLE hDib)
  62. {
  63. WORD bits;
  64. LPBITMAPINFOHEADER lpbi;
  65. lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDib);
  66. if (!lpbi)
  67. return ((WORD)-1);
  68. /* The function NumDIBColors will return the number of colors in the
  69. * DIB by looking at the BitCount field in the info block
  70. */
  71. bits = NumDIBColors(lpbi);
  72. GlobalUnlock(hDib);
  73. return(bits);
  74. }
  75. /***************************************************************************
  76. *
  77. * FUNCTION :bmfCreateDIBPalette(HANDLE hDib)
  78. *
  79. * PURPOSE :Creates a palette suitable for displaying hDib.
  80. *
  81. * RETURNS :A handle to the palette if successful, NULL otherwise.
  82. *
  83. ****************************************************************************/
  84. HPALETTE WINAPI bmfCreateDIBPalette (HANDLE hDib)
  85. {
  86. HPALETTE hPal;
  87. LPBITMAPINFOHEADER lpbi;
  88. if (!hDib)
  89. return NULL; //bail out if handle is invalid
  90. lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDib);
  91. if (!lpbi)
  92. return NULL;
  93. hPal = CreateBIPalette(lpbi);
  94. GlobalUnlock(hDib);
  95. return hPal;
  96. }
  97. /***************************************************************************
  98. *
  99. * FUNCTION :bmfDIBSize(HANDLE hDIB)
  100. *
  101. * PURPOSE :Return the size of a DIB.
  102. *
  103. * RETURNS :DWORD with size of DIB, include BITMAPINFOHEADER and
  104. * palette. Returns 0 if failed.
  105. *
  106. * HISTORY:
  107. * 92/08/13 - BUG 1642: (w-markd)
  108. * Added this function so Quick Recorder could find out the
  109. * size of a DIB.
  110. * 92/08/29 - BUG 2123: (w-markd)
  111. * If the biSizeImage field of the structure we get is zero,
  112. * then we have to calculate the size of the image ourselves.
  113. * Also, after size is calculated, we bail out if the
  114. * size we calculated is larger than the size of the global
  115. * object, since this indicates that the structure data
  116. * we used to calculate the size was invalid.
  117. *
  118. ****************************************************************************/
  119. DWORD WINAPI bmfDIBSize(HANDLE hDIB)
  120. {
  121. LPBITMAPINFOHEADER lpbi;
  122. DWORD dwSize;
  123. /* Lock down the handle, and cast to a LPBITMAPINFOHEADER
  124. ** so we can read the fields we need
  125. */
  126. lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDIB);
  127. if (!lpbi)
  128. return 0;
  129. /* BUG 2123: (w-markd)
  130. ** Since the biSizeImage could be zero, we may have to calculate
  131. ** the size ourselves.
  132. */
  133. dwSize = lpbi->biSizeImage;
  134. if (dwSize == 0)
  135. dwSize = WIDTHBYTES((WORD)(lpbi->biWidth) * lpbi->biBitCount) *
  136. lpbi->biHeight;
  137. /* The size of the DIB is the size of the BITMAPINFOHEADER
  138. ** structure (lpbi->biSize) plus the size of our palette plus
  139. ** the size of the actual data (calculated above).
  140. */
  141. dwSize += lpbi->biSize + (DWORD)PaletteSize(lpbi);
  142. /* BUG 2123: (w-markd)
  143. ** Check to see if the size is greater than the size
  144. ** of the global object. If it is, the hDIB is corrupt.
  145. */
  146. GlobalUnlock(hDIB);
  147. if (dwSize > GlobalSize(hDIB))
  148. return 0;
  149. else
  150. return(dwSize);
  151. }
  152. /***************************************************************************
  153. *
  154. * FUNCTION :bmfDIBFromBitmap(HBITMAP hBmp, DWORD biStyle, WORD biBits,
  155. * HPALETTE hPal)
  156. *
  157. * PURPOSE :Converts the device-dependent BITMAP indicated by hBmp into
  158. * a DIB. biStyle indicates whether the palette contains
  159. * DIB_RGB_COLORS or DIB_PAL_COLORS. biBits indicates the
  160. * desired number of bits in the destination DIB. If biBits
  161. * is zero, the destination DIB will be created with the
  162. * minimum required bits. hPal is a handle to the palette to be
  163. * stored with the DIB data. If hPal is NULL, the default
  164. * system palette is used.
  165. *
  166. * RETURNS :A global handle to a memory block containing the DIB
  167. * information in CF_DIB format. NULL is returned if errors
  168. * are encountered.
  169. *
  170. * HISTORY:
  171. *
  172. * 92/08/12 - BUG 1642: (angeld)
  173. * Check the return value from GetObject, it will tell us
  174. * if the handle hBmp was valid. bail out right away if it isn't
  175. * 92/08/29 - BUG 2123: (w-markd)
  176. * Use temporary variable to store old palette, then
  177. * reselect the old palette when we are done.
  178. *
  179. ****************************************************************************/
  180. HANDLE WINAPI bmfDIBFromBitmap (HBITMAP hBmp, DWORD biStyle, WORD biBits,
  181. HPALETTE hPal)
  182. {
  183. BITMAP bm;
  184. BITMAPINFOHEADER bi;
  185. BITMAPINFOHEADER FAR *lpbi;
  186. DWORD dwLen;
  187. HANDLE hDib;
  188. HANDLE hMem;
  189. HDC hdc;
  190. HPALETTE hOldPal;
  191. if (!hBmp || !(GetObject(hBmp,sizeof(bm),(LPSTR)&bm)))
  192. {
  193. #if DEBUG
  194. OutputDebugString(TEXT("bmfDIBFromBitmap: INVALID HBITMAP!!!\n\r"));
  195. #endif
  196. return NULL; //bail out if handle is invalid
  197. }
  198. /* get default system palette if hPal is invalid */
  199. if (hPal == NULL)
  200. hPal = GetStockObject(DEFAULT_PALETTE);
  201. if (biBits == 0)
  202. biBits = bm.bmPlanes * bm.bmBitsPixel;
  203. /* set up BITMAPINFOHEADER structure */
  204. bi.biSize = sizeof(BITMAPINFOHEADER);
  205. bi.biWidth = bm.bmWidth;
  206. bi.biHeight = bm.bmHeight;
  207. bi.biPlanes = 1;
  208. bi.biBitCount = biBits;
  209. bi.biCompression = biStyle;
  210. bi.biSizeImage = 0;
  211. bi.biXPelsPerMeter = 0;
  212. bi.biYPelsPerMeter = 0;
  213. bi.biClrUsed = 0;
  214. bi.biClrImportant = 0;
  215. dwLen = bi.biSize + PaletteSize(&bi);
  216. hdc = GetDC(NULL);
  217. /* BUG 2123: (w-markd)
  218. ** Store the previous palette in hOldPal, restore it on exit.
  219. */
  220. hOldPal = SelectPalette(hdc,hPal,FALSE);
  221. RealizePalette(hdc);
  222. /* get global memory for DIB */
  223. hDib = GlobalAlloc(GHND,dwLen);
  224. if (!hDib)
  225. {
  226. /* could not allocate memory; clean up and exit */
  227. SelectPalette(hdc,hOldPal,FALSE);
  228. ReleaseDC(NULL,hdc);
  229. return NULL;
  230. }
  231. lpbi = (VOID FAR *)GlobalLock(hDib);
  232. if (!lpbi)
  233. {
  234. /* could not lock memory; clean up and exit */
  235. SelectPalette(hdc,hOldPal,FALSE);
  236. ReleaseDC(NULL,hdc);
  237. GlobalFree(hDib);
  238. return NULL;
  239. }
  240. *lpbi = bi;
  241. /* call GetDIBits with a NULL lpBits param, so it will calculate the
  242. * biSizeImage field for us
  243. */
  244. GetDIBits(hdc, hBmp, 0, (WORD)bi.biHeight,
  245. NULL, (LPBITMAPINFO)lpbi, DIB_RGB_COLORS);
  246. bi = *lpbi;
  247. GlobalUnlock(hDib);
  248. /* If the driver did not fill in the biSizeImage field, make one up */
  249. if (bi.biSizeImage == 0)
  250. {
  251. bi.biSizeImage = WIDTHBYTES((DWORD)bm.bmWidth * biBits) * bm.bmHeight;
  252. if (biStyle != BI_RGB)
  253. bi.biSizeImage = (bi.biSizeImage * 3) / 2;
  254. }
  255. /* realloc the buffer big enough to hold all the bits */
  256. dwLen = bi.biSize + PaletteSize(&bi) + bi.biSizeImage;
  257. hMem = GlobalReAlloc(hDib,dwLen,GMEM_MOVEABLE);
  258. if (!hMem)
  259. {
  260. /* could not allocate memory; clean up and exit */
  261. GlobalFree(hDib);
  262. SelectPalette(hdc,hOldPal,FALSE);
  263. ReleaseDC(NULL,hdc);
  264. return NULL;
  265. }
  266. else
  267. hDib = hMem;
  268. /* call GetDIBits with a NON-NULL lpBits param, and actualy get the
  269. * bits this time
  270. */
  271. lpbi = (VOID FAR *)GlobalLock(hDib);
  272. if (!lpbi)
  273. {
  274. /* could not lock memory; clean up and exit */
  275. GlobalFree(hDib);
  276. SelectPalette(hdc,hOldPal,FALSE);
  277. ReleaseDC(NULL,hdc);
  278. return NULL;
  279. }
  280. if (GetDIBits( hdc, hBmp, 0, (WORD)bi.biHeight,
  281. (LPSTR)lpbi + (WORD)lpbi->biSize + PaletteSize(lpbi),
  282. (LPBITMAPINFO)lpbi, DIB_RGB_COLORS) == 0)
  283. {
  284. /* clean up and exit */
  285. GlobalUnlock(hDib);
  286. GlobalFree(hDib);
  287. SelectPalette(hdc,hOldPal,FALSE);
  288. ReleaseDC(NULL,hdc);
  289. return NULL;
  290. }
  291. bi = *lpbi;
  292. /* clean up and exit */
  293. GlobalUnlock(hDib);
  294. SelectPalette(hdc,hOldPal,FALSE);
  295. ReleaseDC(NULL,hdc);
  296. return hDib;
  297. }
  298. /***************************************************************************
  299. *
  300. * FUNCTION :bmfBitmapFromDIB(HANDLE hDib, HPALETTE hPal)
  301. *
  302. * PURPOSE :Converts DIB information into a device-dependent BITMAP
  303. * suitable for display on the current display device. hDib is
  304. * a global handle to a memory block containing the DIB
  305. * information in CF_DIB format. hPal is a handle to a palette
  306. * to be used for displaying the bitmap. If hPal is NULL, the
  307. * default system palette is used during the conversion.
  308. *
  309. * RETURNS :Returns a handle to a bitmap is successful, NULL otherwise.
  310. *
  311. * HISTORY:
  312. * 92/08/29 - BUG 2123: (w-markd)
  313. * Check if DIB is has a valid size, and bail out if not.
  314. * If no palette is passed in, try to create one. If we
  315. * create one, we must destroy it before we exit.
  316. *
  317. ****************************************************************************/
  318. HBITMAP WINAPI bmfBitmapFromDIB(HANDLE hDib, HPALETTE hPal)
  319. {
  320. LPBITMAPINFOHEADER lpbi;
  321. HPALETTE hPalT;
  322. HDC hdc;
  323. HBITMAP hBmp;
  324. DWORD dwSize;
  325. BOOL bMadePalette = FALSE;
  326. if (!hDib)
  327. return NULL; //bail out if handle is invalid
  328. /* BUG 2123: (w-markd)
  329. ** Check to see if we can get the size of the DIB. If this call
  330. ** fails, bail out.
  331. */
  332. dwSize = bmfDIBSize(hDib);
  333. if (!dwSize)
  334. return NULL;
  335. lpbi = (VOID FAR *)GlobalLock(hDib);
  336. if (!lpbi)
  337. return NULL;
  338. /* prepare palette */
  339. /* BUG 2123: (w-markd)
  340. ** If the palette is NULL, we create one suitable for displaying
  341. ** the dib.
  342. */
  343. if (!hPal)
  344. {
  345. hPal = bmfCreateDIBPalette(hDib);
  346. if (!hPal)
  347. {
  348. GlobalUnlock(hDib);
  349. #ifdef V101
  350. #else
  351. bMadePalette = TRUE;
  352. #endif
  353. return NULL;
  354. }
  355. #ifdef V101
  356. /* BUGFIX: mikeroz 2123 - this flag was in the wrong place */
  357. bMadePalette = TRUE;
  358. #endif
  359. }
  360. hdc = GetDC(NULL);
  361. hPalT = SelectPalette(hdc,hPal,FALSE);
  362. RealizePalette(hdc); // GDI Bug...????
  363. /* Create the bitmap. Note that a return value of NULL is ok here */
  364. hBmp = CreateDIBitmap(hdc, (LPBITMAPINFOHEADER)lpbi, (LONG)CBM_INIT,
  365. (LPSTR)lpbi + lpbi->biSize + PaletteSize(lpbi),
  366. (LPBITMAPINFO)lpbi, DIB_RGB_COLORS );
  367. /* clean up and exit */
  368. /* BUG 2123: (w-markd)
  369. ** If we made the palette, we need to delete it.
  370. */
  371. if (bMadePalette)
  372. DeleteObject(SelectPalette(hdc,hPalT,FALSE));
  373. else
  374. SelectPalette(hdc,hPalT,FALSE);
  375. ReleaseDC(NULL,hdc);
  376. GlobalUnlock(hDib);
  377. return hBmp;
  378. }
  379. /***************************************************************************
  380. *
  381. * FUNCTION :bmfBitmapFromIcon (HICON hIcon, DWORD dwColor)
  382. *
  383. * PURPOSE :Converts an icon into a bitmap. hIcon is a handle to a
  384. * windows ICON object. dwColor sets the background color for
  385. * the bitmap.
  386. *
  387. * RETURNS :A handle to the bitmap is successful, NULL otherwise.
  388. *
  389. ****************************************************************************/
  390. HBITMAP WINAPI bmfBitmapFromIcon (HICON hIcon, DWORD dwColor)
  391. {
  392. HDC hDC;
  393. HDC hMemDC = 0;
  394. HBITMAP hBitmap = 0;
  395. HBITMAP hOldBitmap;
  396. HBRUSH hBrush = 0;
  397. HBRUSH hOldBrush;
  398. int xIcon, yIcon;
  399. hDC = GetDC(NULL);
  400. hMemDC = CreateCompatibleDC( hDC );
  401. if (hMemDC)
  402. {
  403. /* get the size for the destination bitmap */
  404. xIcon = GetSystemMetrics(SM_CXICON);
  405. yIcon = GetSystemMetrics(SM_CYICON);
  406. hBitmap = CreateCompatibleBitmap(hDC, xIcon, yIcon);
  407. if (hBitmap)
  408. {
  409. hBrush = CreateSolidBrush(dwColor);
  410. if (hBrush)
  411. {
  412. hOldBitmap = SelectObject (hMemDC, hBitmap);
  413. hOldBrush = SelectObject (hMemDC, hBrush);
  414. /* draw the icon on the memory device context */
  415. PatBlt (hMemDC, 0, 0, xIcon, yIcon, PATCOPY);
  416. DrawIcon (hMemDC, 0, 0, hIcon);
  417. /* clean up and exit */
  418. DeleteObject(SelectObject(hMemDC, hOldBrush));
  419. SelectObject(hMemDC, hOldBitmap);
  420. DeleteDC(hMemDC);
  421. ReleaseDC(NULL, hDC);
  422. return hBitmap;
  423. }
  424. }
  425. }
  426. /* clean up resources and exit */
  427. if (hBitmap)
  428. DeleteObject(hBitmap);
  429. if (hMemDC)
  430. DeleteDC(hMemDC);
  431. ReleaseDC (NULL, hDC);
  432. return NULL;
  433. }
  434. /***************************************************************************
  435. *
  436. * FUNCTION :bmfDrawBitmap(HDC hdc, int xpos, int ypos, HBITMAP hBmp,
  437. * DWORD rop)
  438. *
  439. * PURPOSE :Draws bitmap hBmp at the specifed position in DC hdc
  440. *
  441. * RETURNS :Return value of BitBlt() or FALSE if in an error is
  442. * encountered. Note that BitBlt returns true if successful.
  443. *
  444. ****************************************************************************/
  445. BOOL WINAPI bmfDrawBitmap (HDC hdc, int xpos, int ypos, HBITMAP hBmp,
  446. DWORD rop)
  447. {
  448. HDC hdcBits;
  449. BITMAP bm;
  450. BOOL bResult;
  451. if (!hdc || !hBmp)
  452. return FALSE;
  453. hdcBits = CreateCompatibleDC(hdc);
  454. if (!hdcBits)
  455. return FALSE;
  456. GetObject(hBmp,sizeof(BITMAP),(LPSTR)&bm);
  457. SelectObject(hdcBits,hBmp);
  458. bResult = BitBlt(hdc,xpos,ypos,bm.bmWidth,bm.bmHeight,hdcBits,0,0,rop);
  459. DeleteDC(hdcBits);
  460. return bResult;
  461. }
  462. /***************************************************************************
  463. *
  464. * FUNCTION :DIBInfo(HANDLE hbi,LPBITMAPINFOHEADER lpbi)
  465. *
  466. * PURPOSE :Retrieves the DIB info associated with a CF_DIB
  467. * format memory block.
  468. *
  469. * RETURNS :TRUE (non-zero) if successful; FALSE (zero) otherwise.
  470. *
  471. ****************************************************************************/
  472. BOOL DIBInfo (HANDLE hbi, LPBITMAPINFOHEADER lpbi)
  473. {
  474. if (!hbi)
  475. return FALSE;
  476. *lpbi = *(LPBITMAPINFOHEADER)GlobalLock (hbi);
  477. if (!lpbi)
  478. return FALSE;
  479. /* fill in the default fields */
  480. if (lpbi->biSize != sizeof (BITMAPCOREHEADER))
  481. {
  482. if (lpbi->biSizeImage == 0L)
  483. lpbi->biSizeImage =
  484. WIDTHBYTES(lpbi->biWidth*lpbi->biBitCount) * lpbi->biHeight;
  485. if (lpbi->biClrUsed == 0L)
  486. lpbi->biClrUsed = NumDIBColors (lpbi);
  487. }
  488. GlobalUnlock (hbi);
  489. return TRUE;
  490. }
  491. /***************************************************************************
  492. *
  493. * FUNCTION :CreateBIPalette(LPBITMAPINFOHEADER lpbi)
  494. *
  495. * PURPOSE :Given a Pointer to a BITMAPINFO struct will create a
  496. * a GDI palette object from the color table.
  497. *
  498. * RETURNS :A handle to the palette if successful, NULL otherwise.
  499. *
  500. ****************************************************************************/
  501. HPALETTE CreateBIPalette (LPBITMAPINFOHEADER lpbi)
  502. {
  503. LPLOGPALETTE pPal;
  504. HPALETTE hPal = NULL;
  505. WORD nNumColors;
  506. BYTE red;
  507. BYTE green;
  508. BYTE blue;
  509. int i;
  510. RGBQUAD FAR *pRgb;
  511. HANDLE hMem;
  512. if (!lpbi)
  513. return NULL;
  514. if (lpbi->biSize != sizeof(BITMAPINFOHEADER))
  515. return NULL;
  516. /* Get a pointer to the color table and the number of colors in it */
  517. pRgb = (RGBQUAD FAR *)((LPSTR)lpbi + (WORD)lpbi->biSize);
  518. nNumColors = NumDIBColors(lpbi);
  519. if (nNumColors)
  520. {
  521. /* Allocate for the logical palette structure */
  522. hMem = GlobalAlloc(GMEM_MOVEABLE,
  523. sizeof(LOGPALETTE) + nNumColors * sizeof(PALETTEENTRY));
  524. if (!hMem)
  525. return NULL;
  526. pPal = (LPLOGPALETTE)GlobalLock(hMem);
  527. if (!pPal)
  528. {
  529. GlobalFree(hMem);
  530. return NULL;
  531. }
  532. pPal->palNumEntries = nNumColors;
  533. pPal->palVersion = PALVERSION;
  534. /* Fill in the palette entries from the DIB color table and
  535. * create a logical color palette.
  536. */
  537. for (i = 0; (unsigned)i < nNumColors; i++)
  538. {
  539. pPal->palPalEntry[i].peRed = pRgb[i].rgbRed;
  540. pPal->palPalEntry[i].peGreen = pRgb[i].rgbGreen;
  541. pPal->palPalEntry[i].peBlue = pRgb[i].rgbBlue;
  542. pPal->palPalEntry[i].peFlags = (BYTE)0;
  543. }
  544. hPal = CreatePalette(pPal);
  545. /* note that a NULL return value for the above CreatePalette call
  546. * is acceptable, since this value will be returned, and is not
  547. * used again here
  548. */
  549. GlobalUnlock(hMem);
  550. GlobalFree(hMem);
  551. }
  552. else if (lpbi->biBitCount == 24)
  553. {
  554. /* A 24 bitcount DIB has no color table entries so, set the number of
  555. * to the maximum value (256).
  556. */
  557. nNumColors = MAXPALETTE;
  558. hMem =GlobalAlloc(GMEM_MOVEABLE,
  559. sizeof(LOGPALETTE) + nNumColors * sizeof(PALETTEENTRY));
  560. if (!hMem)
  561. return NULL;
  562. pPal = (LPLOGPALETTE)GlobalLock(hMem);
  563. if (!pPal)
  564. {
  565. GlobalFree(hMem);
  566. return NULL;
  567. }
  568. pPal->palNumEntries = nNumColors;
  569. pPal->palVersion = PALVERSION;
  570. red = green = blue = 0;
  571. /* Generate 256 (= 8*8*4) RGB combinations to fill the palette
  572. * entries.
  573. */
  574. for (i = 0; (unsigned)i < pPal->palNumEntries; i++)
  575. {
  576. pPal->palPalEntry[i].peRed = red;
  577. pPal->palPalEntry[i].peGreen = green;
  578. pPal->palPalEntry[i].peBlue = blue;
  579. pPal->palPalEntry[i].peFlags = (BYTE)0;
  580. if (!(red += 32))
  581. if (!(green += 32))
  582. blue += 64;
  583. }
  584. hPal = CreatePalette(pPal);
  585. /* note that a NULL return value for the above CreatePalette call
  586. * is acceptable, since this value will be returned, and is not
  587. * used again here
  588. */
  589. GlobalUnlock(hMem);
  590. GlobalFree(hMem);
  591. }
  592. return hPal;
  593. }
  594. /***************************************************************************
  595. *
  596. * FUNCTION :PaletteSize(VOID FAR * pv)
  597. *
  598. * PURPOSE :Calculates the palette size in bytes. If the info. block
  599. * is of the BITMAPCOREHEADER type, the number of colors is
  600. * multiplied by 3 to give the palette size, otherwise the
  601. * number of colors is multiplied by 4.
  602. *
  603. * RETURNS :Palette size in number of bytes.
  604. *
  605. ****************************************************************************/
  606. WORD PaletteSize (VOID FAR *pv)
  607. {
  608. LPBITMAPINFOHEADER lpbi;
  609. WORD NumColors;
  610. lpbi = (LPBITMAPINFOHEADER)pv;
  611. NumColors = NumDIBColors(lpbi);
  612. if (lpbi->biSize == sizeof(BITMAPCOREHEADER))
  613. return (NumColors * sizeof(RGBTRIPLE));
  614. else
  615. return (NumColors * sizeof(RGBQUAD));
  616. }
  617. /***************************************************************************
  618. *
  619. * FUNCTION :NumDIBColors(VOID FAR * pv)
  620. *
  621. * PURPOSE :Determines the number of colors in the DIB by looking at
  622. * the BitCount field in the info block.
  623. * For use only internal to DLL.
  624. *
  625. * RETURNS :The number of colors in the DIB.
  626. *
  627. ****************************************************************************/
  628. WORD NumDIBColors (VOID FAR * pv)
  629. {
  630. int bits;
  631. LPBITMAPINFOHEADER lpbi;
  632. LPBITMAPCOREHEADER lpbc;
  633. lpbi = ((LPBITMAPINFOHEADER)pv);
  634. lpbc = ((LPBITMAPCOREHEADER)pv);
  635. /* With the BITMAPINFO format headers, the size of the palette
  636. * is in biClrUsed, whereas in the BITMAPCORE - style headers, it
  637. * is dependent on the bits per pixel ( = 2 raised to the power of
  638. * bits/pixel).
  639. */
  640. if (lpbi->biSize != sizeof(BITMAPCOREHEADER))
  641. {
  642. if (lpbi->biClrUsed != 0)
  643. return (WORD)lpbi->biClrUsed;
  644. bits = lpbi->biBitCount;
  645. }
  646. else
  647. bits = lpbc->bcBitCount;
  648. switch (bits)
  649. {
  650. case 1:
  651. return 2;
  652. case 4:
  653. return 16;
  654. case 8:
  655. return 256;
  656. default:
  657. /* A 24 bitcount DIB has no color table */
  658. return 0;
  659. }
  660. }
  661. /***************************************************************************
  662. *
  663. * FUNCTION :bmfDrawBitmapSize(HDC hdc, int x, int y, int xSize,
  664. * int ySize, HBITMAP hBmp, DWORD rop)
  665. *
  666. * PURPOSE :Draws bitmap <hBmp> at the specifed position in DC <hdc> with
  667. * a specified size.
  668. *
  669. * RETURNS :Return value of BitBlt() or false in an error is
  670. * encountered. Note that BitBlt returns true if successful.
  671. *
  672. * HISTORY:
  673. * 92/08/13 - BUG 1642: (w-markd)
  674. * Exported this function.
  675. * Also stored object that was returned from SelectObject,
  676. * and selected this back into the hdc before deleting.
  677. *
  678. ****************************************************************************/
  679. BOOL WINAPI bmfDrawBitmapSize (HDC hdc, int xpos, int ypos, int xSize, int ySize, HBITMAP hBmp, DWORD rop)
  680. {
  681. HDC hdcBits;
  682. BOOL bResult;
  683. HBITMAP hOldBmp;
  684. if (!hdc || !hBmp)
  685. return FALSE;
  686. hdcBits = CreateCompatibleDC(hdc);
  687. if (!hdcBits)
  688. return FALSE;
  689. /* BUG 1642: (w-markd)
  690. ** Remeber old bmp and reselect into hdc before DeleteDC
  691. */
  692. hOldBmp = SelectObject(hdcBits,hBmp);
  693. bResult = BitBlt(hdc,xpos,ypos,xSize, ySize,hdcBits, 0,0,rop);
  694. SelectObject(hdcBits, hOldBmp);
  695. DeleteDC(hdcBits);
  696. return bResult;
  697. }
  698. //----------------------------------------------------------------------------
  699. // LoadUIBitmap() - load a bitmap resource
  700. //
  701. // load a bitmap resource from a resource file, converting all
  702. // the standard UI colors to the current user specifed ones.
  703. //
  704. // this code is designed to load bitmaps used in "gray ui" or
  705. // "toolbar" code.
  706. //
  707. // the bitmap must be a 4bpp windows 3.0 DIB, with the standard
  708. // VGA 16 colors.
  709. //
  710. // the bitmap must be authored with the following colors
  711. //
  712. // Button Text Black (index 0)
  713. // Button Face lt gray (index 7)
  714. // Button Shadow gray (index 8)
  715. // Button Highlight white (index 15)
  716. // Window Color yellow (index 11)
  717. // Window Frame green (index 10)
  718. //
  719. // Example:
  720. //
  721. // hbm = LoadUIBitmap(hInstance, "TestBmp",
  722. // GetSysColor(COLOR_BTNTEXT),
  723. // GetSysColor(COLOR_BTNFACE),
  724. // GetSysColor(COLOR_BTNSHADOW),
  725. // GetSysColor(COLOR_BTNHIGHLIGHT),
  726. // GetSysColor(COLOR_WINDOW),
  727. // GetSysColor(COLOR_WINDOWFRAME));
  728. //
  729. // Author: JimBov, ToddLa
  730. // History: 5/13/92 - added to dib.c in sndcntrl.dll, t-chrism
  731. //
  732. //----------------------------------------------------------------------------
  733. HBITMAP WINAPI LoadUIBitmap(
  734. HANDLE hInstance, // EXE file to load resource from
  735. LPCTSTR szName, // name of bitmap resource
  736. COLORREF rgbText, // color to use for "Button Text"
  737. COLORREF rgbFace, // color to use for "Button Face"
  738. COLORREF rgbShadow, // color to use for "Button Shadow"
  739. COLORREF rgbHighlight, // color to use for "Button Hilight"
  740. COLORREF rgbWindow, // color to use for "Window Color"
  741. COLORREF rgbFrame) // color to use for "Window Frame"
  742. {
  743. LPBYTE lpb;
  744. HBITMAP hbm;
  745. LPBITMAPINFOHEADER lpbi = NULL;
  746. HANDLE h;
  747. HDC hdc;
  748. LPDWORD lprgb;
  749. HRSRC hrsrc;
  750. // convert a RGB into a RGBQ
  751. #define RGBQ(dw) RGB(GetBValue(dw),GetGValue(dw),GetRValue(dw))
  752. hrsrc = FindResource(hInstance, szName, RT_BITMAP);
  753. if (hrsrc)
  754. {
  755. h = LoadResource(hInstance,hrsrc);
  756. if (h)
  757. lpbi = (LPBITMAPINFOHEADER)LockResource(h);
  758. }
  759. if (!lpbi)
  760. return(NULL);
  761. if (lpbi->biSize != sizeof(BITMAPINFOHEADER))
  762. return NULL;
  763. if (lpbi->biBitCount != 4)
  764. return NULL;
  765. lprgb = (LPDWORD)((LPBYTE)lpbi + (int)lpbi->biSize);
  766. lpb = (LPBYTE)(lprgb + 16);
  767. lprgb[0] = RGBQ(rgbText); // Black
  768. lprgb[7] = RGBQ(rgbFace); // lt gray
  769. lprgb[8] = RGBQ(rgbShadow); // gray
  770. lprgb[15] = RGBQ(rgbHighlight); // white
  771. lprgb[11] = RGBQ(rgbWindow); // yellow
  772. lprgb[10] = RGBQ(rgbFrame); // green
  773. hdc = GetDC(NULL);
  774. hbm = CreateDIBitmap(hdc, lpbi, CBM_INIT, (LPVOID)lpb,
  775. (LPBITMAPINFO)lpbi, DIB_RGB_COLORS);
  776. ReleaseDC(NULL, hdc);
  777. UnlockResource(h);
  778. FreeResource(h);
  779. return(hbm);
  780. }// LoadUIBitmap