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.

858 lines
27 KiB

  1. /*****************************************************************************\
  2. FILE: PreviewSM.cpp
  3. DESCRIPTION:
  4. This code will display a preview of system metrics.
  5. NOTE: This code will >hand< draw all the window controls, so if
  6. windows changes the way the windows controls are draw, this code
  7. needs to be manually updated. This is an issue for skinning.
  8. ??????? ?/??/1993 Created
  9. BryanSt 3/23/2000 Updated and Converted to C++
  10. Copyright (C) Microsoft Corp 1993-2000. All rights reserved.
  11. \*****************************************************************************/
  12. #include "priv.h"
  13. #include "PreviewSM.h"
  14. #include "AdvAppearPg.h"
  15. #define RCZ(element) g_elements[element].rc
  16. TCHAR g_szActive[CCH_MAX_STRING];
  17. TCHAR g_szInactive[CCH_MAX_STRING];
  18. TCHAR g_szMinimized[CCH_MAX_STRING];
  19. TCHAR g_szIconTitle[CCH_MAX_STRING];
  20. TCHAR g_szNormal[CCH_MAX_STRING];
  21. TCHAR g_szDisabled[CCH_MAX_STRING];
  22. TCHAR g_szSelected[CCH_MAX_STRING];
  23. TCHAR g_szMsgBox[CCH_MAX_STRING];
  24. TCHAR g_szButton[CCH_MAX_STRING];
  25. TCHAR g_szWindowText[CCH_MAX_STRING];
  26. TCHAR g_szMsgBoxText[CCH_MAX_STRING];
  27. TCHAR g_szABC[] = TEXT("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz");
  28. int cxSize;
  29. HMENU g_hmenuSample;
  30. HBITMAP g_hbmLook = NULL; // bitmap for the appearance preview
  31. int g_nBitsPixel = 0; // bits pizel for the appearance preview
  32. HDC g_hdcMem;
  33. HBITMAP g_hbmDefault;
  34. BOOL g_bMirroredOS = FALSE;
  35. int cyBorder;
  36. int cxBorder;
  37. int cyEdge;
  38. int cxEdge;
  39. //===========================
  40. // *** Class Internals & Helpers ***
  41. //===========================
  42. // Note that the rectangles are defined back to front. So we walk through
  43. // the list backwards, checking PtInRect() until we find a match.
  44. int LookPrev_HitTest(POINT pt)
  45. {
  46. int i;
  47. // start with last, don't bother with 0 (desktop)... it's the fallback
  48. for (i = NUM_ELEMENTS - 1; i > 0; i--)
  49. {
  50. if (PtInRect(&RCZ(i), pt))
  51. {
  52. break;
  53. }
  54. }
  55. // if the chosen one is really a dupe of another, use the base one
  56. if (g_elements[i].iBaseElement != -1)
  57. {
  58. i = g_elements[i].iBaseElement;
  59. }
  60. return i;
  61. }
  62. HRESULT CAdvAppearancePage::_OnNCCreate(HWND hWnd)
  63. {
  64. DWORD dwWindowStyles = GetWindowLong(hWnd, GWL_STYLE);
  65. SetWindowLong(hWnd, GWL_STYLE, dwWindowStyles | WS_BORDER);
  66. dwWindowStyles = GetWindowLong(hWnd,GWL_EXSTYLE);
  67. SetWindowLong(hWnd, GWL_EXSTYLE, dwWindowStyles | WS_EX_CLIENTEDGE);
  68. return S_OK;
  69. }
  70. HRESULT CAdvAppearancePage::_OnCreatePreviewSMDlg(LPRECT prc, BOOL fRTL)
  71. {
  72. cyBorder = ClassicGetSystemMetrics(SM_CYBORDER);
  73. cxBorder = ClassicGetSystemMetrics(SM_CXBORDER);
  74. cyEdge = ClassicGetSystemMetrics(SM_CXEDGE);
  75. cxEdge = ClassicGetSystemMetrics(SM_CYEDGE);
  76. _InitPreview(prc, fRTL);
  77. return S_OK;
  78. }
  79. // ----------------------------------------------------------------------------
  80. // create the preview bitmap and collect all of the global, non-changing data
  81. // ----------------------------------------------------------------------------
  82. void CAdvAppearancePage::_InitPreview(LPRECT prc, BOOL fRTL)
  83. {
  84. RECT rc;
  85. HDC hdc;
  86. rc = *prc;
  87. hdc = GetDC(NULL);
  88. g_nBitsPixel = GetDeviceCaps(hdc, BITSPIXEL);
  89. g_hbmLook = CreateCompatibleBitmap(hdc, rc.right - rc.left, rc.bottom - rc.top);
  90. ReleaseDC(NULL, hdc);
  91. // Load our display strings.
  92. LoadString(HINST_THISDLL, IDS_ACTIVE, g_szActive, ARRAYSIZE(g_szActive));
  93. LoadString(HINST_THISDLL, IDS_INACTIVE, g_szInactive, ARRAYSIZE(g_szInactive));
  94. LoadString(HINST_THISDLL, IDS_MINIMIZED, g_szMinimized, ARRAYSIZE(g_szMinimized));
  95. LoadString(HINST_THISDLL, IDS_ICONTITLE, g_szIconTitle, ARRAYSIZE(g_szIconTitle));
  96. LoadString(HINST_THISDLL, IDS_NORMAL, g_szNormal, ARRAYSIZE(g_szNormal));
  97. LoadString(HINST_THISDLL, IDS_DISABLED, g_szDisabled, ARRAYSIZE(g_szDisabled));
  98. LoadString(HINST_THISDLL, IDS_SELECTED, g_szSelected, ARRAYSIZE(g_szSelected));
  99. LoadString(HINST_THISDLL, IDS_MSGBOX, g_szMsgBox, ARRAYSIZE(g_szMsgBox));
  100. LoadString(HINST_THISDLL, IDS_BUTTONTEXT, g_szButton, ARRAYSIZE(g_szButton));
  101. LoadString(HINST_THISDLL, IDS_WINDOWTEXT, g_szWindowText, ARRAYSIZE(g_szWindowText));
  102. LoadString(HINST_THISDLL, IDS_MSGBOXTEXT, g_szMsgBoxText, ARRAYSIZE(g_szMsgBoxText));
  103. // load up and
  104. g_hmenuSample = LoadMenu(HINST_THISDLL, MAKEINTRESOURCE(IDR_MENU));
  105. EnableMenuItem(g_hmenuSample, IDM_DISABLED, MF_GRAYED | MF_BYCOMMAND);
  106. if (fRTL) {
  107. SET_DC_RTL_MIRRORED(g_hdcMem);
  108. }
  109. }
  110. HRESULT CAdvAppearancePage::_OnDestroyPreview(HWND hWnd)
  111. {
  112. if (g_hbmLook)
  113. {
  114. DeleteObject(g_hbmLook);
  115. g_hbmLook = NULL;
  116. }
  117. if (g_hmenuSample)
  118. {
  119. DestroyMenu(g_hmenuSample);
  120. g_hmenuSample = NULL;
  121. }
  122. return S_OK;
  123. }
  124. HRESULT CAdvAppearancePage::_OnPaintPreview(HWND hWnd)
  125. {
  126. PAINTSTRUCT ps;
  127. BeginPaint(hWnd, &ps);
  128. RECT rc;
  129. GetClientRect(hWnd, &rc);
  130. if (g_hbmLook)
  131. _ShowBitmap(hWnd, ps.hdc);
  132. else
  133. _DrawPreview(ps.hdc, &rc, FALSE, TRUE);
  134. EndPaint(hWnd, &ps);
  135. return S_OK;
  136. }
  137. HRESULT CAdvAppearancePage::_OnReCreateBitmap(HWND hWnd)
  138. {
  139. if (g_hbmLook)
  140. {
  141. HDC hdc = GetDC(NULL);
  142. if (g_nBitsPixel != GetDeviceCaps(hdc, BITSPIXEL))
  143. {
  144. DeleteObject(g_hbmLook);
  145. g_hbmLook = NULL;
  146. RECT rc;
  147. GetClientRect(hWnd, &rc);
  148. _InitPreview(&rc, IS_WINDOW_RTL_MIRRORED(hWnd));
  149. _RepaintPreview(hWnd);
  150. }
  151. ReleaseDC(NULL, hdc);
  152. }
  153. return S_OK;
  154. }
  155. HRESULT CAdvAppearancePage::_OnButtonDownOrDblClick(HWND hWnd, int nCoordX, int nCoordY)
  156. {
  157. POINT pt;
  158. pt.x = nCoordX; // horizontal position of cursor
  159. pt.y = nCoordY; // vertical position of cursor
  160. int nElementIndex = LookPrev_HitTest(pt);
  161. return _SelectElement(hWnd, nElementIndex, LSE_SETCUR);
  162. }
  163. LRESULT CALLBACK CAdvAppearancePage::PreviewSystemMetricsWndProc(HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam)
  164. {
  165. CAdvAppearancePage * pThis = (CAdvAppearancePage *)GetWindowLongPtr(hWnd, GWLP_USERDATA);
  166. if (!pThis && (WM_NCDESTROY != wMsg))
  167. {
  168. AssertMsg((NULL != g_pAdvAppearancePage), TEXT("We need this or the dlg doesn't work at all. -BryanSt"));
  169. if (g_pAdvAppearancePage)
  170. {
  171. SetWindowLongPtr(hWnd, GWLP_USERDATA, (LONG_PTR)g_pAdvAppearancePage);
  172. pThis = (CAdvAppearancePage *)g_pAdvAppearancePage;
  173. }
  174. }
  175. if (pThis)
  176. return pThis->_PreviewSystemMetricsWndProc(hWnd, wMsg, wParam, lParam);
  177. return DefWindowProc(hWnd, wMsg, wParam, lParam);
  178. }
  179. // This Property Sheet appear in the top level of the "Display Control Panel".
  180. LRESULT CAdvAppearancePage::_PreviewSystemMetricsWndProc(HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam)
  181. {
  182. LRESULT lReturnValue = TRUE;
  183. BOOL fCallWndProc = TRUE;
  184. switch(wMsg)
  185. {
  186. case WM_NCCREATE:
  187. _OnNCCreate(hWnd);
  188. fCallWndProc = FALSE;
  189. break;
  190. case WM_CREATE:
  191. {
  192. RECT rc;
  193. GetClientRect(hWnd, &rc);
  194. _OnCreatePreviewSMDlg(&rc, IS_WINDOW_RTL_MIRRORED(hWnd));
  195. }
  196. break;
  197. case WM_DESTROY:
  198. _OnDestroyPreview(hWnd);
  199. break;
  200. case WM_PALETTECHANGED:
  201. if ((HWND)wParam == hWnd)
  202. break;
  203. //fallthru
  204. case WM_QUERYNEWPALETTE:
  205. if (m_hpal3D)
  206. InvalidateRect(hWnd, NULL, FALSE);
  207. break;
  208. case WM_LBUTTONDOWN:
  209. case WM_LBUTTONDBLCLK:
  210. _OnButtonDownOrDblClick(GetParent(hWnd), LOWORD(lParam), HIWORD(lParam));
  211. break;
  212. case WM_RECREATEBITMAP:
  213. _OnReCreateBitmap(hWnd);
  214. break;
  215. case WM_SIZE: // right mouse click
  216. break;
  217. case WM_PAINT:
  218. _OnPaintPreview(hWnd);
  219. break;
  220. }
  221. if (fCallWndProc)
  222. {
  223. lReturnValue = DefWindowProc(hWnd, wMsg, wParam, lParam);
  224. }
  225. return lReturnValue;
  226. }
  227. // ----------------------------------------------------------------------------
  228. // calculate all of the rectangles based on the given window rect
  229. // ----------------------------------------------------------------------------
  230. void CAdvAppearancePage::_Recalc(LPRECT prc)
  231. {
  232. DWORD cxNormal;
  233. int cxDisabled, cxSelected;
  234. int cxAvgCharx2;
  235. RECT rc;
  236. HFONT hfontT;
  237. int cxFrame, cyFrame;
  238. int cyCaption;
  239. int i;
  240. SIZE sizButton;
  241. rc = *prc;
  242. // Get our drawing data
  243. cxSize = ClassicGetSystemMetrics(SM_CXSIZE);
  244. cxFrame = (m_sizes[SIZE_FRAME].CurSize + 1) * m_cxBorderSM + m_cxEdgeSM;
  245. cyFrame = (m_sizes[SIZE_FRAME].CurSize + 1) * m_cyBorderSM + m_cyEdgeSM;
  246. cyCaption = m_sizes[SIZE_CAPTION].CurSize;
  247. // Get text dimensions, with proper font.
  248. hfontT = (HFONT) SelectObject(g_hdcMem, m_fonts[FONT_MENU].hfont);
  249. GetTextExtentPoint32(g_hdcMem, g_szNormal, lstrlen(g_szNormal), &sizButton);
  250. cxNormal = sizButton.cx;
  251. GetTextExtentPoint32(g_hdcMem, g_szDisabled, lstrlen(g_szDisabled), &sizButton);
  252. cxDisabled = sizButton.cx;
  253. GetTextExtentPoint32(g_hdcMem, g_szSelected, lstrlen(g_szSelected), &sizButton);
  254. cxSelected = sizButton.cx;
  255. // get the average width (USER style) of menu font
  256. GetTextExtentPoint32(g_hdcMem, g_szABC, 52, &sizButton);
  257. cxAvgCharx2 = 2 * (sizButton.cx / 52);
  258. // actual menu-handling widths of strings is bigger
  259. cxDisabled += cxAvgCharx2;
  260. cxSelected += cxAvgCharx2;
  261. cxNormal += cxAvgCharx2;
  262. SelectObject(g_hdcMem, hfontT);
  263. GetTextExtentPoint32(g_hdcMem, g_szButton, lstrlen(g_szButton), &sizButton);
  264. // Desktop
  265. RCZ(ELEMENT_DESKTOP) = rc;
  266. InflateRect(&rc, -8*m_cxBorderSM, -8*m_cyBorderSM);
  267. // Windows
  268. rc.bottom -= cyFrame + cyCaption;
  269. RCZ(ELEMENT_ACTIVEBORDER) = rc;
  270. OffsetRect(&RCZ(ELEMENT_ACTIVEBORDER), cxFrame,
  271. cyFrame + cyCaption + m_cyBorderSM);
  272. RCZ(ELEMENT_ACTIVEBORDER).bottom -= cyCaption;
  273. // Inactive window
  274. rc.right -= cyCaption;
  275. RCZ(ELEMENT_INACTIVEBORDER) = rc;
  276. // Caption
  277. InflateRect(&rc, -cxFrame, -cyFrame);
  278. rc.bottom = rc.top + cyCaption + m_cyBorderSM;
  279. RCZ(ELEMENT_INACTIVECAPTION) = rc;
  280. // close button
  281. InflateRect(&rc, -m_cxEdgeSM, -m_cyEdgeSM);
  282. rc.bottom -= m_cyBorderSM; // compensate for magic line under caption
  283. RCZ(ELEMENT_INACTIVESYSBUT1) = rc;
  284. RCZ(ELEMENT_INACTIVESYSBUT1).left = rc.right - (cyCaption - m_cxEdgeSM);
  285. // min/max buttons
  286. RCZ(ELEMENT_INACTIVESYSBUT2) = rc;
  287. RCZ(ELEMENT_INACTIVESYSBUT2).right = RCZ(ELEMENT_INACTIVESYSBUT1).left - m_cxEdgeSM;
  288. RCZ(ELEMENT_INACTIVESYSBUT2).left = RCZ(ELEMENT_INACTIVESYSBUT2).right -
  289. 2 * (cyCaption - m_cxEdgeSM);
  290. // Caption
  291. rc = RCZ(ELEMENT_ACTIVEBORDER);
  292. InflateRect(&rc, -cxFrame, -cyFrame);
  293. RCZ(ELEMENT_ACTIVECAPTION) = rc;
  294. RCZ(ELEMENT_ACTIVECAPTION).bottom =
  295. RCZ(ELEMENT_ACTIVECAPTION).top + cyCaption + m_cyBorderSM;
  296. // close button
  297. RCZ(ELEMENT_ACTIVESYSBUT1) = RCZ(ELEMENT_ACTIVECAPTION);
  298. InflateRect(&RCZ(ELEMENT_ACTIVESYSBUT1), -m_cxEdgeSM, -m_cyEdgeSM);
  299. RCZ(ELEMENT_ACTIVESYSBUT1).bottom -= m_cyBorderSM; // compensate for magic line under caption
  300. RCZ(ELEMENT_ACTIVESYSBUT1).left = RCZ(ELEMENT_ACTIVESYSBUT1).right -
  301. (cyCaption - m_cxEdgeSM);
  302. // min/max buttons
  303. RCZ(ELEMENT_ACTIVESYSBUT2) = RCZ(ELEMENT_ACTIVESYSBUT1);
  304. RCZ(ELEMENT_ACTIVESYSBUT2).right = RCZ(ELEMENT_ACTIVESYSBUT1).left - m_cxEdgeSM;
  305. RCZ(ELEMENT_ACTIVESYSBUT2).left = RCZ(ELEMENT_ACTIVESYSBUT2).right -
  306. 2 * (cyCaption - m_cxEdgeSM);
  307. // Menu
  308. rc.top = RCZ(ELEMENT_ACTIVECAPTION).bottom;
  309. RCZ(ELEMENT_MENUNORMAL) = rc;
  310. rc.top = RCZ(ELEMENT_MENUNORMAL).bottom = RCZ(ELEMENT_MENUNORMAL).top + m_sizes[SIZE_MENU].CurSize;
  311. RCZ(ELEMENT_MENUDISABLED) = RCZ(ELEMENT_MENUSELECTED) = RCZ(ELEMENT_MENUNORMAL);
  312. RCZ(ELEMENT_MENUDISABLED).left = RCZ(ELEMENT_MENUNORMAL).left + cxNormal;
  313. RCZ(ELEMENT_MENUDISABLED).right = RCZ(ELEMENT_MENUSELECTED).left =
  314. RCZ(ELEMENT_MENUDISABLED).left + cxDisabled;
  315. RCZ(ELEMENT_MENUSELECTED).right = RCZ(ELEMENT_MENUSELECTED).left + cxSelected;
  316. // Client
  317. RCZ(ELEMENT_WINDOW) = rc;
  318. // Scrollbar
  319. InflateRect(&rc, -m_cxEdgeSM, -m_cyEdgeSM); // take off client edge
  320. RCZ(ELEMENT_SCROLLBAR) = rc;
  321. rc.right = RCZ(ELEMENT_SCROLLBAR).left = rc.right - m_sizes[SIZE_SCROLL].CurSize;
  322. RCZ(ELEMENT_SCROLLUP) = RCZ(ELEMENT_SCROLLBAR);
  323. RCZ(ELEMENT_SCROLLUP).bottom = RCZ(ELEMENT_SCROLLBAR).top + m_sizes[SIZE_SCROLL].CurSize;
  324. RCZ(ELEMENT_SCROLLDOWN) = RCZ(ELEMENT_SCROLLBAR);
  325. RCZ(ELEMENT_SCROLLDOWN).top = RCZ(ELEMENT_SCROLLBAR).bottom - m_sizes[SIZE_SCROLL].CurSize;
  326. // Message Box
  327. rc.top = RCZ(ELEMENT_WINDOW).top + (RCZ(ELEMENT_WINDOW).bottom - RCZ(ELEMENT_WINDOW).top) / 2;
  328. rc.bottom = RCZ(ELEMENT_DESKTOP).bottom - 2*m_cyEdgeSM;
  329. rc.left = RCZ(ELEMENT_WINDOW).left + 2*m_cyEdgeSM;
  330. rc.right = RCZ(ELEMENT_WINDOW).left + (RCZ(ELEMENT_WINDOW).right - RCZ(ELEMENT_WINDOW).left) / 2 + 3*cyCaption;
  331. RCZ(ELEMENT_MSGBOX) = rc;
  332. // Caption
  333. RCZ(ELEMENT_MSGBOXCAPTION) = rc;
  334. RCZ(ELEMENT_MSGBOXCAPTION).top += m_cyEdgeSM + m_cyBorderSM;
  335. RCZ(ELEMENT_MSGBOXCAPTION).bottom = RCZ(ELEMENT_MSGBOXCAPTION).top + cyCaption + m_cyBorderSM;
  336. RCZ(ELEMENT_MSGBOXCAPTION).left += m_cxEdgeSM + m_cxBorderSM;
  337. RCZ(ELEMENT_MSGBOXCAPTION).right -= m_cxEdgeSM + m_cxBorderSM;
  338. RCZ(ELEMENT_MSGBOXSYSBUT) = RCZ(ELEMENT_MSGBOXCAPTION);
  339. InflateRect(&RCZ(ELEMENT_MSGBOXSYSBUT), -m_cxEdgeSM, -m_cyEdgeSM);
  340. RCZ(ELEMENT_MSGBOXSYSBUT).left = RCZ(ELEMENT_MSGBOXSYSBUT).right -
  341. (cyCaption - m_cxEdgeSM);
  342. RCZ(ELEMENT_MSGBOXSYSBUT).bottom -= m_cyBorderSM; // line under caption
  343. // Button
  344. RCZ(ELEMENT_BUTTON).bottom = RCZ(ELEMENT_MSGBOX).bottom - (4*m_cyBorderSM + m_cyEdgeSM);
  345. RCZ(ELEMENT_BUTTON).top = RCZ(ELEMENT_BUTTON).bottom - (sizButton.cy + 8 * m_cyBorderSM);
  346. i = (RCZ(ELEMENT_BUTTON).bottom - RCZ(ELEMENT_BUTTON).top) * 3;
  347. RCZ(ELEMENT_BUTTON).left = (rc.left + (rc.right - rc.left)/2) - i/2;
  348. RCZ(ELEMENT_BUTTON).right = RCZ(ELEMENT_BUTTON).left + i;
  349. }
  350. // ----------------------------------------------------------------------------
  351. //
  352. // MyDrawFrame() -
  353. //
  354. // Draws bordered frame, border size cl, and adjusts passed in rect.
  355. //
  356. // ----------------------------------------------------------------------------
  357. void MyDrawFrame(HDC hdc, LPRECT prc, HBRUSH hbrColor, int cl)
  358. {
  359. HBRUSH hbr;
  360. int cx, cy;
  361. RECT rcT;
  362. rcT = *prc;
  363. cx = cl * cxBorder;
  364. cy = cl * cyBorder;
  365. hbr = (HBRUSH) SelectObject(hdc, hbrColor);
  366. PatBlt(hdc, rcT.left, rcT.top, cx, rcT.bottom - rcT.top, PATCOPY);
  367. rcT.left += cx;
  368. PatBlt(hdc, rcT.left, rcT.top, rcT.right - rcT.left, cy, PATCOPY);
  369. rcT.top += cy;
  370. rcT.right -= cx;
  371. PatBlt(hdc, rcT.right, rcT.top, cx, rcT.bottom - rcT.top, PATCOPY);
  372. rcT.bottom -= cy;
  373. PatBlt(hdc, rcT.left, rcT.bottom, rcT.right - rcT.left, cy, PATCOPY);
  374. hbr = (HBRUSH) SelectObject(hdc, hbr);
  375. *prc = rcT;
  376. }
  377. /*
  378. ** draw a m_cyBorderSM band of 3DFACE at the bottom of the given rectangle.
  379. ** also, adjust the rectangle accordingly.
  380. */
  381. void CAdvAppearancePage::_MyDrawBorderBelow(HDC hdc, LPRECT prc)
  382. {
  383. int i;
  384. i = prc->top;
  385. prc->top = prc->bottom - m_cyBorderSM;
  386. FillRect(hdc, prc, m_brushes[COLOR_3DFACE]);
  387. prc->top = i;
  388. prc->bottom -= m_cyBorderSM;
  389. }
  390. void CAdvAppearancePage::_ShowBitmap(HWND hWnd, HDC hdc)
  391. {
  392. RECT rc;
  393. HBITMAP hbmOld;
  394. HPALETTE hpalOld = NULL;
  395. if (m_hpal3D)
  396. {
  397. hpalOld = SelectPalette(hdc, m_hpal3D, FALSE);
  398. RealizePalette(hdc);
  399. }
  400. GetClientRect(hWnd, &rc);
  401. hbmOld = (HBITMAP) SelectObject(g_hdcMem, g_hbmLook);
  402. BitBlt(hdc, 0, 0, rc.right - rc.left, rc.bottom - rc.top, g_hdcMem, 0, 0, SRCCOPY);
  403. SelectObject(g_hdcMem, hbmOld);
  404. if (hpalOld)
  405. {
  406. SelectPalette(hdc, hpalOld, FALSE);
  407. RealizePalette(hdc);
  408. }
  409. }
  410. // ----------------------------------------------------------------------------
  411. //
  412. //
  413. // ----------------------------------------------------------------------------
  414. void CAdvAppearancePage::_DrawPreview(HDC hdc, LPRECT prc, BOOL fOnlyShowActiveWindow, BOOL fShowBack)
  415. {
  416. RECT rcT;
  417. int nMode;
  418. DWORD rgbBk;
  419. int cxSize, cySize;
  420. HANDLE hOldColors;
  421. HPALETTE hpalOld = NULL;
  422. HICON hiconLogo;
  423. HFONT hfontOld;
  424. BOOL bGradient = FALSE;
  425. ClassicSystemParametersInfo(SPI_GETGRADIENTCAPTIONS, 0, (PVOID)&bGradient, 0);
  426. SaveDC(hdc);
  427. if (m_hpal3D)
  428. {
  429. hpalOld = SelectPalette(hdc, m_hpal3D, TRUE);
  430. RealizePalette(hdc);
  431. }
  432. hOldColors = SetSysColorsTemp(m_rgb, m_brushes, COLOR_MAX);
  433. hiconLogo = (HICON) LoadImage(NULL, IDI_APPLICATION, IMAGE_ICON,
  434. m_sizes[SIZE_CAPTION].CurSize - 2*m_cxBorderSM,
  435. m_sizes[SIZE_CAPTION].CurSize - 2*m_cyBorderSM, 0);
  436. // Setup drawing stuff
  437. nMode = SetBkMode(hdc, TRANSPARENT);
  438. rgbBk = GetTextColor(hdc);
  439. cxSize = ClassicGetSystemMetrics(SM_CXSIZE);
  440. cySize = ClassicGetSystemMetrics(SM_CYSIZE);
  441. // Desktop
  442. if (fShowBack)
  443. {
  444. FillRect(hdc, &RCZ(ELEMENT_DESKTOP), m_brushes[COLOR_BACKGROUND]);
  445. }
  446. if (!fOnlyShowActiveWindow)
  447. {
  448. // Inactive window
  449. // Border
  450. rcT = RCZ(ELEMENT_INACTIVEBORDER);
  451. DrawEdge(hdc, &rcT, EDGE_RAISED, BF_RECT | BF_ADJUST);
  452. MyDrawFrame(hdc, &rcT, m_brushes[COLOR_INACTIVEBORDER], m_sizes[SIZE_FRAME].CurSize);
  453. MyDrawFrame(hdc, &rcT, m_brushes[COLOR_3DFACE], 1);
  454. // Caption
  455. rcT = RCZ(ELEMENT_INACTIVECAPTION);
  456. _MyDrawBorderBelow(hdc, &rcT);
  457. // NOTE: because USER draws icon stuff using its own DC and subsequently
  458. // its own palette, we need to make sure to use the inactivecaption
  459. // brush before USER does so that it will be realized against our palette.
  460. // this might get fixed in USER by better be safe.
  461. // "clip" the caption title under the buttons
  462. rcT.left = RCZ(ELEMENT_INACTIVESYSBUT2).left - m_cyEdgeSM;
  463. FillRect(hdc, &rcT, m_brushes[bGradient ? COLOR_GRADIENTINACTIVECAPTION : COLOR_INACTIVECAPTION]);
  464. rcT.right = rcT.left;
  465. rcT.left = RCZ(ELEMENT_INACTIVECAPTION).left;
  466. DrawCaptionTemp(NULL, hdc, &rcT, m_fonts[FONT_CAPTION].hfont, hiconLogo, g_szInactive, DC_ICON | DC_TEXT |
  467. (bGradient ? DC_GRADIENT : 0));
  468. DrawFrameControl(hdc, &RCZ(ELEMENT_INACTIVESYSBUT1), DFC_CAPTION, DFCS_CAPTIONCLOSE);
  469. rcT = RCZ(ELEMENT_INACTIVESYSBUT2);
  470. rcT.right -= (rcT.right - rcT.left)/2;
  471. DrawFrameControl(hdc, &rcT, DFC_CAPTION, DFCS_CAPTIONMIN);
  472. rcT.left = rcT.right;
  473. rcT.right = RCZ(ELEMENT_INACTIVESYSBUT2).right;
  474. DrawFrameControl(hdc, &rcT, DFC_CAPTION, DFCS_CAPTIONMAX);
  475. }
  476. // Border
  477. rcT = RCZ(ELEMENT_ACTIVEBORDER);
  478. DrawEdge(hdc, &rcT, EDGE_RAISED, BF_RECT | BF_ADJUST);
  479. MyDrawFrame(hdc, &rcT, m_brushes[COLOR_ACTIVEBORDER], m_sizes[SIZE_FRAME].CurSize);
  480. MyDrawFrame(hdc, &rcT, m_brushes[COLOR_3DFACE], 1);
  481. // Caption
  482. rcT = RCZ(ELEMENT_ACTIVECAPTION);
  483. _MyDrawBorderBelow(hdc, &rcT);
  484. // "clip" the caption title under the buttons
  485. rcT.left = RCZ(ELEMENT_ACTIVESYSBUT2).left - m_cxEdgeSM;
  486. FillRect(hdc, &rcT, m_brushes[bGradient ? COLOR_GRADIENTACTIVECAPTION : COLOR_ACTIVECAPTION]);
  487. rcT.right = rcT.left;
  488. rcT.left = RCZ(ELEMENT_ACTIVECAPTION).left;
  489. DrawCaptionTemp(NULL, hdc, &rcT, m_fonts[FONT_CAPTION].hfont, hiconLogo, g_szActive, DC_ACTIVE | DC_ICON | DC_TEXT |
  490. (bGradient ? DC_GRADIENT : 0));
  491. DrawFrameControl(hdc, &RCZ(ELEMENT_ACTIVESYSBUT1), DFC_CAPTION, DFCS_CAPTIONCLOSE);
  492. rcT = RCZ(ELEMENT_ACTIVESYSBUT2);
  493. rcT.right -= (rcT.right - rcT.left)/2;
  494. DrawFrameControl(hdc, &rcT, DFC_CAPTION, DFCS_CAPTIONMIN);
  495. rcT.left = rcT.right;
  496. rcT.right = RCZ(ELEMENT_ACTIVESYSBUT2).right;
  497. DrawFrameControl(hdc, &rcT, DFC_CAPTION, DFCS_CAPTIONMAX);
  498. // Menu
  499. rcT = RCZ(ELEMENT_MENUNORMAL);
  500. DrawMenuBarTemp(GetDesktopWindow(), hdc, &rcT, g_hmenuSample, m_fonts[FONT_MENU].hfont);
  501. _MyDrawBorderBelow(hdc, &rcT);
  502. // Client area
  503. rcT = RCZ(ELEMENT_WINDOW);
  504. DrawEdge(hdc, &rcT, EDGE_SUNKEN, BF_RECT | BF_ADJUST);
  505. FillRect(hdc, &rcT, m_brushes[COLOR_WINDOW]);
  506. // window text
  507. SetBkMode(hdc, TRANSPARENT);
  508. SetTextColor(hdc, m_rgb[COLOR_WINDOWTEXT]);
  509. hfontOld = (HFONT) SelectObject(hdc, m_fonts[FONT_CAPTION].hfont);
  510. TextOut(hdc, RCZ(ELEMENT_WINDOW).left + 2*m_cxEdgeSM, RCZ(ELEMENT_WINDOW).top + 2*m_cyEdgeSM, g_szWindowText, lstrlen(g_szWindowText));
  511. if (hfontOld)
  512. SelectObject(hdc, hfontOld);
  513. // scroll bar
  514. rcT = RCZ(ELEMENT_SCROLLBAR);
  515. FillRect(hdc, &rcT, m_brushes[COLOR_SCROLLBAR]);
  516. DrawFrameControl(hdc, &RCZ(ELEMENT_SCROLLUP), DFC_SCROLL, DFCS_SCROLLUP);
  517. DrawFrameControl(hdc, &RCZ(ELEMENT_SCROLLDOWN), DFC_SCROLL, DFCS_SCROLLDOWN);
  518. if (!fOnlyShowActiveWindow)
  519. {
  520. // MessageBox
  521. rcT = RCZ(ELEMENT_MSGBOX);
  522. DrawEdge(hdc, &rcT, EDGE_RAISED, BF_RECT | BF_ADJUST);
  523. FillRect(hdc, &rcT, m_brushes[COLOR_3DFACE]);
  524. rcT = RCZ(ELEMENT_MSGBOXCAPTION);
  525. _MyDrawBorderBelow(hdc, &rcT);
  526. // "clip" the caption title under the buttons
  527. rcT.left = RCZ(ELEMENT_MSGBOXSYSBUT).left - m_cxEdgeSM;
  528. FillRect(hdc, &rcT, m_brushes[bGradient ? COLOR_GRADIENTACTIVECAPTION : COLOR_ACTIVECAPTION]);
  529. rcT.right = rcT.left;
  530. rcT.left = RCZ(ELEMENT_MSGBOXCAPTION).left;
  531. DrawCaptionTemp(NULL, hdc, &rcT, m_fonts[FONT_CAPTION].hfont, hiconLogo, g_szMsgBox, DC_ACTIVE | DC_ICON | DC_TEXT |
  532. (bGradient ? DC_GRADIENT : 0));
  533. DrawFrameControl(hdc, &RCZ(ELEMENT_MSGBOXSYSBUT), DFC_CAPTION, DFCS_CAPTIONCLOSE);
  534. // message box text
  535. SetBkMode(hdc, TRANSPARENT);
  536. SetTextColor(hdc, m_rgb[COLOR_WINDOWTEXT]);
  537. hfontOld = (HFONT) SelectObject(hdc, m_fonts[FONT_MSGBOX].hfont);
  538. TextOut(hdc, RCZ(ELEMENT_MSGBOX).left + 3*m_cxEdgeSM, RCZ(ELEMENT_MSGBOXCAPTION).bottom + m_cyEdgeSM,
  539. g_szMsgBoxText, lstrlen(g_szMsgBoxText));
  540. if (hfontOld)
  541. SelectObject(hdc, hfontOld);
  542. // Button
  543. rcT = RCZ(ELEMENT_BUTTON);
  544. DrawFrameControl(hdc, &rcT, DFC_BUTTON, DFCS_BUTTONPUSH);
  545. // ?????? what font should this use ??????
  546. // [msadek]; Pick the same one we use for Messagebox text.(This is what Message Box uses for its buttons)
  547. // else we will be using the font originally selected in the DC (System font)
  548. hfontOld = (HFONT) SelectObject(hdc, m_fonts[FONT_MSGBOX].hfont);
  549. SetBkMode(hdc, TRANSPARENT);
  550. SetTextColor(hdc, m_rgb[COLOR_BTNTEXT]);
  551. DrawText(hdc, g_szButton, -1, &rcT, DT_CENTER | DT_NOPREFIX |
  552. DT_SINGLELINE | DT_VCENTER);
  553. if (hfontOld)
  554. SelectObject(hdc, hfontOld);
  555. }
  556. SetBkColor(hdc, rgbBk);
  557. SetBkMode(hdc, nMode);
  558. if (hiconLogo)
  559. DestroyIcon(hiconLogo);
  560. SetSysColorsTemp(NULL, NULL, (UINT_PTR)hOldColors);
  561. if (hpalOld)
  562. {
  563. hpalOld = SelectPalette(hdc, hpalOld, FALSE);
  564. RealizePalette(hdc);
  565. }
  566. RestoreDC(hdc, -1);
  567. }
  568. void CAdvAppearancePage::_RepaintPreview(HWND hwnd)
  569. {
  570. HBITMAP hbmOld;
  571. if (g_hbmLook)
  572. {
  573. hbmOld = (HBITMAP) SelectObject(g_hdcMem, g_hbmLook);
  574. RECT rc;
  575. GetClientRect(hwnd, &rc);
  576. _DrawPreview(g_hdcMem, &rc, FALSE, TRUE);
  577. SelectObject(g_hdcMem, hbmOld);
  578. }
  579. InvalidateRect(hwnd, NULL, FALSE);
  580. }
  581. BOOL RegisterPreviewSystemMetricClass(HINSTANCE hInst)
  582. {
  583. WNDCLASS wc;
  584. if (!GetClassInfo(hInst, PREVIEWSM_CLASS, &wc))
  585. {
  586. wc.style = 0;
  587. wc.lpfnWndProc = CAdvAppearancePage::PreviewSystemMetricsWndProc;
  588. wc.cbClsExtra = 0;
  589. wc.cbWndExtra = 0;
  590. wc.hInstance = hInst;
  591. wc.hIcon = NULL;
  592. wc.hCursor = LoadCursor(NULL, IDC_ARROW);
  593. wc.hbrBackground = (HBRUSH)(COLOR_3DFACE+1);
  594. wc.lpszMenuName = NULL;
  595. wc.lpszClassName = PREVIEWSM_CLASS;
  596. if (!RegisterClass(&wc))
  597. return FALSE;
  598. }
  599. return TRUE;
  600. }
  601. /*---------------------------------------------------------
  602. **
  603. **---------------------------------------------------------*/
  604. BOOL CreateGlobals(void)
  605. {
  606. HBITMAP hbm;
  607. HDC hdc;
  608. // Check if the mirroring APIs exist on the current
  609. // platform.
  610. g_bMirroredOS = IS_MIRRORING_ENABLED();
  611. if (!g_hdcMem)
  612. {
  613. hdc = GetDC(NULL);
  614. g_hdcMem = CreateCompatibleDC(hdc);
  615. ReleaseDC(NULL, hdc);
  616. }
  617. if (!g_hdcMem)
  618. return FALSE;
  619. if (!g_hbmDefault)
  620. {
  621. hbm = CreateBitmap(1, 1, 1, 1, NULL);
  622. if (hbm)
  623. {
  624. g_hbmDefault = (HBITMAP) SelectObject(g_hdcMem, hbm);
  625. SelectObject(g_hdcMem, g_hbmDefault);
  626. DeleteObject(hbm);
  627. }
  628. }
  629. return TRUE;
  630. }
  631. HRESULT CAdvAppearancePage::Draw(HDC hdc, LPRECT prc, BOOL fOnlyShowActiveWindow, BOOL fRTL)
  632. {
  633. _OnCreatePreviewSMDlg(prc, fRTL);
  634. m_cyBorderSM = ClassicGetSystemMetrics(SM_CYBORDER);
  635. m_cxBorderSM = ClassicGetSystemMetrics(SM_CXBORDER);
  636. m_cxEdgeSM = ClassicGetSystemMetrics(SM_CXEDGE);
  637. m_cyEdgeSM = ClassicGetSystemMetrics(SM_CYEDGE);
  638. _InitSysStuff();
  639. _Recalc(prc);
  640. _DrawPreview(hdc, prc, fOnlyShowActiveWindow, FALSE);
  641. _DestroySysStuff();
  642. if (g_hbmLook)
  643. {
  644. DeleteObject(g_hbmLook);
  645. }
  646. if (g_hmenuSample)
  647. {
  648. DestroyMenu(g_hmenuSample);
  649. }
  650. return S_OK;
  651. }
  652. HRESULT DrawAppearance(HDC hdc, LPRECT prc, SYSTEMMETRICSALL* psysMet, BOOL fOnlyShowActiveWindow, BOOL fRTL)
  653. {
  654. HRESULT hr = E_OUTOFMEMORY;
  655. CAdvAppearancePage* pAdv = new CAdvAppearancePage(psysMet);
  656. if (pAdv)
  657. {
  658. hr = pAdv->Draw(hdc, prc, fOnlyShowActiveWindow, fRTL);
  659. delete pAdv;
  660. }
  661. return hr;
  662. }