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.

315 lines
6.7 KiB

  1. /*
  2. ** CUTILS.C
  3. **
  4. ** Common utilities for common controls
  5. **
  6. */
  7. #include "ctlspriv.h"
  8. int iDitherCount = 0;
  9. HBRUSH hbrDither = NULL;
  10. int nSysColorChanges = 0;
  11. DWORD rgbFace; // globals used a lot
  12. DWORD rgbShadow;
  13. DWORD rgbHilight;
  14. DWORD rgbFrame;
  15. int iThumbCount = 0;
  16. HBITMAP hbmThumb = NULL; // the thumb bitmap
  17. #define CCS_ALIGN (CCS_TOP|CCS_NOMOVEY|CCS_BOTTOM)
  18. #if 0
  19. /* Note that the default alignment is CCS_BOTTOM
  20. */
  21. void FAR PASCAL NewSize(HWND hWnd, int nHeight, LONG style, int left, int top, int width, int height)
  22. {
  23. RECT rc, rcWindow, rcBorder;
  24. /* Resize the window unless the user said not to
  25. */
  26. if (!(style & CCS_NORESIZE))
  27. {
  28. /* Calculate the borders around the client area of the status bar
  29. */
  30. GetWindowRect(hWnd, &rcWindow);
  31. rcWindow.right -= rcWindow.left;
  32. rcWindow.bottom -= rcWindow.top;
  33. GetClientRect(hWnd, &rc);
  34. ClientToScreen(hWnd, (LPPOINT)&rc);
  35. rcBorder.left = rc.left - rcWindow.left;
  36. rcBorder.top = rc.top - rcWindow.top ;
  37. rcBorder.right = rcWindow.right - rc.right - rcBorder.left;
  38. rcBorder.bottom = rcWindow.bottom - rc.bottom - rcBorder.top ;
  39. nHeight += rcBorder.top + rcBorder.bottom;
  40. /* Check whether to align to the parent window
  41. */
  42. if (style & CCS_NOPARENTALIGN)
  43. {
  44. /* Check out whether this bar is top aligned or bottom aligned
  45. */
  46. switch ((style&CCS_ALIGN))
  47. {
  48. case CCS_TOP:
  49. case CCS_NOMOVEY:
  50. break;
  51. default:
  52. top = top + height - nHeight;
  53. }
  54. }
  55. else
  56. {
  57. /* It is assumed there is a parent by default
  58. */
  59. GetClientRect(GetParent(hWnd), &rc);
  60. /* Don't forget to account for the borders
  61. */
  62. left = -rcBorder.left;
  63. width = rc.right + rcBorder.left + rcBorder.right;
  64. if ((style&CCS_ALIGN) == CCS_TOP)
  65. top = -rcBorder.top;
  66. else if ((style&CCS_ALIGN) != CCS_NOMOVEY)
  67. top = rc.bottom - nHeight + rcBorder.bottom;
  68. }
  69. if (!(GetWindowLong(hWnd, GWL_STYLE) & CCS_NODIVIDER))
  70. {
  71. // make room for divider
  72. top += 2 * GetSystemMetrics(SM_CYBORDER);
  73. }
  74. SetWindowPos(hWnd, NULL, left, top, width, nHeight, SWP_NOZORDER);
  75. }
  76. }
  77. #endif
  78. static HBITMAP NEAR PASCAL CreateDitherBitmap()
  79. {
  80. PBITMAPINFO pbmi;
  81. HBITMAP hbm;
  82. HDC hdc;
  83. int i;
  84. long patGray[8];
  85. DWORD rgb;
  86. pbmi = (PBITMAPINFO)LocalAlloc(LPTR, sizeof(BITMAPINFOHEADER) + (sizeof(RGBQUAD) * 16));
  87. if (!pbmi)
  88. return NULL;
  89. pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
  90. pbmi->bmiHeader.biWidth = 8;
  91. pbmi->bmiHeader.biHeight = 8;
  92. pbmi->bmiHeader.biPlanes = 1;
  93. pbmi->bmiHeader.biBitCount = 1;
  94. pbmi->bmiHeader.biCompression = BI_RGB;
  95. rgb = GetSysColor(COLOR_BTNFACE);
  96. pbmi->bmiColors[0].rgbBlue = GetBValue(rgb);
  97. pbmi->bmiColors[0].rgbGreen = GetGValue(rgb);
  98. pbmi->bmiColors[0].rgbRed = GetRValue(rgb);
  99. pbmi->bmiColors[0].rgbReserved = 0;
  100. rgb = GetSysColor(COLOR_BTNHIGHLIGHT);
  101. pbmi->bmiColors[1].rgbBlue = GetBValue(rgb);
  102. pbmi->bmiColors[1].rgbGreen = GetGValue(rgb);
  103. pbmi->bmiColors[1].rgbRed = GetRValue(rgb);
  104. pbmi->bmiColors[1].rgbReserved = 0;
  105. /* initialize the brushes */
  106. for (i = 0; i < 8; i++)
  107. if (i & 1)
  108. patGray[i] = 0xAAAA5555L; // 0x11114444L; // lighter gray
  109. else
  110. patGray[i] = 0x5555AAAAL; // 0x11114444L; // lighter gray
  111. hdc = GetDC(NULL);
  112. hbm = CreateDIBitmap(hdc, &pbmi->bmiHeader, CBM_INIT, patGray, pbmi, DIB_RGB_COLORS);
  113. ReleaseDC(NULL, hdc);
  114. LocalFree(pbmi);
  115. return hbm;
  116. }
  117. /*---------------------------------------------------------------------------
  118. MySetObjectOwner
  119. Purpose: Call SetObjectOwner in GDI, eliminating "<Object> not released"
  120. error messages when an app terminates.
  121. Returns: Yep
  122. ---------------------------------------------------------------------------*/
  123. static void MySetObjectOwner(HANDLE hObject)
  124. {
  125. VOID (FAR PASCAL *lpSetObjOwner)(HANDLE, HANDLE);
  126. HMODULE hMod;
  127. hMod = GetModuleHandle("GDI");
  128. if (hMod)
  129. {
  130. (FARPROC)lpSetObjOwner = GetProcAddress(hMod, MAKEINTRESOURCE(461));
  131. if (lpSetObjOwner)
  132. {
  133. (lpSetObjOwner)(hObject, hInst);
  134. }
  135. }
  136. }
  137. // initialize the hbrDither global brush
  138. // Call this with bIgnoreCount == TRUE if you just want to update the
  139. // current dither brush.
  140. BOOL FAR PASCAL CreateDitherBrush(BOOL bIgnoreCount)
  141. {
  142. HBITMAP hbmGray;
  143. HBRUSH hbrSave;
  144. if (bIgnoreCount && !iDitherCount)
  145. {
  146. return TRUE;
  147. }
  148. if (iDitherCount>0 && !bIgnoreCount)
  149. {
  150. iDitherCount++;
  151. return TRUE;
  152. }
  153. hbmGray = CreateDitherBitmap();
  154. if (hbmGray)
  155. {
  156. hbrSave = hbrDither;
  157. hbrDither = CreatePatternBrush(hbmGray);
  158. DeleteObject(hbmGray);
  159. if (hbrDither)
  160. {
  161. MySetObjectOwner(hbrDither);
  162. if (hbrSave)
  163. {
  164. DeleteObject(hbrSave);
  165. }
  166. if (!bIgnoreCount)
  167. {
  168. iDitherCount = 1;
  169. }
  170. return TRUE;
  171. }
  172. else
  173. {
  174. hbrDither = hbrSave;
  175. }
  176. }
  177. return FALSE;
  178. }
  179. BOOL FAR PASCAL FreeDitherBrush(void)
  180. {
  181. iDitherCount--;
  182. if (iDitherCount > 0)
  183. return FALSE;
  184. if (hbrDither)
  185. DeleteObject(hbrDither);
  186. hbrDither = NULL;
  187. return TRUE;
  188. }
  189. // initialize the hbmThumb global bitmap
  190. // Call this with bIgnoreCount == TRUE if you just want to update the
  191. // current bitmap.
  192. void FAR PASCAL CreateThumb(BOOL bIgnoreCount)
  193. {
  194. HBITMAP hbmSave;
  195. if (bIgnoreCount && !iThumbCount)
  196. {
  197. return;
  198. }
  199. if (iThumbCount && !bIgnoreCount)
  200. {
  201. ++iThumbCount;
  202. return;
  203. }
  204. hbmSave = hbmThumb;
  205. hbmThumb = CreateMappedBitmap(hInst, IDB_THUMB, CMB_MASKED, NULL, 0);
  206. if (hbmThumb)
  207. {
  208. if (hbmSave)
  209. {
  210. DeleteObject(hbmSave);
  211. }
  212. if (!bIgnoreCount)
  213. {
  214. iThumbCount = 1;
  215. }
  216. }
  217. else
  218. {
  219. hbmThumb = hbmSave;
  220. }
  221. }
  222. void FAR PASCAL DestroyThumb(void)
  223. {
  224. iThumbCount--;
  225. if (iThumbCount <= 0)
  226. {
  227. if (hbmThumb)
  228. {
  229. DeleteObject(hbmThumb);
  230. }
  231. hbmThumb = NULL;
  232. iThumbCount = 0;
  233. }
  234. }
  235. // Note that the trackbar will pass in NULL for pTBState, because it
  236. // just wants the dither brush to be updated.
  237. void FAR PASCAL CheckSysColors(void)
  238. {
  239. static COLORREF rgbSaveFace = 0xffffffffL,
  240. rgbSaveShadow = 0xffffffffL,
  241. rgbSaveHilight = 0xffffffffL,
  242. rgbSaveFrame = 0xffffffffL;
  243. rgbFace = GetSysColor(COLOR_BTNFACE);
  244. rgbShadow = GetSysColor(COLOR_BTNSHADOW);
  245. rgbHilight = GetSysColor(COLOR_BTNHIGHLIGHT);
  246. rgbFrame = GetSysColor(COLOR_WINDOWFRAME);
  247. if (rgbSaveFace!=rgbFace || rgbSaveShadow!=rgbShadow
  248. || rgbSaveHilight!=rgbHilight || rgbSaveFrame!=rgbFrame)
  249. {
  250. ++nSysColorChanges;
  251. // Update the brush for pushed-in buttons
  252. CreateDitherBrush(TRUE);
  253. CreateThumb(TRUE);
  254. rgbSaveFace = rgbFace;
  255. rgbSaveShadow = rgbShadow;
  256. rgbSaveHilight = rgbHilight;
  257. rgbSaveFrame = rgbFrame;
  258. }
  259. }