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.

2190 lines
69 KiB

  1. /*****************************************************************************\
  2. FILE: AdvAppearPg.cpp
  3. DESCRIPTION:
  4. This code will display a "Advanced Appearances" tab in the
  5. "Advanced Display Properties" dialog.
  6. ??????? ?/??/1993 Created
  7. BryanSt 3/23/2000 Updated and Converted to C++
  8. Copyright (C) Microsoft Corp 1993-2000. All rights reserved.
  9. \*****************************************************************************/
  10. #include "priv.h"
  11. #include "PreviewSM.h"
  12. #include "AdvAppearPg.h"
  13. #include "BaseAppearPg.h"
  14. #include "regutil.h"
  15. #include "CoverWnd.h"
  16. #include "fontfix.h"
  17. // The following are the indices into the above array.
  18. #define COLORFLAG_SOLID 0x0001
  19. #define COLOR_MAX_400 (COLOR_INFOBK + 1)
  20. #define CURRENT_ELEMENT_NONE -2 // This means that no element is selected.
  21. // used by ChooseColor dialog
  22. COLORREF g_CustomColors[16]; // This is the user customized palette. We could put this into the class.
  23. CAdvAppearancePage * g_pAdvAppearancePage = NULL;
  24. //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  25. //this order has to match the enum order in look.h
  26. //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  27. LOOK_ELEMENT g_elements[] = {
  28. /* ELEMENT_APPSPACE */ {COLOR_APPWORKSPACE, SIZE_NONE, FALSE, COLOR_NONE, FONT_NONE, ELNAME_APPSPACE, -1, COLOR_NONE, {-1,-1,-1,-1}},
  29. /* ELEMENT_DESKTOP */ {COLOR_BACKGROUND, SIZE_NONE, FALSE, COLOR_NONE, FONT_NONE, ELNAME_DESKTOP, -1, COLOR_NONE, {-1,-1,-1,-1}},
  30. /* ELEMENT_INACTIVEBORDER */ {COLOR_INACTIVEBORDER, SIZE_FRAME, FALSE, COLOR_NONE, FONT_NONE, ELNAME_INACTIVEBORDER, -1, COLOR_NONE, {-1,-1,-1,-1}},
  31. /* ELEMENT_ACTIVEBORDER */ {COLOR_ACTIVEBORDER, SIZE_FRAME, FALSE, COLOR_NONE, FONT_NONE, ELNAME_ACTIVEBORDER, -1, COLOR_NONE, {-1,-1,-1,-1}},
  32. /* ELEMENT_INACTIVECAPTION */ {COLOR_INACTIVECAPTION, SIZE_CAPTION, TRUE, COLOR_INACTIVECAPTIONTEXT,FONT_CAPTION,ELNAME_INACTIVECAPTION, -1,COLOR_GRADIENTINACTIVECAPTION, {-1,-1,-1,-1}},
  33. /* ELEMENT_INACTIVESYSBUT1 */ {COLOR_NONE, SIZE_CAPTION, FALSE, COLOR_NONE, FONT_NONE, -1, ELEMENT_ACTIVESYSBUT1, COLOR_NONE, {-1,-1,-1,-1}},
  34. /* ELEMENT_INACTIVESYSBUT2 */ {COLOR_NONE, SIZE_CAPTION, FALSE, COLOR_NONE, FONT_NONE, -1, ELEMENT_ACTIVESYSBUT1, COLOR_NONE, {-1,-1,-1,-1}},
  35. /* ELEMENT_ACTIVECAPTION */ {COLOR_ACTIVECAPTION, SIZE_CAPTION, TRUE, COLOR_CAPTIONTEXT, FONT_CAPTION, ELNAME_ACTIVECAPTION, -1, COLOR_GRADIENTACTIVECAPTION, {-1,-1,-1,-1}},
  36. /* ELEMENT_ACTIVESYSBUT1 */ {COLOR_NONE, SIZE_CAPTION, FALSE, COLOR_NONE, FONT_NONE, ELNAME_CAPTIONBUTTON, -1, COLOR_NONE, {-1,-1,-1,-1}},
  37. /* ELEMENT_ACTIVESYSBUT2 */ {COLOR_NONE, SIZE_CAPTION, FALSE, COLOR_NONE, FONT_NONE, -1, ELEMENT_ACTIVESYSBUT1, COLOR_NONE, {-1,-1,-1,-1}},
  38. /* ELEMENT_MENUNORMAL */ {COLOR_MENU, SIZE_MENU, TRUE, COLOR_MENUTEXT, FONT_MENU, ELNAME_MENU, -1, COLOR_NONE, {-1,-1,-1,-1}},
  39. /* ELEMENT_MENUSELECTED */ {COLOR_HIGHLIGHT, SIZE_MENU, TRUE, COLOR_HIGHLIGHTTEXT, FONT_MENU, ELNAME_MENUSELECTED, -1, COLOR_NONE, {-1,-1,-1,-1}},
  40. /* ELEMENT_MENUDISABLED */ {COLOR_MENU, SIZE_MENU, TRUE, COLOR_NONE, FONT_MENU, -1, ELEMENT_MENUNORMAL, COLOR_NONE, {-1,-1,-1,-1}},
  41. /* ELEMENT_WINDOW */ {COLOR_WINDOW, SIZE_NONE, FALSE, COLOR_WINDOWTEXT, FONT_NONE, ELNAME_WINDOW, -1, COLOR_NONE, {-1,-1,-1,-1}},
  42. /* ELEMENT_MSGBOX */ {COLOR_NONE, SIZE_NONE, TRUE, COLOR_WINDOWTEXT, FONT_MSGBOX, ELNAME_MSGBOX, -1, COLOR_NONE, {-1,-1,-1,-1}},
  43. /* ELEMENT_MSGBOXCAPTION */ {COLOR_ACTIVECAPTION, SIZE_CAPTION, TRUE, COLOR_CAPTIONTEXT, FONT_CAPTION, -1, ELEMENT_ACTIVECAPTION, COLOR_GRADIENTACTIVECAPTION, {-1,-1,-1,-1}},
  44. /* ELEMENT_MSGBOXSYSBUT */ {COLOR_3DFACE, SIZE_CAPTION, TRUE, COLOR_BTNTEXT, FONT_CAPTION, -1, ELEMENT_ACTIVESYSBUT1, COLOR_NONE, {-1,-1,-1,-1}},
  45. // do not even try to set a scrollbar color the system will ignore you
  46. /* ELEMENT_SCROLLBAR */ {COLOR_NONE, SIZE_SCROLL, FALSE, COLOR_NONE, FONT_NONE, ELNAME_SCROLLBAR, -1, COLOR_NONE, {-1,-1,-1,-1}},
  47. /* ELEMENT_SCROLLUP */ {COLOR_NONE, SIZE_SCROLL, FALSE, COLOR_NONE, FONT_NONE, -1, ELEMENT_SCROLLBAR, COLOR_NONE, {-1,-1,-1,-1}},
  48. /* ELEMENT_SCROLLDOWN */ {COLOR_NONE, SIZE_SCROLL, FALSE, COLOR_NONE, FONT_NONE, -1, ELEMENT_SCROLLBAR, COLOR_NONE, {-1,-1,-1,-1}},
  49. /* ELEMENT_BUTTON */ {COLOR_3DFACE, SIZE_NONE, FALSE, COLOR_BTNTEXT, FONT_NONE, ELNAME_BUTTON, -1, COLOR_NONE, {-1,-1,-1,-1}},
  50. /* ELEMENT_SMCAPTION */ {COLOR_NONE, SIZE_SMCAPTION, TRUE, COLOR_NONE, FONT_SMCAPTION,ELNAME_SMALLCAPTION, -1, COLOR_NONE, {-1,-1,-1,-1}},
  51. /* ELEMENT_ICON */ {COLOR_NONE, SIZE_ICON, FALSE, COLOR_NONE, FONT_ICONTITLE,ELNAME_ICON, -1, COLOR_NONE, {-1,-1,-1,-1}},
  52. /* ELEMENT_ICONHORZSPACING */ {COLOR_NONE, SIZE_DXICON, FALSE, COLOR_NONE, FONT_NONE, ELNAME_DXICON, -1, COLOR_NONE, {-1,-1,-1,-1}},
  53. /* ELEMENT_ICONVERTSPACING */ {COLOR_NONE, SIZE_DYICON, FALSE, COLOR_NONE, FONT_NONE, ELNAME_DYICON, -1, COLOR_NONE, {-1,-1,-1,-1}},
  54. /* ELEMENT_INFO */ {COLOR_INFOBK, SIZE_NONE, TRUE, COLOR_INFOTEXT, FONT_STATUS, ELNAME_INFO, -1, COLOR_NONE, {-1,-1,-1,-1}},
  55. /* ELEMENT_HOTTRACKAREA */ {COLOR_HOTLIGHT, SIZE_NONE, FALSE, COLOR_NONE, FONT_NONE, ELNAME_HOTTRACKAREA, -1, COLOR_NONE, {-1,-1,-1,-1}}
  56. };
  57. #if 0
  58. // go fix look.h if you decide to add this back in
  59. /* ELEMENT_SMICON */ {COLOR_NONE, SIZE_SMICON, FALSE, COLOR_NONE, FONT_NONE, ELNAME_SMICON, -1, COLOR_NONE, {-1,-1,-1,-1}},
  60. #endif
  61. #define ELCUR (g_elements[m_iCurElement])
  62. #define ELCURFONT (m_fonts[ELCUR.iFont])
  63. void LoadCustomColors(void);
  64. BOOL Font_GetNameFromList(HWND hwndList, INT iItem, LPTSTR pszFace, INT cchFaceMax, LPTSTR pszScript, INT cchScriptMax);
  65. void Font_AddSize(HWND hwndPoints, int iNewPoint, BOOL bSort);
  66. int CALLBACK Font_EnumSizes(LPENUMLOGFONT lpelf, LPNEWTEXTMETRIC lpntm, int Type, LPARAM lData);
  67. //============================================================================================================
  68. // *** Globals ***
  69. //============================================================================================================
  70. const static DWORD aAdvAppearanceHelpIds[] = {
  71. IDC_ADVAP_LOOKPREV, IDH_DISPLAY_APPEARANCE_GRAPHIC,
  72. IDC_ADVAP_ELEMENTSLABEL, IDH_DISPLAY_APPEARANCE_ITEM_LIST,
  73. IDC_ADVAP_ELEMENTS, IDH_DISPLAY_APPEARANCE_ITEM_LIST,
  74. IDC_ADVAP_MAINSIZE, IDH_DISPLAY_APPEARANCE_ITEM_SIZE,
  75. IDC_ADVAP_SIZELABEL, IDH_DISPLAY_APPEARANCE_ITEM_SIZE,
  76. IDC_ADVAP_SIZEARROWS, IDH_DISPLAY_APPEARANCE_ITEM_SIZE,
  77. IDC_ADVAP_COLORLABEL, IDH_DISPLAY_APPEARANCE_ITEM_COLOR,
  78. IDC_ADVAP_MAINCOLOR, IDH_DISPLAY_APPEARANCE_ITEM_COLOR,
  79. IDC_ADVAP_GRADIENTLABEL, IDH_DISPLAY_APPEARANCE_ITEM_COLOR2,
  80. IDC_ADVAP_GRADIENT, IDH_DISPLAY_APPEARANCE_ITEM_COLOR2,
  81. IDC_ADVAP_FONTLABEL, IDH_DISPLAY_APPEARANCE_FONT_LIST,
  82. IDC_ADVAP_FONTNAME, IDH_DISPLAY_APPEARANCE_FONT_LIST,
  83. IDC_ADVAP_FONTSIZELABEL, IDH_DISPLAY_APPEARANCE_FONT_SIZE,
  84. IDC_ADVAP_FONTSIZE, IDH_DISPLAY_APPEARANCE_FONT_SIZE,
  85. IDC_ADVAP_FNCOLORLABEL, IDH_DISPLAY_APPEARANCE_FONT_COLOR,
  86. IDC_ADVAP_TEXTCOLOR, IDH_DISPLAY_APPEARANCE_FONT_COLOR,
  87. IDC_ADVAP_FONTBOLD, IDH_DISPLAY_APPEARANCE_FONT_BOLD,
  88. IDC_ADVAP_FONTITAL, IDH_DISPLAY_APPEARANCE_FONT_ITALIC,
  89. 0, 0
  90. };
  91. #define SZ_HELPFILE_ADVAPPEARANCE TEXT("display.hlp")
  92. //===========================
  93. // *** Class Internals & Helpers ***
  94. //===========================
  95. // a new font name was chosen. build a new point size list.
  96. void CAdvAppearancePage::_SelectName(HWND hDlg, int iSel)
  97. {
  98. INT dwItemData;
  99. HWND hwndFontSize = GetDlgItem(hDlg, IDC_ADVAP_FONTSIZE);
  100. HDC hdc;
  101. // build the approriate point size list
  102. SendMessage(hwndFontSize, CB_RESETCONTENT, 0, 0L);
  103. dwItemData = LOWORD(SendDlgItemMessage(hDlg, IDC_ADVAP_FONTNAME, CB_GETITEMDATA, (WPARAM)iSel, 0L));
  104. if (LOWORD(dwItemData) == TRUETYPE_FONTTYPE)
  105. {
  106. INT i;
  107. for (i = 6; i <= 24; i++)
  108. Font_AddSize(hwndFontSize, i, FALSE);
  109. }
  110. else
  111. {
  112. LOGFONT lf;
  113. Font_GetNameFromList(GetDlgItem(hDlg, IDC_ADVAP_FONTNAME),
  114. iSel,
  115. lf.lfFaceName,
  116. ARRAYSIZE(lf.lfFaceName),
  117. NULL,
  118. 0);
  119. hdc = GetDC(NULL);
  120. lf.lfCharSet = (BYTE)(HIWORD(dwItemData));
  121. lf.lfPitchAndFamily = 0;
  122. EnumFontFamiliesEx(hdc, &lf, (FONTENUMPROC)Font_EnumSizes, (LPARAM)this, 0);
  123. ReleaseDC(NULL, hdc);
  124. }
  125. }
  126. // new font was chosen. select the proper point size
  127. // return: actual point size chosen
  128. int Font_SelectSize(HWND hDlg, int iCurPoint)
  129. {
  130. int i, iPoint = 0;
  131. HWND hwndFontSize = GetDlgItem(hDlg, IDC_ADVAP_FONTSIZE);
  132. i = (int)SendMessage(hwndFontSize, CB_GETCOUNT, 0, 0L);
  133. // the loop stops with i=0, so we get some selection for sure
  134. for (i--; i > 0; i--)
  135. {
  136. iPoint = LOWORD(SendMessage(hwndFontSize, CB_GETITEMDATA, (WPARAM)i, 0L));
  137. // walking backwards through list, find equal or next smallest
  138. if (iCurPoint >= iPoint)
  139. break;
  140. }
  141. SendMessage(hwndFontSize, CB_SETCURSEL, (WPARAM)i, 0L);
  142. return iPoint;
  143. }
  144. int CAdvAppearancePage::_HeightToPoint(int nHeight)
  145. {
  146. if (nHeight < 0)
  147. {
  148. nHeight = -nHeight;
  149. }
  150. return MulDiv(nHeight, 72, m_nCachedNewDPI);
  151. }
  152. int CAdvAppearancePage::_PointToHeight(int nPoints)
  153. {
  154. if (nPoints > 0)
  155. {
  156. nPoints = -nPoints;
  157. }
  158. // Heights must always be negative. NTUSER is full of bugs when
  159. // the values are positive.
  160. return MulDiv(nPoints, m_nCachedNewDPI, 72);
  161. }
  162. /*
  163. ** initialize the constant dialog components
  164. **
  165. ** initialize the list of element names. this stays constant with the
  166. ** possible exception that some items might be added/removed depending
  167. ** on some special case conditions.
  168. */
  169. void Look_InitDialog(HWND hDlg)
  170. {
  171. int iEl, iName;
  172. TCHAR szName[CCH_MAX_STRING];
  173. HWND hwndElements;
  174. LOGFONT lf;
  175. HFONT hfont;
  176. int oldWeight;
  177. LoadCustomColors();
  178. hwndElements = GetDlgItem(hDlg, IDC_ADVAP_ELEMENTS);
  179. for (iEl = 0; iEl < ARRAYSIZE(g_elements); iEl++)
  180. {
  181. if ((g_elements[iEl].iResId != -1) &&
  182. LoadString(HINST_THISDLL, g_elements[iEl].iResId, szName, ARRAYSIZE(szName)))
  183. {
  184. iName = (int)SendMessage(hwndElements, CB_FINDSTRINGEXACT, 0, (LPARAM)szName);
  185. if (iName == CB_ERR)
  186. iName = (int)SendMessage(hwndElements, CB_ADDSTRING, 0, (LPARAM)szName);
  187. // reference back to item in array
  188. if (iName != CB_ERR)
  189. SendMessage(hwndElements, CB_SETITEMDATA, (WPARAM)iName, (LPARAM)iEl);
  190. }
  191. }
  192. // make bold button have bold text
  193. hfont = (HFONT)SendDlgItemMessage(hDlg, IDC_ADVAP_FONTBOLD, WM_GETFONT, 0, 0L);
  194. GetObject(hfont, sizeof(lf), &lf);
  195. oldWeight = lf.lfWeight;
  196. lf.lfWeight = FW_BOLD;
  197. hfont = CreateFontIndirect(&lf);
  198. if (hfont)
  199. SendDlgItemMessage(hDlg, IDC_ADVAP_FONTBOLD, WM_SETFONT, (WPARAM)hfont, 0L);
  200. // make italic button have italic text
  201. lf.lfWeight = oldWeight;
  202. lf.lfItalic = TRUE;
  203. hfont = CreateFontIndirect(&lf);
  204. if (hfont)
  205. {
  206. SendDlgItemMessage(hDlg, IDC_ADVAP_FONTITAL, WM_SETFONT, (WPARAM)hfont, 0L);
  207. }
  208. }
  209. HRESULT CAdvAppearancePage::_OnFontNameChanged(HWND hDlg)
  210. {
  211. HRESULT hr = E_NOTIMPL;
  212. TCHAR szBuf[MAX_PATH];
  213. int nIndex = (int)SendDlgItemMessage(hDlg, IDC_ADVAP_FONTNAME, CB_GETCURSEL,0,0L);
  214. DWORD dwItemData = (DWORD)SendDlgItemMessage(hDlg, IDC_ADVAP_FONTNAME, CB_GETITEMDATA, (WPARAM)nIndex, 0);
  215. _SelectName(hDlg, nIndex);
  216. Font_SelectSize(hDlg, _HeightToPoint(ELCURFONT.lf.lfHeight));
  217. Font_GetNameFromList(GetDlgItem(hDlg, IDC_ADVAP_FONTNAME), nIndex, szBuf, ARRAYSIZE(szBuf), NULL, 0);
  218. // Change font to currently selected name and charset.
  219. _ChangeFontName(hDlg, szBuf, HIWORD(dwItemData));
  220. return hr;
  221. }
  222. HRESULT CAdvAppearancePage::_OnSizeChange(HWND hDlg, WORD wEvent)
  223. {
  224. HRESULT hr = E_NOTIMPL;
  225. int nIndex;
  226. if ((wEvent == EN_CHANGE) && (m_iCurElement >= 0) && (ELCUR.iSize >= 0))
  227. {
  228. nIndex = (int)LOWORD(SendDlgItemMessage(hDlg, IDC_ADVAP_SIZEARROWS, UDM_GETPOS,0,0L));
  229. _ChangeSize(hDlg, nIndex, TRUE);
  230. }
  231. else if (wEvent == EN_KILLFOCUS)
  232. {
  233. nIndex = (int)SendDlgItemMessage(hDlg, IDC_ADVAP_SIZEARROWS, UDM_GETPOS,0,0L);
  234. if (HIWORD(nIndex) != 0)
  235. {
  236. SetDlgItemInt(hDlg, IDC_ADVAP_MAINSIZE, (UINT)LOWORD(nIndex), FALSE);
  237. }
  238. }
  239. return hr;
  240. }
  241. HRESULT CAdvAppearancePage::_OnInitAdvAppearanceDlg(HWND hDlg)
  242. {
  243. m_fInUserEditMode = FALSE;
  244. // initialize some globals
  245. _hwnd = hDlg;
  246. m_cyBorderSM = ClassicGetSystemMetrics(SM_CYBORDER);
  247. m_cxBorderSM = ClassicGetSystemMetrics(SM_CXBORDER);
  248. m_cxEdgeSM = ClassicGetSystemMetrics(SM_CXEDGE);
  249. m_cyEdgeSM = ClassicGetSystemMetrics(SM_CYEDGE);
  250. Look_InitDialog(hDlg);
  251. _InitSysStuff();
  252. _InitFontList(hDlg);
  253. // paint the preview
  254. _Repaint(hDlg, TRUE);
  255. _SelectElement(hDlg, ELEMENT_DESKTOP, LSE_SETCUR);
  256. m_fInUserEditMode = TRUE;
  257. // theme ownerdrawn color picker button
  258. m_hTheme = OpenThemeData(GetDlgItem(hDlg, IDC_ADVAP_MAINCOLOR), WC_BUTTON);
  259. return S_OK;
  260. }
  261. HRESULT CAdvAppearancePage::_LoadState(IN const SYSTEMMETRICSALL * pState)
  262. {
  263. HRESULT hr = E_INVALIDARG;
  264. if (pState)
  265. {
  266. _SetMyNonClientMetrics((const LPNONCLIENTMETRICS)&(pState->schemeData.ncm));
  267. m_dwChanged = pState->dwChanged;
  268. // Set Sizes
  269. m_sizes[SIZE_DXICON].CurSize = pState->nDXIcon;
  270. m_sizes[SIZE_DYICON].CurSize = pState->nDYIcon;
  271. m_sizes[SIZE_ICON].CurSize = pState->nIcon;
  272. m_sizes[SIZE_SMICON].CurSize = pState->nSmallIcon;
  273. // Set Fonts
  274. m_fonts[FONT_ICONTITLE].lf = pState->schemeData.lfIconTitle;
  275. m_fModifiedScheme = pState->fModifiedScheme;
  276. for (int nIndex = 0; nIndex < ARRAYSIZE(m_rgb); nIndex++)
  277. {
  278. m_rgb[nIndex] = pState->schemeData.rgb[nIndex];
  279. }
  280. hr = S_OK;
  281. }
  282. return hr;
  283. }
  284. HRESULT CAdvAppearancePage::_OnDestroy(HWND hDlg)
  285. {
  286. _DestroySysStuff();
  287. HFONT hfont, hfontOther;
  288. hfontOther = (HFONT)SendDlgItemMessage(hDlg, IDC_ADVAP_MAINSIZE, WM_GETFONT, 0, 0L);
  289. hfont = (HFONT)SendDlgItemMessage(hDlg, IDC_ADVAP_FONTBOLD, WM_GETFONT, 0, 0L);
  290. if (hfont && (hfont != hfontOther))
  291. {
  292. DeleteObject(hfont);
  293. }
  294. hfont = (HFONT)SendDlgItemMessage(hDlg, IDC_ADVAP_FONTITAL, WM_GETFONT, 0, 0L);
  295. if (hfont && (hfont != hfontOther))
  296. {
  297. DeleteObject(hfont);
  298. }
  299. if (m_hTheme)
  300. {
  301. CloseThemeData(m_hTheme);
  302. m_hTheme = NULL;
  303. }
  304. _hwnd = NULL;
  305. return S_OK;
  306. }
  307. INT_PTR CAdvAppearancePage::_OnCommand(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
  308. {
  309. BOOL fHandled = 1; // Not handled (WM_COMMAND seems to be different)
  310. WORD idCtrl = GET_WM_COMMAND_ID(wParam, lParam);
  311. WORD wEvent = GET_WM_COMMAND_CMD(wParam, lParam);
  312. int nIndex;
  313. TCHAR szBuf[100];
  314. switch (idCtrl)
  315. {
  316. case IDOK:
  317. EndDialog(hDlg, IDOK);
  318. break;
  319. case IDCANCEL:
  320. EndDialog(hDlg, IDCANCEL);
  321. break;
  322. case IDC_ADVAP_ELEMENTS:
  323. if(wEvent == CBN_SELCHANGE)
  324. {
  325. nIndex = (int)SendDlgItemMessage(hDlg, IDC_ADVAP_ELEMENTS, CB_GETCURSEL,0,0L);
  326. nIndex = LOWORD(SendDlgItemMessage(hDlg, IDC_ADVAP_ELEMENTS, CB_GETITEMDATA, (WPARAM)nIndex, 0L));
  327. _SelectElement(hDlg, nIndex, LSE_NONE);
  328. }
  329. break;
  330. case IDC_ADVAP_FONTNAME:
  331. if(wEvent == CBN_SELCHANGE)
  332. {
  333. _OnFontNameChanged(hDlg);
  334. }
  335. break;
  336. case IDC_ADVAP_FONTSIZE:
  337. switch (wEvent)
  338. {
  339. case CBN_SELCHANGE:
  340. nIndex = (int)SendDlgItemMessage(hDlg, IDC_ADVAP_FONTSIZE, CB_GETCURSEL,0,0L);
  341. nIndex = LOWORD(SendDlgItemMessage(hDlg, IDC_ADVAP_FONTSIZE, CB_GETITEMDATA, (WPARAM)nIndex, 0L));
  342. _ChangeFontSize(hDlg, nIndex);
  343. break;
  344. case CBN_EDITCHANGE:
  345. GetWindowText(GetDlgItem(hDlg, IDC_ADVAP_FONTSIZE), szBuf, ARRAYSIZE(szBuf));
  346. _ChangeFontSize(hDlg, StrToInt(szBuf));
  347. break;
  348. }
  349. break;
  350. case IDC_ADVAP_FONTBOLD:
  351. case IDC_ADVAP_FONTITAL:
  352. if (wEvent == BN_CLICKED)
  353. {
  354. BOOL fCheck = !IsDlgButtonChecked(hDlg, LOWORD(wParam));
  355. CheckDlgButton(hDlg, LOWORD(wParam), fCheck);
  356. _ChangeFontBI(hDlg, LOWORD(wParam), fCheck);
  357. }
  358. break;
  359. case IDC_ADVAP_MAINSIZE:
  360. _OnSizeChange(hDlg, wEvent);
  361. break;
  362. case IDC_ADVAP_GRADIENT:
  363. case IDC_ADVAP_MAINCOLOR:
  364. case IDC_ADVAP_TEXTCOLOR:
  365. if (wEvent == BN_CLICKED)
  366. _PickAColor(hDlg, idCtrl);
  367. break;
  368. default:
  369. break;
  370. }
  371. return fHandled;
  372. }
  373. INT_PTR CALLBACK CAdvAppearancePage::AdvAppearDlgProc(HWND hDlg, UINT wMsg, WPARAM wParam, LPARAM lParam)
  374. {
  375. CAdvAppearancePage * pThis = (CAdvAppearancePage *)GetWindowLongPtr(hDlg, DWLP_USER);
  376. if (WM_INITDIALOG == wMsg)
  377. {
  378. pThis = (CAdvAppearancePage *) lParam;
  379. if (pThis)
  380. {
  381. SetWindowLongPtr(hDlg, DWLP_USER, lParam);
  382. }
  383. }
  384. if (pThis)
  385. return pThis->_AdvAppearDlgProc(hDlg, wMsg, wParam, lParam);
  386. return DefWindowProc(hDlg, wMsg, wParam, lParam);
  387. }
  388. // This Property Sheet appear in the top level of the "Display Control Panel".
  389. INT_PTR CAdvAppearancePage::_AdvAppearDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
  390. {
  391. switch(message)
  392. {
  393. case WM_NOTIFY:
  394. break;
  395. case WM_INITDIALOG:
  396. _OnInitAdvAppearanceDlg(hDlg);
  397. break;
  398. case WM_DESTROY:
  399. _OnDestroy(hDlg);
  400. break;
  401. case WM_DRAWITEM:
  402. switch (wParam)
  403. {
  404. case IDC_ADVAP_GRADIENT:
  405. case IDC_ADVAP_MAINCOLOR:
  406. case IDC_ADVAP_TEXTCOLOR:
  407. _DrawButton(hDlg, (LPDRAWITEMSTRUCT)lParam);
  408. return TRUE;
  409. }
  410. break;
  411. case WM_SETTINGCHANGE:
  412. case WM_SYSCOLORCHANGE:
  413. case WM_DISPLAYCHANGE:
  414. _PropagateMessage(hDlg, message, wParam, lParam);
  415. break;
  416. case WM_QUERYNEWPALETTE:
  417. case WM_PALETTECHANGED:
  418. SendDlgItemMessage(hDlg, IDC_ADVAP_LOOKPREV, message, wParam, lParam);
  419. return TRUE;
  420. case WM_HELP:
  421. WinHelp((HWND) ((LPHELPINFO) lParam)->hItemHandle, SZ_HELPFILE_ADVAPPEARANCE, HELP_WM_HELP, (DWORD_PTR) aAdvAppearanceHelpIds);
  422. break;
  423. case WM_CONTEXTMENU: // right mouse click
  424. WinHelp((HWND) wParam, SZ_HELPFILE_ADVAPPEARANCE, HELP_CONTEXTMENU, (DWORD_PTR) aAdvAppearanceHelpIds);
  425. break;
  426. case WM_COMMAND:
  427. _OnCommand(hDlg, message, wParam, lParam);
  428. break;
  429. case WM_THEMECHANGED:
  430. if (m_hTheme)
  431. {
  432. CloseThemeData(m_hTheme);
  433. }
  434. m_hTheme = OpenThemeData(GetDlgItem(hDlg, IDC_ADVAP_MAINCOLOR), WC_BUTTON);
  435. break;
  436. }
  437. return FALSE;
  438. }
  439. const UINT g_colorFlags[COLOR_MAX] = {
  440. /* COLOR_SCROLLBAR */ 0,
  441. /* COLOR_DESKTOP */ 0,
  442. /* COLOR_ACTIVECAPTION */ COLORFLAG_SOLID,
  443. /* COLOR_INACTIVECAPTION */ COLORFLAG_SOLID,
  444. /* COLOR_MENU */ COLORFLAG_SOLID,
  445. /* COLOR_WINDOW */ COLORFLAG_SOLID,
  446. /* COLOR_WINDOWFRAME */ COLORFLAG_SOLID,
  447. /* COLOR_MENUTEXT */ COLORFLAG_SOLID,
  448. /* COLOR_WINDOWTEXT */ COLORFLAG_SOLID,
  449. /* COLOR_CAPTIONTEXT */ COLORFLAG_SOLID,
  450. /* COLOR_ACTIVEBORDER */ 0,
  451. /* COLOR_INACTIVEBORDER */ 0,
  452. /* COLOR_APPWORKSPACE */ 0,
  453. /* COLOR_HIGHLIGHT */ COLORFLAG_SOLID,
  454. /* COLOR_HIGHLIGHTTEXT */ COLORFLAG_SOLID,
  455. /* COLOR_3DFACE */ COLORFLAG_SOLID,
  456. /* COLOR_3DSHADOW */ COLORFLAG_SOLID,
  457. /* COLOR_GRAYTEXT */ COLORFLAG_SOLID,
  458. /* COLOR_BTNTEXT */ COLORFLAG_SOLID,
  459. /* COLOR_INACTIVECAPTIONTEXT */ COLORFLAG_SOLID,
  460. /* COLOR_3DHILIGHT */ COLORFLAG_SOLID,
  461. /* COLOR_3DDKSHADOW */ COLORFLAG_SOLID,
  462. /* COLOR_3DLIGHT */ COLORFLAG_SOLID,
  463. /* COLOR_INFOTEXT */ COLORFLAG_SOLID,
  464. /* COLOR_INFOBK */ 0,
  465. /* COLOR_3DALTFACE */ 0,
  466. /* COLOR_HOTLIGHT */ COLORFLAG_SOLID,
  467. /* COLOR_GRADIENTACTIVECAPTION */ COLORFLAG_SOLID,
  468. /* COLOR_GRADIENTINACTIVECAPTION */ COLORFLAG_SOLID,
  469. /* COLOR_MENUHILIGHT */ 0,
  470. /* COLOR_MENUBAR */ 0
  471. };
  472. #define RGB_PALETTE 0x02000000
  473. // make the color a solid color if it needs to be.
  474. // on a palette device make is a palette relative color, if we need to.
  475. COLORREF CAdvAppearancePage::_NearestColor(int iColor, COLORREF rgb)
  476. {
  477. rgb &= 0x00FFFFFF;
  478. // if we are on a palette device, we need to do special stuff...
  479. if (m_bPalette)
  480. {
  481. if (g_colorFlags[iColor] & COLORFLAG_SOLID)
  482. {
  483. if (IsPaletteColor(m_hpal3D, rgb))
  484. rgb |= RGB_PALETTE;
  485. else
  486. rgb = GetNearestPaletteColor(m_hpalVGA, rgb);
  487. }
  488. else
  489. {
  490. if (IsPaletteColor(m_hpal3D, rgb))
  491. rgb |= RGB_PALETTE;
  492. else if (IsPaletteColor((HPALETTE)GetStockObject(DEFAULT_PALETTE), rgb))
  493. rgb ^= 0x000001; // force a dither
  494. }
  495. }
  496. else
  497. {
  498. // map color to nearest color if we need to for this UI element.
  499. if (g_colorFlags[iColor] & COLORFLAG_SOLID)
  500. {
  501. HDC hdc = GetDC(NULL);
  502. rgb = GetNearestColor(hdc, rgb);
  503. ReleaseDC(NULL, hdc);
  504. }
  505. }
  506. return rgb;
  507. }
  508. void CAdvAppearancePage::_PickAColor(HWND hDlg, int CtlID)
  509. {
  510. COLORPICK_INFO cpi;
  511. int iColor;
  512. switch (CtlID)
  513. {
  514. case IDC_ADVAP_GRADIENT:
  515. iColor = ELCUR.iGradientColor;
  516. break;
  517. case IDC_ADVAP_MAINCOLOR:
  518. iColor = ELCUR.iMainColor;
  519. break;
  520. case IDC_ADVAP_TEXTCOLOR:
  521. iColor = ELCUR.iTextColor;
  522. break;
  523. default:
  524. return;
  525. }
  526. cpi.hwndParent = GetDlgItem(hDlg, CtlID);
  527. cpi.hwndOwner = GetDlgItem(hDlg, CtlID); // Color button
  528. cpi.hpal = m_hpal3D;
  529. cpi.rgb = m_rgb[iColor];
  530. cpi.flags = CC_RGBINIT | CC_FULLOPEN;
  531. if ((iColor == COLOR_3DFACE) && m_bPalette)
  532. {
  533. cpi.flags |= CC_ANYCOLOR;
  534. }
  535. else if (g_colorFlags[iColor] & COLORFLAG_SOLID)
  536. {
  537. cpi.flags |= CC_SOLIDCOLOR;
  538. }
  539. if (ChooseColorMini(&cpi) && _ChangeColor(hDlg, iColor, cpi.rgb))
  540. {
  541. _SetColor(hDlg, CtlID, m_brushes[iColor]);
  542. _Repaint(hDlg, FALSE);
  543. }
  544. }
  545. // ------------------------ magic color utilities --------------------------
  546. /*
  547. ** set a color in the 3D palette.
  548. */
  549. void CAdvAppearancePage::_Set3DPaletteColor(COLORREF rgb, int iColor)
  550. {
  551. int iPalette;
  552. PALETTEENTRY pe;
  553. if (!m_hpal3D)
  554. return;
  555. switch (iColor)
  556. {
  557. case COLOR_3DFACE:
  558. iPalette = 16;
  559. break;
  560. case COLOR_3DSHADOW:
  561. iPalette = 17;
  562. break;
  563. case COLOR_3DHILIGHT:
  564. iPalette = 18;
  565. break;
  566. default:
  567. return;
  568. }
  569. pe.peRed = GetRValue(rgb);
  570. pe.peGreen = GetGValue(rgb);
  571. pe.peBlue = GetBValue(rgb);
  572. pe.peFlags = 0;
  573. SetPaletteEntries(m_hpal3D, iPalette, 1, (LPPALETTEENTRY)&pe);
  574. }
  575. // ------------end--------- magic color utilities --------------------------
  576. void CAdvAppearancePage::_InitUniqueCharsetArray(void)
  577. {
  578. UINT uiCharsets[MAX_CHARSETS];
  579. Font_GetCurrentCharsets(uiCharsets, ARRAYSIZE(uiCharsets));
  580. // Find the unique Charsets and save that in a global array.
  581. Font_GetUniqueCharsets(uiCharsets, m_uiUniqueCharsets, MAX_CHARSETS, &m_iCountCharsets);
  582. }
  583. HRESULT CAdvAppearancePage::_InitFonts(void)
  584. {
  585. for (int nIndex = 0; nIndex < ARRAYSIZE(m_fonts); nIndex++)
  586. {
  587. if (m_fonts[nIndex].hfont)
  588. {
  589. DeleteObject(m_fonts[nIndex].hfont);
  590. m_fonts[nIndex].hfont = NULL;
  591. }
  592. m_fonts[nIndex].hfont = CreateFontIndirect(&m_fonts[nIndex].lf);
  593. }
  594. return S_OK;
  595. }
  596. HRESULT CAdvAppearancePage::_FreeFonts(void)
  597. {
  598. for (int nIndex = 0; nIndex < ARRAYSIZE(m_fonts); nIndex++)
  599. {
  600. if (m_fonts[nIndex].hfont)
  601. {
  602. DeleteObject(m_fonts[nIndex].hfont);
  603. m_fonts[nIndex].hfont = NULL;
  604. }
  605. }
  606. return S_OK;
  607. }
  608. // new data has been set. flush out current objects and rebuild
  609. void CAdvAppearancePage::_RebuildSysStuff(BOOL fInit)
  610. {
  611. int i;
  612. SelectObject(g_hdcMem, GetStockObject(BLACK_BRUSH));
  613. SelectObject(g_hdcMem, GetStockObject(SYSTEM_FONT));
  614. _InitFonts();
  615. if (fInit)
  616. {
  617. HPALETTE hpal = (HPALETTE) GetStockObject(DEFAULT_PALETTE);
  618. if (hpal)
  619. {
  620. PALETTEENTRY pal[4];
  621. // get current magic colors
  622. pal[0].peFlags = 0;
  623. pal[1].peFlags = 0;
  624. pal[2].peFlags = 0;
  625. pal[3].peFlags = 0;
  626. if (GetPaletteEntries(hpal, 8, 4, pal))
  627. {
  628. SetPaletteEntries(m_hpal3D, 16, 4, pal);
  629. // set up magic colors in the 3d palette
  630. if (!IsPaletteColor(hpal, m_rgb[COLOR_3DFACE]))
  631. _Set3DPaletteColor(m_rgb[COLOR_3DFACE], COLOR_3DFACE);
  632. if (!IsPaletteColor(hpal, m_rgb[COLOR_3DSHADOW]))
  633. _Set3DPaletteColor(m_rgb[COLOR_3DSHADOW], COLOR_3DSHADOW);
  634. if (!IsPaletteColor(hpal, m_rgb[COLOR_3DHILIGHT]))
  635. _Set3DPaletteColor(m_rgb[COLOR_3DHILIGHT], COLOR_3DHILIGHT);
  636. }
  637. }
  638. }
  639. for (i = 0; i < COLOR_MAX; i++)
  640. {
  641. if (m_brushes[i])
  642. DeleteObject(m_brushes[i]);
  643. m_brushes[i] = CreateSolidBrush(_NearestColor(i, m_rgb[i]));
  644. }
  645. if (m_iCurElement >= 0)
  646. {
  647. // we changed the brushes out from under the buttons...
  648. _SetColor(NULL, IDC_ADVAP_MAINCOLOR, ((ELCUR.iMainColor != COLOR_NONE) ? m_brushes[ELCUR.iMainColor] : NULL));
  649. _SetColor(NULL, IDC_ADVAP_GRADIENT, ((ELCUR.iGradientColor != COLOR_NONE) ? m_brushes[ELCUR.iGradientColor] : NULL));
  650. _SetColor(NULL, IDC_ADVAP_TEXTCOLOR, ((ELCUR.iTextColor != COLOR_NONE) ? m_brushes[ELCUR.iTextColor] : NULL));
  651. }
  652. }
  653. HRESULT CAdvAppearancePage::_InitColorAndPalette(void)
  654. {
  655. m_bPalette = FALSE;
  656. HDC hdc = GetDC(NULL);
  657. if (hdc)
  658. {
  659. m_bPalette = GetDeviceCaps(hdc, RASTERCAPS) & RC_PALETTE;
  660. ReleaseDC(NULL, hdc);
  661. }
  662. DWORD pal[21];
  663. HPALETTE hpal = (HPALETTE) GetStockObject(DEFAULT_PALETTE);
  664. pal[1] = RGB(255, 255, 255);
  665. pal[2] = RGB(0, 0, 0 );
  666. pal[3] = RGB(192, 192, 192);
  667. pal[4] = RGB(128, 128, 128);
  668. pal[5] = RGB(255, 0, 0 );
  669. pal[6] = RGB(128, 0, 0 );
  670. pal[7] = RGB(255, 255, 0 );
  671. pal[8] = RGB(128, 128, 0 );
  672. pal[9] = RGB(0 , 255, 0 );
  673. pal[10] = RGB(0 , 128, 0 );
  674. pal[11] = RGB(0 , 255, 255);
  675. pal[12] = RGB(0 , 128, 128);
  676. pal[13] = RGB(0 , 0, 255);
  677. pal[14] = RGB(0 , 0, 128);
  678. pal[15] = RGB(255, 0, 255);
  679. pal[16] = RGB(128, 0, 128);
  680. if (GetPaletteEntries(hpal, 11, 1, (LPPALETTEENTRY)&pal[17]))
  681. {
  682. pal[0] = MAKELONG(0x300, 17);
  683. m_hpalVGA = CreatePalette((LPLOGPALETTE)pal);
  684. // get magic colors
  685. if (GetPaletteEntries(hpal, 8, 4, (LPPALETTEENTRY)&pal[17]))
  686. {
  687. pal[0] = MAKELONG(0x300, 20);
  688. m_hpal3D = CreatePalette((LPLOGPALETTE)pal);
  689. }
  690. }
  691. return S_OK;
  692. }
  693. // get all of the interesting system information and put it in the tables
  694. HRESULT CAdvAppearancePage::_InitSysStuff(void)
  695. {
  696. int nIndex;
  697. _InitColorAndPalette();
  698. // clean out the memory
  699. for (nIndex = 0; nIndex < ARRAYSIZE(m_fonts); nIndex++)
  700. {
  701. m_fonts[nIndex].hfont = NULL;
  702. }
  703. // build all the brushes/fonts we need
  704. _RebuildSysStuff(TRUE);
  705. // Get the current System and User charsets based on locales and UI languages.
  706. _InitUniqueCharsetArray();
  707. return S_OK;
  708. }
  709. /*
  710. ** clean up any mess made in maintaining system information
  711. ** also, write out any global changes in our setup.
  712. */
  713. void CAdvAppearancePage::_DestroySysStuff(void)
  714. {
  715. int i;
  716. HKEY hkAppear;
  717. SelectObject(g_hdcMem, GetStockObject(BLACK_BRUSH));
  718. SelectObject(g_hdcMem, GetStockObject(SYSTEM_FONT));
  719. _FreeFonts();
  720. for (i = 0; i < COLOR_MAX; i++)
  721. {
  722. if (m_brushes[i])
  723. {
  724. DeleteObject(m_brushes[i]);
  725. m_brushes[i] = NULL;
  726. }
  727. }
  728. m_hbrGradientColor = m_hbrMainColor = m_hbrTextColor = NULL;
  729. // save out possible changes to custom color table
  730. if (RegOpenKeyEx(HKEY_CURRENT_USER, REGSTR_PATH_APPEARANCE, 0, KEY_WRITE, &hkAppear) == ERROR_SUCCESS)
  731. {
  732. RegSetValueEx(hkAppear, REGSTR_VAL_CUSTOMCOLORS, 0L, REG_BINARY,
  733. (LPBYTE)g_CustomColors, sizeof(g_CustomColors));
  734. RegCloseKey(hkAppear);
  735. }
  736. // reset these so they init properly
  737. m_iCurElement = CURRENT_ELEMENT_NONE;
  738. m_iPrevSize = SIZE_NONE;
  739. m_bPalette = FALSE;
  740. m_fInUserEditMode = FALSE;
  741. }
  742. //------------------------ mini font picker controls --------------------------
  743. // Add a facename/script combination to the font dropdown combo list.
  744. //
  745. // The strings are formatted as "FaceName (ScriptName)"
  746. INT Font_AddNameToList(HWND hwndList, LPTSTR pszFace, LPTSTR pszScript)
  747. {
  748. // Create temp buffer to hold a face name, a script name, one space
  749. // two parens and a NUL char.
  750. //
  751. // i.e.: "Arial (Western)"
  752. #ifdef DEBUG
  753. TCHAR szFaceAndScript[LF_FACESIZE + LF_FACESIZE + 4];
  754. #endif //DEBUG
  755. LPTSTR pszDisplayName = pszFace;
  756. INT iItem;
  757. // We decided not to show the scriptnames; Only facenames will be shown.
  758. // For the purpose of debugging, I leave the script name in debug versions only.
  759. #ifdef DEBUG
  760. if (NULL != pszScript && TEXT('\0') != *pszScript)
  761. {
  762. //
  763. // Font has a script name. Append it to the facename in parens.
  764. // This format string controls the appearance of the font names
  765. // in the list. If you change this, you must also change the
  766. // extraction logic in Font_GetNameFromList().
  767. //
  768. StringCchPrintf(szFaceAndScript, ARRAYSIZE(szFaceAndScript), TEXT("%s(%s)"), pszFace, pszScript);
  769. pszDisplayName = szFaceAndScript;
  770. }
  771. #endif //DEBUG
  772. //
  773. // Add the display name string to the listbox.
  774. //
  775. iItem = (INT)SendMessage(hwndList, CB_ADDSTRING, 0, (LPARAM)pszDisplayName);
  776. if (CB_ERR != iItem)
  777. {
  778. //
  779. // Ensure the drop-down combo list will show the entire string.
  780. //
  781. HDC hdc = GetDC(hwndList);
  782. if (NULL != hdc)
  783. {
  784. SIZE sizeItem;
  785. //
  786. // Make sure the list's font is selected into the DC before
  787. // calculating the text extent.
  788. //
  789. HFONT hfontList = (HFONT)SendMessage(hwndList, WM_GETFONT, 0, 0);
  790. HFONT hfontOld = (HFONT)SelectObject(hdc, hfontList);
  791. if (GetTextExtentPoint32(hdc, pszDisplayName, lstrlen(pszDisplayName), &sizeItem))
  792. {
  793. //
  794. // Get the current width of the dropped list.
  795. //
  796. INT cxList = (int)SendMessage(hwndList, CB_GETDROPPEDWIDTH, 0, 0);
  797. //
  798. // We need the length of this string plus two
  799. // widths of a vertical scroll bar.
  800. //
  801. sizeItem.cx += (ClassicGetSystemMetrics(SM_CXVSCROLL) * 2);
  802. if (sizeItem.cx > cxList)
  803. {
  804. //
  805. // List is not wide enough. Increase the width.
  806. //
  807. SendMessage(hwndList, CB_SETDROPPEDWIDTH, (WPARAM)sizeItem.cx, 0);
  808. }
  809. }
  810. SelectObject(hdc, hfontOld);
  811. ReleaseDC(hwndList, hdc);
  812. }
  813. }
  814. return iItem;
  815. }
  816. // Retrieve a font name from the font dropdown combo list.
  817. // Optionally, retrieve the script name string.
  818. BOOL Font_GetNameFromList(
  819. HWND hwndList, // HWND of combo.
  820. INT iItem, // Index of item in list.
  821. LPTSTR pszFace, // Destination for face name.
  822. INT cchFaceMax, // Chars in face name buffer.
  823. LPTSTR pszScript, // Optional. Can be NULL
  824. INT cchScriptMax // Optional. Ignored if pszScript is NULL
  825. )
  826. {
  827. BOOL bResult = FALSE;
  828. TCHAR szItemText[LF_FACESIZE + LF_FACESIZE + 4];
  829. if (pszScript)
  830. {
  831. pszScript[0] = L'\0';
  832. }
  833. if (CB_ERR != SendMessage(hwndList, CB_GETLBTEXT, (WPARAM)iItem, (LPARAM)szItemText))
  834. {
  835. LPTSTR pszEnd, pszParen; // Lookahead pointer
  836. LPCTSTR pszStart = pszEnd = pszParen = szItemText; // "Start" anchor pointer.
  837. //
  838. // Find the left paren.
  839. //
  840. for ( ; *pszEnd; pszEnd++) {
  841. if (TEXT('(') == *pszEnd)
  842. pszParen = pszEnd;
  843. }
  844. if(pszParen > pszStart) //Did we find a parenthis?
  845. pszEnd = pszParen; // Then that is the end of the facename.
  846. if (pszEnd > pszStart)
  847. {
  848. // Found it. Copy face name.
  849. INT cchCopy = (int)(pszEnd - pszStart) + 1; //Add one for the null terminator
  850. if (cchCopy > cchFaceMax)
  851. cchCopy = cchFaceMax;
  852. StringCchCopy(pszFace, cchCopy, pszStart); //(cchCopy-1) bytes are copies followed by a null
  853. bResult = TRUE;
  854. if (*pszEnd && (NULL != pszScript))
  855. {
  856. // Caller wants the script part also.
  857. pszStart = ++pszEnd;
  858. // Find the right paren.
  859. while(*pszEnd && TEXT(')') != *pszEnd)
  860. pszEnd++;
  861. if (*pszEnd && pszEnd > pszStart)
  862. {
  863. // Found it. Copy script name.
  864. cchCopy = (int)(pszEnd - pszStart) + 1;
  865. if (cchCopy > cchScriptMax)
  866. cchCopy = cchScriptMax;
  867. StringCchCopy(pszScript, cchCopy, pszStart);
  868. }
  869. }
  870. }
  871. }
  872. return bResult;
  873. }
  874. // Locate a facename/charset pair in the font list.
  875. INT Font_FindInList(HWND hwndList, LPCTSTR pszFaceName)
  876. {
  877. INT cItems = (int)SendMessage(hwndList, CB_GETCOUNT, 0, 0);
  878. INT i;
  879. for (i = 0; i < cItems; i++)
  880. {
  881. // All items in the fontlist have the same charset (SYSTEM_LOCALE_CHARSET).So, no point
  882. // in checking for the charset.
  883. //
  884. // Let's just get the facename and see if it matches.
  885. TCHAR szFaceName[LF_FACESIZE + 1];
  886. Font_GetNameFromList(hwndList, i, szFaceName, ARRAYSIZE(szFaceName), NULL, 0);
  887. if (0 == lstrcmpi(szFaceName, pszFaceName))
  888. {
  889. //
  890. // Face name matches.
  891. //
  892. return i;
  893. }
  894. }
  895. // No match found.
  896. return -1;
  897. }
  898. // Determine if a given font should be included in the font list.
  899. //
  900. // dwType arg is DEVICE_FONTTYPE, RASTER_FONTTYPE, TRUETYPE_FONTTYPE.
  901. // EXTERNAL_FONTTYPE is a private code. These are the
  902. // values returned to the enumproc from GDI.
  903. BOOL Font_IncludeInList(
  904. LPENUMLOGFONTEX lpelf,
  905. DWORD dwType
  906. )
  907. {
  908. BOOL bResult = TRUE; // Assume it's OK to include.
  909. BYTE lfCharSet = lpelf->elfLogFont.lfCharSet;
  910. #define EXTERNAL_FONTTYPE 8
  911. // Exclusions:
  912. //
  913. // 1. Don't display WIFE font for appearance because WIFE fonts are not
  914. // allowed to be any system use font such as menu/caption as it
  915. // realizes the font before WIFE gets initialized. B#5427
  916. //
  917. // 2. Exclude SYMBOL fonts.
  918. //
  919. // 3. Exclude OEM fonts.
  920. //
  921. // 4. Exclude vertical fonts.
  922. if (EXTERNAL_FONTTYPE & dwType ||
  923. lfCharSet == SYMBOL_CHARSET ||
  924. lfCharSet == OEM_CHARSET ||
  925. TEXT('@') == lpelf->elfLogFont.lfFaceName[0])
  926. {
  927. bResult = FALSE;
  928. }
  929. return bResult;
  930. }
  931. int CALLBACK Font_EnumNames(LPENUMLOGFONTEX lpelf, LPNEWTEXTMETRIC lpntm, DWORD dwType, LPARAM lData)
  932. {
  933. ENUMFONTPARAM * pEnumFontParam = (ENUMFONTPARAM *)lData;
  934. return pEnumFontParam->pThis->_EnumFontNames(lpelf, lpntm, dwType, pEnumFontParam);
  935. }
  936. int CAdvAppearancePage::_EnumFontNames(LPENUMLOGFONTEX lpelf, LPNEWTEXTMETRIC lpntm, DWORD Type, ENUMFONTPARAM * pEnumFontParam)
  937. {
  938. // Should font be included in the "Font" list?
  939. if (Font_IncludeInList(lpelf, Type))
  940. {
  941. int j;
  942. LOGFONT lf = lpelf->elfLogFont; //Make a local copy of the given font
  943. BYTE bSysCharset = lf.lfCharSet; //Preserve the system charset we got.
  944. BOOL fSupportsAllCharsets = TRUE;
  945. //The given font supports the system charset; Let's check if it supports the other charsets
  946. for(j = 1; j < m_iCountCharsets; j++)
  947. {
  948. lf.lfCharSet = (BYTE)m_uiUniqueCharsets[j]; //Let's try the next charset in the array.
  949. if(EnumFontFamiliesEx(pEnumFontParam->hdc, &lf, (FONTENUMPROC)Font_EnumValidCharsets, (LPARAM)0, 0) != 0)
  950. {
  951. // EnumFontFamiliesEx would have returned a zero if Font_EnumValidCharsets was called
  952. // even once. In other words, it returned a non-zero because not even a single font existed
  953. // that supported the given charset. Therefore, we need to skip this font.
  954. fSupportsAllCharsets = FALSE;
  955. break;
  956. }
  957. }
  958. if(fSupportsAllCharsets)
  959. {
  960. int i;
  961. // Yep. Add it to the list.
  962. i = Font_AddNameToList(pEnumFontParam->hwndFontName, lpelf->elfLogFont.lfFaceName, lpelf->elfScript);
  963. if (i != CB_ERR)
  964. {
  965. // Remember the font type and charset in the itemdata.
  966. //
  967. // LOWORD = Type
  968. // HIWORD = System Charset
  969. SendMessage(pEnumFontParam->hwndFontName, CB_SETITEMDATA, (WPARAM)i, MAKELPARAM(Type, bSysCharset));
  970. }
  971. }
  972. }
  973. return 1;
  974. }
  975. void CAdvAppearancePage::_InitFontList(HWND hDlg)
  976. {
  977. LOGFONT lf;
  978. ENUMFONTPARAM EnumFontParam;
  979. // Enumerate all fonts on the system.
  980. // _EnumFontNames will filter out ones we don't want to show.
  981. lf.lfFaceName[0] = TEXT('\0') ;
  982. lf.lfCharSet = (BYTE)m_uiUniqueCharsets[SYSTEM_LOCALE_CHARSET]; //Use charset from the System Locale.
  983. lf.lfPitchAndFamily = 0;
  984. EnumFontParam.hwndFontName = GetDlgItem(hDlg, IDC_ADVAP_FONTNAME);
  985. EnumFontParam.hdc = GetDC(NULL);
  986. EnumFontParam.pThis = this;
  987. EnumFontFamiliesEx(EnumFontParam.hdc, &lf, (FONTENUMPROC)Font_EnumNames, (LPARAM)&EnumFontParam, 0);
  988. ReleaseDC(NULL, EnumFontParam.hdc);
  989. }
  990. void Font_AddSize(HWND hwndPoints, int iNewPoint, BOOL bSort)
  991. {
  992. TCHAR szBuf[10];
  993. int i, iPoint, count;
  994. // find the sorted place for this point size
  995. if (bSort)
  996. {
  997. count = (int)SendMessage(hwndPoints, CB_GETCOUNT, 0, 0L);
  998. for (i=0; i < count; i++)
  999. {
  1000. iPoint = LOWORD(SendMessage(hwndPoints, CB_GETITEMDATA, (WPARAM)i, 0L));
  1001. // don't add duplicates
  1002. if (iPoint == iNewPoint)
  1003. return;
  1004. // belongs before this one
  1005. if (iPoint > iNewPoint)
  1006. break;
  1007. }
  1008. }
  1009. else
  1010. i = -1;
  1011. StringCchPrintf(szBuf, ARRAYSIZE(szBuf), TEXT("%d"), iNewPoint);
  1012. i = (int)SendMessage(hwndPoints, CB_INSERTSTRING, (WPARAM)i, (LPARAM)szBuf);
  1013. if (i != CB_ERR)
  1014. SendMessage(hwndPoints, CB_SETITEMDATA, (WPARAM)i, (LPARAM)iNewPoint);
  1015. }
  1016. // enumerate sizes for a non-TrueType font
  1017. int CALLBACK Font_EnumSizes(LPENUMLOGFONT lpelf, LPNEWTEXTMETRIC lpntm, int Type, LPARAM lData)
  1018. {
  1019. CAdvAppearancePage * pThis = (CAdvAppearancePage *) lData;
  1020. if (pThis)
  1021. {
  1022. return pThis->_EnumSizes(lpelf, lpntm, Type);
  1023. }
  1024. return 1;
  1025. }
  1026. int CAdvAppearancePage::_EnumSizes(LPENUMLOGFONT lpelf, LPNEWTEXTMETRIC lpntm, int Type)
  1027. {
  1028. if (lpntm && _hwnd)
  1029. {
  1030. HWND hwndFontSize = GetDlgItem(_hwnd, IDC_ADVAP_FONTSIZE);
  1031. Font_AddSize(hwndFontSize, _HeightToPoint(lpntm->tmHeight - lpntm->tmInternalLeading), TRUE);
  1032. }
  1033. return 1;
  1034. }
  1035. // a new element was picked, resulting in needing to set up a new font.
  1036. void CAdvAppearancePage::_NewFont(HWND hDlg, int iFont)
  1037. {
  1038. int iSel;
  1039. BOOL bBold;
  1040. // find the name in the list and select it
  1041. iSel = Font_FindInList(GetDlgItem(hDlg, IDC_ADVAP_FONTNAME), m_fonts[iFont].lf.lfFaceName);
  1042. SendDlgItemMessage(hDlg, IDC_ADVAP_FONTNAME, CB_SETCURSEL, (WPARAM)iSel, 0L);
  1043. _SelectName(hDlg, iSel);
  1044. Font_SelectSize(hDlg, _HeightToPoint(m_fonts[iFont].lf.lfHeight));
  1045. // REVIEW: should new size (returned above) be set in logfont?
  1046. CheckDlgButton(hDlg, IDC_ADVAP_FONTITAL, m_fonts[iFont].lf.lfItalic);
  1047. if (m_fonts[iFont].lf.lfWeight > FW_MEDIUM)
  1048. bBold = TRUE;
  1049. else
  1050. bBold = FALSE;
  1051. CheckDlgButton(hDlg, IDC_ADVAP_FONTBOLD, bBold);
  1052. }
  1053. // enable/disable the font selection controls.
  1054. // also involves blanking out anything meaningful if disabling.
  1055. void Font_EnableControls(HWND hDlg, BOOL bEnable)
  1056. {
  1057. if (!bEnable)
  1058. {
  1059. SendDlgItemMessage(hDlg, IDC_ADVAP_FONTNAME, CB_SETCURSEL, (WPARAM)-1, 0L);
  1060. SendDlgItemMessage(hDlg, IDC_ADVAP_FONTSIZE, CB_SETCURSEL, (WPARAM)-1, 0L);
  1061. CheckDlgButton(hDlg, IDC_ADVAP_FONTITAL, 0);
  1062. CheckDlgButton(hDlg, IDC_ADVAP_FONTBOLD, 0);
  1063. }
  1064. EnableWindow(GetDlgItem(hDlg, IDC_ADVAP_FONTNAME), bEnable);
  1065. EnableWindow(GetDlgItem(hDlg, IDC_ADVAP_FONTSIZE), bEnable);
  1066. EnableWindow(GetDlgItem(hDlg, IDC_ADVAP_FONTSIZELABEL), bEnable);
  1067. EnableWindow(GetDlgItem(hDlg, IDC_ADVAP_FONTLABEL), bEnable);
  1068. EnableWindow(GetDlgItem(hDlg, IDC_ADVAP_FONTBOLD), bEnable);
  1069. EnableWindow(GetDlgItem(hDlg, IDC_ADVAP_FONTITAL), bEnable);
  1070. }
  1071. //--------end------------- mini font picker controls --------------------------
  1072. void CAdvAppearancePage::_SetColor(HWND hDlg, int id, HBRUSH hbrColor)
  1073. {
  1074. HWND hwndItem;
  1075. switch (id)
  1076. {
  1077. case IDC_ADVAP_GRADIENT:
  1078. m_hbrGradientColor = hbrColor;
  1079. break;
  1080. case IDC_ADVAP_MAINCOLOR:
  1081. m_hbrMainColor = hbrColor;
  1082. break;
  1083. case IDC_ADVAP_TEXTCOLOR:
  1084. m_hbrTextColor = hbrColor;
  1085. break;
  1086. default:
  1087. return;
  1088. }
  1089. hwndItem = GetDlgItem(hDlg, id);
  1090. if (hwndItem)
  1091. {
  1092. InvalidateRect(hwndItem, NULL, FALSE);
  1093. UpdateWindow(hwndItem);
  1094. }
  1095. }
  1096. void CAdvAppearancePage::_DrawDownArrow(HDC hdc, LPRECT lprc, BOOL bDisabled)
  1097. {
  1098. HBRUSH hbr;
  1099. int x, y;
  1100. x = lprc->right - m_cxEdgeSM - 5;
  1101. y = lprc->top + ((lprc->bottom - lprc->top)/2 - 1);
  1102. if (bDisabled)
  1103. {
  1104. hbr = GetSysColorBrush(COLOR_3DHILIGHT);
  1105. hbr = (HBRUSH) SelectObject(hdc, hbr);
  1106. x++;
  1107. y++;
  1108. PatBlt(hdc, x, y, 5, 1, PATCOPY);
  1109. PatBlt(hdc, x+1, y+1, 3, 1, PATCOPY);
  1110. PatBlt(hdc, x+2, y+2, 1, 1, PATCOPY);
  1111. SelectObject(hdc, hbr);
  1112. x--;
  1113. y--;
  1114. }
  1115. hbr = GetSysColorBrush(bDisabled ? COLOR_3DSHADOW : COLOR_BTNTEXT);
  1116. hbr = (HBRUSH) SelectObject(hdc, hbr);
  1117. PatBlt(hdc, x, y, 5, 1, PATCOPY);
  1118. PatBlt(hdc, x+1, y+1, 3, 1, PATCOPY);
  1119. PatBlt(hdc, x+2, y+2, 1, 1, PATCOPY);
  1120. SelectObject(hdc, hbr);
  1121. lprc->right = x;
  1122. }
  1123. // draw the color combobox thing
  1124. //
  1125. // also, if button was depressed, popup the color picker
  1126. //
  1127. void CAdvAppearancePage::_DrawButton(HWND hDlg, LPDRAWITEMSTRUCT lpdis)
  1128. {
  1129. SIZE thin = { m_cxEdgeSM / 2, m_cyEdgeSM / 2 };
  1130. RECT rc = lpdis->rcItem;
  1131. HDC hdc = lpdis->hDC;
  1132. BOOL bFocus = ((lpdis->itemState & ODS_FOCUS) &&
  1133. !(lpdis->itemState & ODS_DISABLED));
  1134. if (!thin.cx) thin.cx = 1;
  1135. if (!thin.cy) thin.cy = 1;
  1136. if (!m_hTheme)
  1137. {
  1138. if (lpdis->itemState & ODS_SELECTED)
  1139. {
  1140. DrawEdge(hdc, &rc, EDGE_SUNKEN, BF_RECT | BF_ADJUST);
  1141. OffsetRect(&rc, 1, 1);
  1142. }
  1143. else
  1144. {
  1145. DrawEdge(hdc, &rc, EDGE_RAISED, BF_RECT | BF_ADJUST);
  1146. }
  1147. FillRect(hdc, &rc, GetSysColorBrush(COLOR_3DFACE));
  1148. }
  1149. else
  1150. {
  1151. int iStateId;
  1152. if (lpdis->itemState & ODS_SELECTED)
  1153. {
  1154. iStateId = PBS_PRESSED;
  1155. }
  1156. else if (lpdis->itemState & ODS_HOTLIGHT)
  1157. {
  1158. iStateId = PBS_HOT;
  1159. }
  1160. else if (lpdis->itemState & ODS_DISABLED)
  1161. {
  1162. iStateId = PBS_DISABLED;
  1163. }
  1164. else if (lpdis->itemState & ODS_FOCUS)
  1165. {
  1166. iStateId = PBS_DEFAULTED;
  1167. }
  1168. else
  1169. {
  1170. iStateId = PBS_NORMAL;
  1171. }
  1172. DrawThemeBackground(m_hTheme, hdc, BP_PUSHBUTTON, iStateId, &rc, 0);
  1173. GetThemeBackgroundContentRect(m_hTheme, hdc, BP_PUSHBUTTON, iStateId, &rc, &rc);
  1174. }
  1175. if (bFocus)
  1176. {
  1177. InflateRect(&rc, -thin.cx, -thin.cy);
  1178. DrawFocusRect(hdc, &rc);
  1179. InflateRect(&rc, thin.cx, thin.cy);
  1180. }
  1181. InflateRect(&rc, 1-thin.cx, -m_cyEdgeSM);
  1182. rc.left += m_cxEdgeSM;
  1183. _DrawDownArrow(hdc, &rc, lpdis->itemState & ODS_DISABLED);
  1184. InflateRect(&rc, -thin.cx, 0);
  1185. DrawEdge(hdc, &rc, EDGE_ETCHED, BF_RIGHT);
  1186. rc.right -= ( 2 * m_cxEdgeSM ) + thin.cx;
  1187. // color sample
  1188. if ( !(lpdis->itemState & ODS_DISABLED) )
  1189. {
  1190. HPALETTE hpalOld = NULL;
  1191. HBRUSH hbr = 0;
  1192. switch (lpdis->CtlID)
  1193. {
  1194. case IDC_ADVAP_GRADIENT:
  1195. hbr = m_hbrGradientColor;
  1196. break;
  1197. case IDC_ADVAP_MAINCOLOR:
  1198. hbr = m_hbrMainColor;
  1199. break;
  1200. case IDC_ADVAP_TEXTCOLOR:
  1201. hbr = m_hbrTextColor;
  1202. break;
  1203. }
  1204. FrameRect(hdc, &rc, GetSysColorBrush(COLOR_BTNTEXT));
  1205. InflateRect(&rc, -thin.cx, -thin.cy);
  1206. if (m_hpal3D)
  1207. {
  1208. hpalOld = SelectPalette(hdc, m_hpal3D, FALSE);
  1209. RealizePalette(hdc);
  1210. }
  1211. if (hbr)
  1212. {
  1213. hbr = (HBRUSH) SelectObject(hdc, hbr);
  1214. PatBlt(hdc, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, PATCOPY);
  1215. SelectObject(hdc, hbr);
  1216. }
  1217. if (hpalOld)
  1218. {
  1219. SelectPalette(hdc, hpalOld, TRUE);
  1220. RealizePalette(hdc);
  1221. }
  1222. }
  1223. }
  1224. //--------end------------- color stuff --------------------------------------
  1225. void LoadCustomColors(void)
  1226. {
  1227. HKEY hkSchemes;
  1228. DWORD dwType, dwSize;
  1229. // if no colors are there, initialize to all white
  1230. for (int nIndex = 0; nIndex < ARRAYSIZE(g_CustomColors); nIndex++)
  1231. {
  1232. g_CustomColors[nIndex] = RGB(255, 255, 255);
  1233. }
  1234. // select the current scheme
  1235. if (RegOpenKeyEx(HKEY_CURRENT_USER, REGSTR_PATH_APPEARANCE, 0, KEY_READ, &hkSchemes) == ERROR_SUCCESS)
  1236. {
  1237. // also, since this key is already open, get the custom colors
  1238. dwSize = sizeof(g_CustomColors);
  1239. dwType = REG_BINARY;
  1240. // It's okay if this call fails. We handle the case where the user
  1241. // didn't create custom colors.
  1242. RegQueryValueEx(hkSchemes, REGSTR_VAL_CUSTOMCOLORS, NULL, &dwType, (LPBYTE)g_CustomColors, &dwSize);
  1243. RegCloseKey(hkSchemes);
  1244. }
  1245. }
  1246. HRESULT CAdvAppearancePage::_SelectElement(HWND hDlg, int iElement, DWORD dwFlags)
  1247. {
  1248. BOOL bEnable;
  1249. int i;
  1250. BOOL bEnableGradient;
  1251. BOOL bGradient = FALSE;
  1252. if ((iElement == m_iCurElement) && !(dwFlags & LSE_ALWAYS))
  1253. {
  1254. return S_OK;
  1255. }
  1256. ClassicSystemParametersInfo(SPI_GETGRADIENTCAPTIONS, 0, (PVOID)&bGradient, 0);
  1257. m_iCurElement = iElement;
  1258. // if needed, find this element in the combobox and select it
  1259. if (dwFlags & LSE_SETCUR)
  1260. {
  1261. i = (int)SendDlgItemMessage(hDlg, IDC_ADVAP_ELEMENTS, CB_GETCOUNT,0,0L);
  1262. for (i--; i >=0 ; i--)
  1263. {
  1264. // if this is the one that references our element, stop
  1265. if (iElement == (int)LOWORD(SendDlgItemMessage(hDlg, IDC_ADVAP_ELEMENTS, CB_GETITEMDATA, (WPARAM)i, 0L)))
  1266. break;
  1267. }
  1268. SendDlgItemMessage(hDlg, IDC_ADVAP_ELEMENTS, CB_SETCURSEL, (WPARAM)i,0L);
  1269. }
  1270. bEnable = (ELCUR.iMainColor != COLOR_NONE);
  1271. if (bEnable)
  1272. _SetColor(hDlg, IDC_ADVAP_MAINCOLOR, m_brushes[ELCUR.iMainColor]);
  1273. EnableWindow(GetDlgItem(hDlg, IDC_ADVAP_MAINCOLOR), bEnable);
  1274. EnableWindow(GetDlgItem(hDlg, IDC_ADVAP_COLORLABEL), bEnable);
  1275. bEnableGradient = ((ELCUR.iGradientColor != COLOR_NONE));
  1276. if (bEnableGradient)
  1277. _SetColor(hDlg, IDC_ADVAP_GRADIENT, m_brushes[ELCUR.iGradientColor]);
  1278. EnableWindow(GetDlgItem(hDlg, IDC_ADVAP_GRADIENT), (bEnableGradient && bGradient));
  1279. EnableWindow(GetDlgItem(hDlg, IDC_ADVAP_GRADIENTLABEL), (bEnableGradient && bGradient));
  1280. bEnable = (ELCUR.iFont != FONT_NONE);
  1281. if (bEnable)
  1282. {
  1283. _NewFont(hDlg, ELCUR.iFont);
  1284. }
  1285. Font_EnableControls(hDlg, bEnable);
  1286. // size may be based on font
  1287. _DoSizeStuff(hDlg, FALSE);
  1288. bEnable = (ELCUR.iSize != SIZE_NONE);
  1289. EnableWindow(GetDlgItem(hDlg, IDC_ADVAP_MAINSIZE), bEnable);
  1290. EnableWindow(GetDlgItem(hDlg, IDC_ADVAP_SIZEARROWS), bEnable);
  1291. EnableWindow(GetDlgItem(hDlg, IDC_ADVAP_SIZELABEL), bEnable);
  1292. bEnable = (ELCUR.iTextColor != COLOR_NONE);
  1293. if (bEnable)
  1294. _SetColor(hDlg, IDC_ADVAP_TEXTCOLOR, m_brushes[ELCUR.iTextColor]);
  1295. EnableWindow(GetDlgItem(hDlg, IDC_ADVAP_TEXTCOLOR), bEnable);
  1296. EnableWindow(GetDlgItem(hDlg, IDC_ADVAP_FNCOLORLABEL), bEnable);
  1297. return S_OK;
  1298. }
  1299. void CAdvAppearancePage::_Repaint(HWND hDlg, BOOL bRecalc)
  1300. {
  1301. HWND hwndLookPrev;
  1302. hwndLookPrev = GetDlgItem(hDlg, IDC_ADVAP_LOOKPREV);
  1303. if (bRecalc)
  1304. {
  1305. _SyncSize(hDlg);
  1306. RECT rc;
  1307. GetClientRect(hwndLookPrev, &rc);
  1308. _Recalc(&rc);
  1309. }
  1310. _RepaintPreview(hwndLookPrev);
  1311. }
  1312. void CAdvAppearancePage::_SetCurSizeAndRange(HWND hDlg)
  1313. {
  1314. if (ELCUR.iSize == SIZE_NONE)
  1315. SetDlgItemText(hDlg, IDC_ADVAP_MAINSIZE, TEXT(""));
  1316. else
  1317. {
  1318. SendDlgItemMessage(hDlg, IDC_ADVAP_SIZEARROWS, UDM_SETRANGE, 0,
  1319. MAKELPARAM(m_elCurrentSize.MaxSize, m_elCurrentSize.MinSize));
  1320. SetDlgItemInt(hDlg, IDC_ADVAP_MAINSIZE, m_elCurrentSize.CurSize, TRUE);
  1321. }
  1322. }
  1323. void CAdvAppearancePage::_SyncSize(HWND hDlg)
  1324. {
  1325. if (m_iPrevSize != SIZE_NONE)
  1326. m_sizes[m_iPrevSize].CurSize = m_elCurrentSize.CurSize;
  1327. if (m_iCurElement >= 0)
  1328. m_iPrevSize = ELCUR.iSize;
  1329. }
  1330. void CAdvAppearancePage::_UpdateSizeBasedOnFont(HWND hDlg, BOOL fComputeIdeal)
  1331. {
  1332. if ((ELCUR.iSize != SIZE_NONE) && (ELCUR.iFont != FONT_NONE))
  1333. {
  1334. TEXTMETRIC tm;
  1335. HFONT hfontOld = (HFONT) SelectObject(g_hdcMem, ELCURFONT.hfont);
  1336. GetTextMetrics(g_hdcMem, &tm);
  1337. if (ELCUR.iSize == SIZE_MENU)
  1338. {
  1339. // Include external leading for menus
  1340. tm.tmHeight += tm.tmExternalLeading;
  1341. }
  1342. if (hfontOld)
  1343. {
  1344. SelectObject(g_hdcMem, hfontOld);
  1345. }
  1346. m_elCurrentSize.MinSize = tm.tmHeight + 2 * m_cyBorderSM;
  1347. if (fComputeIdeal)
  1348. {
  1349. if ((ELCUR.iSize == SIZE_CAPTION || ELCUR.iSize == SIZE_MENU) &&
  1350. (m_elCurrentSize.MinSize < (ClassicGetSystemMetrics(SM_CYICON)/2 + 2 * m_cyBorderSM)))
  1351. {
  1352. m_elCurrentSize.CurSize = ClassicGetSystemMetrics(SM_CYICON)/2 + 2 * m_cyBorderSM;
  1353. }
  1354. else
  1355. {
  1356. m_elCurrentSize.CurSize = m_elCurrentSize.MinSize;
  1357. }
  1358. }
  1359. else if (m_elCurrentSize.CurSize < m_elCurrentSize.MinSize)
  1360. {
  1361. m_elCurrentSize.CurSize = m_elCurrentSize.MinSize;
  1362. }
  1363. }
  1364. }
  1365. void CAdvAppearancePage::_DoSizeStuff(HWND hDlg, BOOL fCanSuggest)
  1366. {
  1367. _SyncSize(hDlg);
  1368. if (ELCUR.iSize != SIZE_NONE)
  1369. {
  1370. m_elCurrentSize = m_sizes[ELCUR.iSize];
  1371. if (ELCUR.fLinkSizeToFont)
  1372. {
  1373. _UpdateSizeBasedOnFont(hDlg, fCanSuggest);
  1374. }
  1375. if (m_elCurrentSize.CurSize < m_elCurrentSize.MinSize)
  1376. {
  1377. m_elCurrentSize.CurSize = m_elCurrentSize.MinSize;
  1378. }
  1379. else if (m_elCurrentSize.CurSize > m_elCurrentSize.MaxSize)
  1380. {
  1381. m_elCurrentSize.CurSize = m_elCurrentSize.MaxSize;
  1382. }
  1383. }
  1384. _SetCurSizeAndRange(hDlg);
  1385. }
  1386. void CAdvAppearancePage::_RebuildCurFont(HWND hDlg)
  1387. {
  1388. if (ELCURFONT.hfont)
  1389. DeleteObject(ELCURFONT.hfont);
  1390. ELCURFONT.hfont = CreateFontIndirect(&ELCURFONT.lf);
  1391. _DoSizeStuff(hDlg, TRUE);
  1392. _Repaint(hDlg, TRUE);
  1393. }
  1394. void CAdvAppearancePage::_Changed(HWND hDlg, DWORD dwChange)
  1395. {
  1396. if (m_fInUserEditMode)
  1397. {
  1398. if ((dwChange != SCHEME_CHANGE) && (dwChange != DPI_CHANGE))
  1399. {
  1400. // We keep track if we have customized settings from the stock Scheme.
  1401. m_fModifiedScheme = TRUE;
  1402. }
  1403. else
  1404. {
  1405. dwChange = METRIC_CHANGE | COLOR_CHANGE;
  1406. }
  1407. m_dwChanged |= dwChange;
  1408. }
  1409. }
  1410. void CAdvAppearancePage::_ChangeFontName(HWND hDlg, LPCTSTR szBuf, INT iCharSet)
  1411. {
  1412. if (lstrcmpi(ELCURFONT.lf.lfFaceName, szBuf) == 0 &&
  1413. ELCURFONT.lf.lfCharSet == iCharSet)
  1414. {
  1415. return;
  1416. }
  1417. StringCchCopy(ELCURFONT.lf.lfFaceName, ARRAYSIZE(ELCURFONT.lf.lfFaceName), szBuf);
  1418. ELCURFONT.lf.lfCharSet = (BYTE)iCharSet;
  1419. _RebuildCurFont(hDlg);
  1420. _Changed(hDlg, METRIC_CHANGE);
  1421. }
  1422. void CAdvAppearancePage::_ChangeFontSize(HWND hDlg, int Points)
  1423. {
  1424. if (ELCURFONT.lf.lfHeight != _PointToHeight(Points))
  1425. {
  1426. ELCURFONT.lf.lfHeight = _PointToHeight(Points);
  1427. _RebuildCurFont(hDlg);
  1428. _Changed(hDlg, METRIC_CHANGE);
  1429. }
  1430. }
  1431. void CAdvAppearancePage::_ChangeFontBI(HWND hDlg, int id, BOOL bCheck)
  1432. {
  1433. if (id == IDC_ADVAP_FONTBOLD) // bold
  1434. {
  1435. if (bCheck)
  1436. ELCURFONT.lf.lfWeight = FW_BOLD;
  1437. else
  1438. ELCURFONT.lf.lfWeight = FW_NORMAL;
  1439. }
  1440. else // italic
  1441. {
  1442. ELCURFONT.lf.lfItalic = (BYTE)bCheck;
  1443. }
  1444. _RebuildCurFont(hDlg);
  1445. _Changed(hDlg, METRIC_CHANGE);
  1446. }
  1447. void CAdvAppearancePage::_ChangeSize(HWND hDlg, int NewSize, BOOL bRepaint)
  1448. {
  1449. if (m_elCurrentSize.CurSize != NewSize)
  1450. {
  1451. m_elCurrentSize.CurSize = NewSize;
  1452. if (bRepaint)
  1453. {
  1454. _Repaint(hDlg, TRUE);
  1455. }
  1456. _Changed(hDlg, METRIC_CHANGE);
  1457. }
  1458. }
  1459. BOOL CAdvAppearancePage::_ChangeColor(HWND hDlg, int iColor, COLORREF rgb)
  1460. {
  1461. COLORREF rgbShadow, rgbHilight, rgbWatermark;
  1462. if ((rgb & 0x00FFFFFF) == (m_rgb[iColor] & 0x00FFFFFF))
  1463. return FALSE;
  1464. if (iColor == COLOR_3DFACE)
  1465. {
  1466. rgbShadow = AdjustLuma(rgb, m_i3DShadowAdj, m_fScale3DShadowAdj);
  1467. rgbHilight = AdjustLuma(rgb, m_i3DHilightAdj, m_fScale3DHilightAdj);
  1468. rgbWatermark = AdjustLuma(rgb, m_iWatermarkAdj, m_fScaleWatermarkAdj);
  1469. _Set3DPaletteColor(rgb, COLOR_3DFACE);
  1470. _Set3DPaletteColor(rgbShadow, COLOR_3DSHADOW);
  1471. _Set3DPaletteColor(rgbHilight, COLOR_3DHILIGHT);
  1472. // update colors tagged to 3DFACE
  1473. m_rgb[COLOR_3DFACE] = rgb;
  1474. m_rgb[COLOR_3DLIGHT] = rgb; // BOGUS TEMPORARY
  1475. m_rgb[COLOR_ACTIVEBORDER] = rgb;
  1476. m_rgb[COLOR_INACTIVEBORDER] = rgb;
  1477. m_rgb[COLOR_MENU] = rgb;
  1478. // update colors tagged to 3DSHADOW
  1479. m_rgb[COLOR_GRAYTEXT] = rgbShadow;
  1480. m_rgb[COLOR_APPWORKSPACE] = rgbShadow;
  1481. m_rgb[COLOR_3DSHADOW] = rgbShadow;
  1482. m_rgb[COLOR_INACTIVECAPTION] = rgbShadow;
  1483. // update colors tagged to 3DHIGHLIGHT
  1484. m_rgb[COLOR_3DHILIGHT] = rgbHilight;
  1485. m_rgb[COLOR_SCROLLBAR] = rgbHilight;
  1486. if ((m_rgb[COLOR_SCROLLBAR] & 0x00FFFFFF) ==
  1487. (m_rgb[COLOR_WINDOW] & 0x00FFFFFF))
  1488. {
  1489. m_rgb[COLOR_SCROLLBAR] = RGB( 192, 192, 192 );
  1490. }
  1491. }
  1492. else
  1493. {
  1494. m_rgb[iColor] = rgb;
  1495. }
  1496. _RebuildSysStuff(FALSE);
  1497. _Changed(hDlg, COLOR_CHANGE);
  1498. return TRUE;
  1499. }
  1500. void CAdvAppearancePage::_PropagateMessage(HWND hwnd, UINT uMessage, WPARAM wParam, LPARAM lParam)
  1501. {
  1502. HWND hwndChild;
  1503. // Don't propagate during exit since this is only for good looks, and the Up/Down's
  1504. // get confused if they get a WM_SETTINGSHCANGED while they are getting destroyed
  1505. if (m_fProprtySheetExiting)
  1506. return;
  1507. for (hwndChild = ::GetWindow(hwnd, GW_CHILD); hwndChild != NULL;
  1508. hwndChild = ::GetWindow(hwndChild, GW_HWNDNEXT))
  1509. {
  1510. #ifdef DBG_PRINT
  1511. TCHAR szTmp[256];
  1512. GetClassName(hwndChild, szTmp, 256);
  1513. TraceMsg(TF_GENERAL, "desk (PropagateMessage): SendingMessage( 0x%08lX cls:%s, 0x%08X, 0x%08lX, 0x%08lX )\n", hwndChild, szTmp, uMessage, wParam, lParam ));
  1514. #endif
  1515. SendMessage(hwndChild, uMessage, wParam, lParam);
  1516. TraceMsg(TF_GENERAL,"desk (PropagateMessage): back from SendingMessage\n");
  1517. }
  1518. }
  1519. //--------end------------- manage system settings --------------------------
  1520. // Fill in a NONCLIENTMETRICS structure with latest preview stuff
  1521. void CAdvAppearancePage::_GetMyNonClientMetrics(LPNONCLIENTMETRICS lpncm)
  1522. {
  1523. lpncm->iBorderWidth = (LONG)m_sizes[SIZE_FRAME].CurSize;
  1524. lpncm->iScrollWidth = lpncm->iScrollHeight = (LONG)m_sizes[SIZE_SCROLL].CurSize;
  1525. lpncm->iSmCaptionWidth = lpncm->iSmCaptionHeight = (LONG)m_sizes[SIZE_SMCAPTION].CurSize;
  1526. lpncm->iMenuWidth = lpncm->iMenuHeight = (LONG)m_sizes[SIZE_MENU].CurSize;
  1527. // #355378:
  1528. // PRE-WHISTLER: Caption Height always matched Width. They were authored this way and
  1529. // the UI forced them to be the same. I don't know if apps rely on this behavior but they
  1530. // could have. The Status Bar icon is equal to the min(CaptionWidth, CaptionHeight).
  1531. // The user really wants their caption buttons to be square, so that also wants
  1532. // them to be equal. A caption width of 18 makes the icon be 16, anything else causes
  1533. // icon stretch and looks really bad.
  1534. //
  1535. // WHISTLER: In Whistler, our designers want a height of 25 so it looks nicer. They
  1536. // want the width to remain 18 so the icon is 16 pixels (inctlpan.c) in each direction. This means that
  1537. // this code can no longer force them to be even. ScottHan forces the captionbar buttons to
  1538. // be square solving that problem. I will now keep the aspect ratio so I scale them correctly.
  1539. // If we are close, I will snap to 18 to fix rounding errors.
  1540. lpncm->iCaptionHeight = (LONG)m_sizes[SIZE_CAPTION].CurSize;
  1541. lpncm->iCaptionWidth = (int) (m_fCaptionRatio * lpncm->iCaptionHeight);
  1542. // Don't shrink the caption width below 18 point until the caption height also gets below 18.
  1543. if (lpncm->iCaptionWidth < 18 && lpncm->iCaptionHeight >= 18)
  1544. {
  1545. lpncm->iCaptionWidth = 18;
  1546. }
  1547. if ((lpncm->iCaptionWidth <= 19) && (lpncm->iCaptionWidth >= 17) &&
  1548. (1.0f != m_fCaptionRatio))
  1549. {
  1550. // Icons only really look good at 16 pixels, so we need to set lpncm->iCaptionWidth to make the
  1551. // Caption bar icon 16 pixels. (#355378)
  1552. lpncm->iCaptionWidth = 18;
  1553. }
  1554. LFtoLF32(&(m_fonts[FONT_CAPTION].lf), &(lpncm->lfCaptionFont));
  1555. LFtoLF32(&(m_fonts[FONT_SMCAPTION].lf), &(lpncm->lfSmCaptionFont));
  1556. LFtoLF32(&(m_fonts[FONT_MENU].lf), &(lpncm->lfMenuFont));
  1557. LFtoLF32(&(m_fonts[FONT_STATUS].lf), &(lpncm->lfStatusFont));
  1558. LFtoLF32(&(m_fonts[FONT_MSGBOX].lf), &(lpncm->lfMessageFont));
  1559. }
  1560. // given a NONCLIENTMETRICS structure, make it preview's current setting
  1561. void CAdvAppearancePage::_SetMyNonClientMetrics(const LPNONCLIENTMETRICS lpncm)
  1562. {
  1563. m_sizes[SIZE_FRAME].CurSize = (int)lpncm->iBorderWidth;
  1564. m_sizes[SIZE_SCROLL].CurSize = (int)lpncm->iScrollWidth;
  1565. m_sizes[SIZE_SMCAPTION].CurSize = (int)lpncm->iSmCaptionHeight;
  1566. m_sizes[SIZE_MENU].CurSize = (int)lpncm->iMenuHeight;
  1567. m_sizes[SIZE_CAPTION].CurSize = (int)lpncm->iCaptionHeight;
  1568. m_fCaptionRatio = ((float) lpncm->iCaptionWidth / (float) lpncm->iCaptionHeight);
  1569. LF32toLF(&(lpncm->lfCaptionFont), &(m_fonts[FONT_CAPTION].lf));
  1570. LF32toLF(&(lpncm->lfSmCaptionFont), &(m_fonts[FONT_SMCAPTION].lf));
  1571. LF32toLF(&(lpncm->lfMenuFont), &(m_fonts[FONT_MENU].lf));
  1572. LF32toLF(&(lpncm->lfStatusFont), &(m_fonts[FONT_STATUS].lf));
  1573. LF32toLF(&(lpncm->lfMessageFont), &(m_fonts[FONT_MSGBOX].lf));
  1574. }
  1575. //--------end------------- scheme stuff --------------------------------------
  1576. HRESULT CAdvAppearancePage::_IsDirty(IN BOOL * pIsDirty)
  1577. {
  1578. HRESULT hr = E_INVALIDARG;
  1579. if (pIsDirty)
  1580. {
  1581. *pIsDirty = (NO_CHANGE != m_dwChanged);
  1582. hr = S_OK;
  1583. }
  1584. return hr;
  1585. }
  1586. //===========================
  1587. // *** IAdvancedDialog Interface ***
  1588. //===========================
  1589. HRESULT CAdvAppearancePage::DisplayAdvancedDialog(IN HWND hwndParent, IN IPropertyBag * pBasePage, IN BOOL * pfEnableApply)
  1590. {
  1591. HRESULT hr = E_INVALIDARG;
  1592. if (hwndParent && pBasePage && pfEnableApply)
  1593. {
  1594. // Load State Into Advanced Dialog
  1595. ATOMICRELEASE(g_pAdvAppearancePage);
  1596. g_pAdvAppearancePage = this;
  1597. AddRef();
  1598. *pfEnableApply = FALSE;
  1599. if (FAILED(SHPropertyBag_ReadInt(pBasePage, SZ_PBPROP_DPI_MODIFIED_VALUE, &m_nCachedNewDPI)))
  1600. {
  1601. m_nCachedNewDPI = DPI_PERSISTED; // Default to the default DPI.
  1602. }
  1603. // Display Advanced Dialog
  1604. if (IDOK == DialogBoxParam(HINST_THISDLL, MAKEINTRESOURCE(DLG_APPEARANCE_ADVANCEDPG), hwndParent, CAdvAppearancePage::AdvAppearDlgProc, (LPARAM)this))
  1605. {
  1606. // The user clicked OK, so merge modified state back into base dialog
  1607. _IsDirty(pfEnableApply);
  1608. // The user clicked Okay in the dialog so merge the dirty state from the
  1609. // advanced dialog into the base dialog.
  1610. int nIndex;
  1611. SYSTEMMETRICSALL state = {0};
  1612. state.dwChanged = m_dwChanged;
  1613. state.schemeData.version = SCHEME_VERSION;
  1614. state.schemeData.wDummy = 0;
  1615. state.schemeData.ncm.cbSize = sizeof(state.schemeData.ncm);
  1616. for (nIndex = 0; nIndex < ARRAYSIZE(m_rgb); nIndex++)
  1617. {
  1618. state.schemeData.rgb[nIndex] = m_rgb[nIndex];
  1619. }
  1620. _GetMyNonClientMetrics(&state.schemeData.ncm);
  1621. // Set Sizes
  1622. state.nDXIcon = m_sizes[SIZE_DXICON].CurSize;
  1623. state.nDYIcon = m_sizes[SIZE_DYICON].CurSize;
  1624. state.nIcon = m_sizes[SIZE_ICON].CurSize;
  1625. state.nSmallIcon = m_sizes[SIZE_SMICON].CurSize;
  1626. state.fModifiedScheme = m_fModifiedScheme;
  1627. // Set Fonts
  1628. state.schemeData.lfIconTitle = m_fonts[FONT_ICONTITLE].lf;
  1629. VARIANT var = {0};
  1630. hr = pBasePage->Read(SZ_PBPROP_SYSTEM_METRICS, &var, NULL);
  1631. if (SUCCEEDED(hr) && (VT_BYREF == var.vt) && var.byref)
  1632. {
  1633. SYSTEMMETRICSALL * pCurrent = (SYSTEMMETRICSALL *) var.byref;
  1634. state.fFlatMenus = pCurrent->fFlatMenus; // Maintain this value.
  1635. state.fHighContrast = pCurrent->fHighContrast; // Maintain this value.
  1636. }
  1637. hr = SHPropertyBag_WriteByRef(pBasePage, SZ_PBPROP_SYSTEM_METRICS, (void *)&state);
  1638. }
  1639. ATOMICRELEASE(g_pAdvAppearancePage);
  1640. }
  1641. return hr;
  1642. }
  1643. //===========================
  1644. // *** IUnknown Interface ***
  1645. //===========================
  1646. ULONG CAdvAppearancePage::AddRef()
  1647. {
  1648. return InterlockedIncrement(&m_cRef);
  1649. }
  1650. ULONG CAdvAppearancePage::Release()
  1651. {
  1652. ASSERT( 0 != m_cRef );
  1653. ULONG cRef = InterlockedDecrement(&m_cRef);
  1654. if ( 0 == cRef )
  1655. {
  1656. delete this;
  1657. }
  1658. return cRef;
  1659. }
  1660. HRESULT CAdvAppearancePage::QueryInterface(REFIID riid, void **ppvObj)
  1661. {
  1662. static const QITAB qit[] = {
  1663. QITABENT(CAdvAppearancePage, IPersist),
  1664. QITABENT(CAdvAppearancePage, IObjectWithSite),
  1665. QITABENT(CAdvAppearancePage, IAdvancedDialog),
  1666. { 0 },
  1667. };
  1668. return QISearch(this, qit, riid, ppvObj);
  1669. }
  1670. int g_nSizeInitArray[9][3] =
  1671. {
  1672. {0, 0, 50}, // SIZE_FRAME
  1673. {0, 8, 100}, // SIZE_SCROLL
  1674. {0, 8, 100}, // SIZE_CAPTION
  1675. {0, 4, 100}, // SIZE_SMCAPTION
  1676. {0, 8, 100}, // SIZE_MENU
  1677. {0, 0, 150}, // SIZE_DXICON - x spacing
  1678. {0, 0, 150}, // SIZE_DYICON - y spacing
  1679. {0, 16, 72}, // SIZE_ICON - shell icon size
  1680. {0, 8, 36},
  1681. };
  1682. //===========================
  1683. // *** Class Methods ***
  1684. //===========================
  1685. CAdvAppearancePage::CAdvAppearancePage(IN const SYSTEMMETRICSALL * pState) : CObjectCLSID(&PPID_AdvAppearance), m_cRef(1)
  1686. {
  1687. int nIndex;
  1688. DllAddRef();
  1689. // This needs to be allocated in Zero Inited Memory.
  1690. // Assert that all Member Variables are inited to Zero.
  1691. ASSERT(!m_hpal3D);
  1692. ASSERT(!m_hpalVGA);
  1693. ASSERT(!m_hbrMainColor);
  1694. ASSERT(!m_hbrTextColor);
  1695. ASSERT(!m_hbrGradientColor);
  1696. m_dwChanged = NO_CHANGE;
  1697. m_iCurElement = CURRENT_ELEMENT_NONE; // start off as not even "not set"
  1698. m_iPrevSize = SIZE_NONE;
  1699. m_bPalette = FALSE;
  1700. m_fInUserEditMode = FALSE;
  1701. m_fProprtySheetExiting = FALSE;
  1702. m_i3DShadowAdj = -333;
  1703. m_i3DHilightAdj = 500;
  1704. m_iWatermarkAdj = -50;
  1705. m_fScale3DShadowAdj = TRUE;
  1706. m_fScale3DHilightAdj = TRUE;
  1707. m_fScaleWatermarkAdj = TRUE;
  1708. m_hTheme = NULL;
  1709. m_iCountCharsets = 0;
  1710. for (nIndex = 0; nIndex < ARRAYSIZE(m_uiUniqueCharsets); nIndex++)
  1711. {
  1712. m_uiUniqueCharsets[nIndex] = DEFAULT_CHARSET;
  1713. }
  1714. for (int nIndex1 = 0; nIndex1 < ARRAYSIZE(g_nSizeInitArray); nIndex1++)
  1715. {
  1716. m_sizes[nIndex1].CurSize = g_nSizeInitArray[nIndex1][0];
  1717. m_sizes[nIndex1].MinSize = g_nSizeInitArray[nIndex1][1];
  1718. m_sizes[nIndex1].MaxSize = g_nSizeInitArray[nIndex1][2];
  1719. }
  1720. CreateGlobals();
  1721. _LoadState(pState);
  1722. }
  1723. CAdvAppearancePage::~CAdvAppearancePage()
  1724. {
  1725. if (m_hpal3D)
  1726. {
  1727. DeleteObject(m_hpal3D);
  1728. m_hpal3D = NULL;
  1729. }
  1730. if (m_hpalVGA)
  1731. {
  1732. DeleteObject(m_hpalVGA);
  1733. m_hpalVGA = NULL;
  1734. }
  1735. if (g_hdcMem)
  1736. {
  1737. DeleteDC(g_hdcMem);
  1738. g_hdcMem = NULL;
  1739. }
  1740. DllRelease();
  1741. }
  1742. HRESULT CAdvAppearancePage_CreateInstance(OUT IAdvancedDialog ** ppAdvDialog, IN const SYSTEMMETRICSALL * pState)
  1743. {
  1744. HRESULT hr = E_INVALIDARG;
  1745. if (ppAdvDialog)
  1746. {
  1747. CAdvAppearancePage * ptsp = new CAdvAppearancePage(pState);
  1748. if (ptsp)
  1749. {
  1750. hr = ptsp->QueryInterface(IID_PPV_ARG(IAdvancedDialog, ppAdvDialog));
  1751. ptsp->Release();
  1752. }
  1753. else
  1754. {
  1755. *ppAdvDialog = NULL;
  1756. hr = E_OUTOFMEMORY;
  1757. }
  1758. }
  1759. return hr;
  1760. }