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.

233 lines
6.0 KiB

  1. /*++
  2. Copyright (C) 1997-2001 Microsoft Corporation
  3. Module Name:
  4. Abstract:
  5. History:
  6. --*/
  7. // ToolBarEx.cpp : implementation file
  8. //
  9. #include "stdafx.h"
  10. #include "wmitest.h"
  11. #include "ToolBarEx.h"
  12. #include <AFXISAPI.H>
  13. #ifdef _DEBUG
  14. #define new DEBUG_NEW
  15. #undef THIS_FILE
  16. static char THIS_FILE[] = __FILE__;
  17. #endif
  18. /////////////////////////////////////////////////////////////////////////////
  19. // CToolBarEx
  20. CToolBarEx::CToolBarEx()
  21. {
  22. }
  23. CToolBarEx::~CToolBarEx()
  24. {
  25. }
  26. BEGIN_MESSAGE_MAP(CToolBarEx, CToolBar)
  27. //{{AFX_MSG_MAP(CToolBarEx)
  28. // NOTE - the ClassWizard will add and remove mapping macros here.
  29. //}}AFX_MSG_MAP
  30. END_MESSAGE_MAP()
  31. //////////////////////////////////////////////////////////////////////////////
  32. // Lifted from Bartool.cpp.
  33. #define RGB_TO_RGBQUAD(r,g,b) (RGB(b,g,r))
  34. #define CLR_TO_RGBQUAD(clr) (RGB(GetBValue(clr), GetGValue(clr), GetRValue(clr)))
  35. struct AFX_COLORMAP
  36. {
  37. // use DWORD instead of RGBQUAD so we can compare two RGBQUADs easily
  38. DWORD rgbqFrom;
  39. int iSysColorTo;
  40. };
  41. const AFX_COLORMAP _afxSysColorMap[] =
  42. {
  43. // mapping from color in DIB to system color
  44. //{ RGB_TO_RGBQUAD(0x00, 0x00, 0x00), COLOR_BTNTEXT }, // black
  45. //{ RGB_TO_RGBQUAD(0x80, 0x80, 0x80), COLOR_BTNSHADOW }, // dark gray
  46. { RGB_TO_RGBQUAD(0xC0, 0xC0, 0xC0), COLOR_BTNFACE }, // bright gray
  47. //{ RGB_TO_RGBQUAD(0xFF, 0xFF, 0xFF), COLOR_BTNHIGHLIGHT } // white
  48. };
  49. HBITMAP AFXAPI AfxLoadSysColorBitmapEx(HINSTANCE hInst, HRSRC hRsrc, BOOL bMono = FALSE);
  50. #ifndef _countof
  51. #define _countof(x) (sizeof(x)/sizeof(x[0]))
  52. #endif
  53. HBITMAP AFXAPI
  54. AfxLoadSysColorBitmapEx(HINSTANCE hInst, HRSRC hRsrc, BOOL bMono)
  55. {
  56. HGLOBAL hglb;
  57. if ((hglb = LoadResource(hInst, hRsrc)) == NULL)
  58. return NULL;
  59. LPBITMAPINFOHEADER lpBitmap = (LPBITMAPINFOHEADER)LockResource(hglb);
  60. if (lpBitmap == NULL)
  61. return NULL;
  62. // make copy of BITMAPINFOHEADER so we can modify the color table
  63. const int nColorTableSize = 16;
  64. UINT nSize = lpBitmap->biSize + nColorTableSize * sizeof(RGBQUAD);
  65. LPBITMAPINFOHEADER lpBitmapInfo = (LPBITMAPINFOHEADER)::malloc(nSize);
  66. if (lpBitmapInfo == NULL)
  67. return NULL;
  68. memcpy(lpBitmapInfo, lpBitmap, nSize);
  69. // color table is in RGBQUAD DIB format
  70. DWORD* pColorTable =
  71. (DWORD*)(((LPBYTE)lpBitmapInfo) + (UINT)lpBitmapInfo->biSize);
  72. for (int iColor = 0; iColor < nColorTableSize; iColor++)
  73. {
  74. // look for matching RGBQUAD color in original
  75. for (int i = 0; i < _countof(_afxSysColorMap); i++)
  76. {
  77. if (pColorTable[iColor] == _afxSysColorMap[i].rgbqFrom)
  78. {
  79. if (bMono)
  80. {
  81. // all colors except text become white
  82. if (_afxSysColorMap[i].iSysColorTo != COLOR_BTNTEXT)
  83. pColorTable[iColor] = RGB_TO_RGBQUAD(255, 255, 255);
  84. }
  85. else
  86. pColorTable[iColor] =
  87. CLR_TO_RGBQUAD(::GetSysColor(_afxSysColorMap[i].iSysColorTo));
  88. break;
  89. }
  90. }
  91. }
  92. int nWidth = (int)lpBitmapInfo->biWidth;
  93. int nHeight = (int)lpBitmapInfo->biHeight;
  94. HDC hDCScreen = ::GetDC(NULL);
  95. HBITMAP hbm = ::CreateCompatibleBitmap(hDCScreen, nWidth, nHeight);
  96. if (hbm != NULL)
  97. {
  98. HDC hDCGlyphs = ::CreateCompatibleDC(hDCScreen);
  99. HBITMAP hbmOld = (HBITMAP)::SelectObject(hDCGlyphs, hbm);
  100. LPBYTE lpBits;
  101. lpBits = (LPBYTE)(lpBitmap + 1);
  102. lpBits += (1 << (lpBitmapInfo->biBitCount)) * sizeof(RGBQUAD);
  103. StretchDIBits(hDCGlyphs, 0, 0, nWidth, nHeight, 0, 0, nWidth, nHeight,
  104. lpBits, (LPBITMAPINFO)lpBitmapInfo, DIB_RGB_COLORS, SRCCOPY);
  105. SelectObject(hDCGlyphs, hbmOld);
  106. ::DeleteDC(hDCGlyphs);
  107. }
  108. ::ReleaseDC(NULL, hDCScreen);
  109. // free copy of bitmap info struct and resource itself
  110. ::free(lpBitmapInfo);
  111. ::FreeResource(hglb);
  112. return hbm;
  113. }
  114. //////////////////////////////////////////////////////////////////////////////
  115. // Lifted from Bartool.cpp. The only thing we changed was LoadBitmap to
  116. // LoadBitmapEx.
  117. struct CToolBarData
  118. {
  119. WORD wVersion;
  120. WORD wWidth;
  121. WORD wHeight;
  122. WORD wItemCount;
  123. //WORD aItems[wItemCount]
  124. WORD* items()
  125. { return (WORD*)(this+1); }
  126. };
  127. BOOL CToolBarEx::LoadToolBarEx(LPCTSTR lpszResourceName)
  128. {
  129. ASSERT_VALID(this);
  130. ASSERT(lpszResourceName != NULL);
  131. // determine location of the bitmap in resource fork
  132. HINSTANCE hInst = AfxFindResourceHandle(lpszResourceName, RT_TOOLBAR);
  133. HRSRC hRsrc = ::FindResource(hInst, lpszResourceName, RT_TOOLBAR);
  134. if (hRsrc == NULL)
  135. return FALSE;
  136. HGLOBAL hGlobal = LoadResource(hInst, hRsrc);
  137. if (hGlobal == NULL)
  138. return FALSE;
  139. CToolBarData* pData = (CToolBarData*)LockResource(hGlobal);
  140. if (pData == NULL)
  141. return FALSE;
  142. ASSERT(pData->wVersion == 1);
  143. UINT* pItems = new UINT[pData->wItemCount];
  144. for (int i = 0; i < pData->wItemCount; i++)
  145. pItems[i] = pData->items()[i];
  146. BOOL bResult = SetButtons(pItems, pData->wItemCount);
  147. delete[] pItems;
  148. if (bResult)
  149. {
  150. // set new sizes of the buttons
  151. CSize sizeImage(pData->wWidth, pData->wHeight);
  152. CSize sizeButton(pData->wWidth + 7, pData->wHeight + 7);
  153. SetSizes(sizeButton, sizeImage);
  154. // load bitmap now that sizes are known by the toolbar control
  155. bResult = LoadBitmapEx(lpszResourceName);
  156. }
  157. UnlockResource(hGlobal);
  158. FreeResource(hGlobal);
  159. return bResult;
  160. }
  161. //////////////////////////////////////////////////////////////////////////////
  162. // Lifted from Bartool.cpp. The only thing we changed was AfxLoadSysColorBitmap to
  163. // AfxLoadSysColorBitmapEx.
  164. BOOL CToolBarEx::LoadBitmapEx(LPCTSTR lpszResourceName)
  165. {
  166. ASSERT_VALID(this);
  167. ASSERT(lpszResourceName != NULL);
  168. // determine location of the bitmap in resource fork
  169. HINSTANCE hInstImageWell = AfxFindResourceHandle(lpszResourceName, RT_BITMAP);
  170. HRSRC hRsrcImageWell = ::FindResource(hInstImageWell, lpszResourceName, RT_BITMAP);
  171. if (hRsrcImageWell == NULL)
  172. return FALSE;
  173. // load the bitmap
  174. HBITMAP hbmImageWell;
  175. hbmImageWell = AfxLoadSysColorBitmapEx(hInstImageWell, hRsrcImageWell);
  176. // tell common control toolbar about the new bitmap
  177. if (!AddReplaceBitmap(hbmImageWell))
  178. return FALSE;
  179. // remember the resource handles so the bitmap can be recolored if necessary
  180. m_hInstImageWell = hInstImageWell;
  181. m_hRsrcImageWell = hRsrcImageWell;
  182. return TRUE;
  183. }
  184. /////////////////////////////////////////////////////////////////////////////
  185. // CToolBarEx message handlers