Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1226 lines
42 KiB

  1. /* FAKEWIN.C
  2. Resident Code Segment // Tweak: make non-resident?
  3. Most of this code is taken from the display CPLs adjusted to
  4. work with the Theme Switcher and cleaned up a little.
  5. Routines for painting the preview box in the main window
  6. Window samples
  7. Icons
  8. (Desktop background is in BKGD.C)
  9. Frosting: Master Theme Selector for Windows '95
  10. Copyright (c) 1994-1999 Microsoft Corporation. All rights reserved.
  11. */
  12. // ---------------------------------------------
  13. // Brief file history:
  14. // Alpha:
  15. // Beta:
  16. // Bug fixes
  17. // ---------
  18. #include "windows.h"
  19. #include "frost.h"
  20. #include "global.h"
  21. #include "bkgd.h"
  22. #include "fakewin.h"
  23. #include "nc.h"
  24. //
  25. // local routines
  26. void NEAR FakewinRecalc(void);
  27. void NEAR PASCAL Set3DPaletteColor(COLORREF rgb, int iColor);
  28. COLORREF NearestColor(int iColor, COLORREF rgb);
  29. void GetThemeColors(LPTSTR);
  30. void GetThemeFonts(LPTSTR);
  31. BOOL IsPaletteColor(HPALETTE, COLORREF);
  32. COLORREF GetNearestPaletteColor(HPALETTE, COLORREF);
  33. // as per DavidBa 3/95 and MartinHa 4/95
  34. WINUSERAPI HANDLE WINAPI SetSysColorsTemp(COLORREF FAR *, HBRUSH FAR *, UINT_PTR); // internal
  35. WINUSERAPI int WINAPI DrawMenuBarTemp(HWND, HDC, LPRECT, HMENU, HFONT);
  36. #ifdef UNICODE
  37. #define DrawCaptionTemp DrawCaptionTempW
  38. #else
  39. #define DrawCaptionTemp DrawCaptionTempA
  40. #endif // !UNICODE
  41. WINUSERAPI BOOL WINAPI DrawCaptionTemp(HWND, HDC, LPRECT, HFONT, HICON, LPTSTR, UINT);
  42. // globals
  43. ICONMETRICS imTheme;
  44. NONCLIENTMETRICS ncmTheme;
  45. // string size metrics
  46. int cxNormalStr;
  47. int yButtonStr;
  48. int cxDisabledStr, cxSelectedStr; // includes extra 2 chars width cxAvgCharx2
  49. int cyDisabledStr, cxAvgCharx2;
  50. #define RGB_PALETTE 0x02000000
  51. //
  52. // FakewinInit/Destroy
  53. //
  54. // These are the the constant objects and one-time inits for
  55. // things we need to paint the fake window sample.
  56. //
  57. // Taken from the display CPL code, rearranged, commented and cleaned up.
  58. //
  59. BOOL FAR PASCAL FakewinInit(void)
  60. {
  61. HDC hdc;
  62. int iter;
  63. //
  64. // Load our display strings.
  65. LoadString(hInstApp, IDS_ACTIVE, szFakeActive, ARRAYSIZE(szFakeActive));
  66. LoadString(hInstApp, IDS_INACTIVE, szFakeInactive, ARRAYSIZE(szFakeInactive));
  67. LoadString(hInstApp, IDS_MINIMIZED, szFakeMinimized, ARRAYSIZE(szFakeMinimized));
  68. LoadString(hInstApp, IDS_ICONTITLE, szFakeIconTitle, ARRAYSIZE(szFakeIconTitle));
  69. LoadString(hInstApp, IDS_NORMAL, szFakeNormal, ARRAYSIZE(szFakeNormal));
  70. LoadString(hInstApp, IDS_DISABLED, szFakeDisabled, ARRAYSIZE(szFakeDisabled));
  71. LoadString(hInstApp, IDS_SELECTED, szFakeSelected, ARRAYSIZE(szFakeSelected));
  72. LoadString(hInstApp, IDS_MSGBOX, szFakeMsgBox, ARRAYSIZE(szFakeMsgBox));
  73. LoadString(hInstApp, IDS_BUTTONTEXT, szFakeButton, ARRAYSIZE(szFakeButton));
  74. // LoadString(hInstApp, IDS_SMCAPTION, szFakeSmallCaption, ARRAYSIZE(szFakeSmallCaption));
  75. LoadString(hInstApp, IDS_WINDOWTEXT, szFakeWindowText, ARRAYSIZE(szFakeWindowText));
  76. LoadString(hInstApp, IDS_MSGBOXTEXT, szFakeMsgBoxText, ARRAYSIZE(szFakeMsgBoxText));
  77. //
  78. // store interesting gdi info
  79. hdc = GetDC(NULL);
  80. bPalette = GetDeviceCaps(hdc, RASTERCAPS) & RC_PALETTE;
  81. ReleaseDC(NULL, hdc);
  82. //
  83. // other sys info that doesn't change with theme
  84. cyFixedBorder = GetSystemMetrics(SM_CYBORDER);
  85. cxFixedBorder = GetSystemMetrics(SM_CXBORDER);
  86. cxFixedEdge = GetSystemMetrics(SM_CXEDGE);
  87. cyFixedEdge = GetSystemMetrics(SM_CYEDGE);
  88. //
  89. // always make a palette even on non-pal device (???)
  90. if (bPalette || TRUE)
  91. {
  92. DWORD dwPal[21];
  93. HPALETTE hpal = GetStockObject(DEFAULT_PALETTE);
  94. dwPal[0] = MAKELONG(0x300, 20);
  95. dwPal[1] = RGB(255, 255, 255);
  96. dwPal[2] = RGB(0, 0, 0 );
  97. dwPal[3] = RGB(192, 192, 192);
  98. dwPal[4] = RGB(128, 128, 128);
  99. dwPal[5] = RGB(255, 0, 0 );
  100. dwPal[6] = RGB(128, 0, 0 );
  101. dwPal[7] = RGB(255, 255, 0 );
  102. dwPal[8] = RGB(128, 128, 0 );
  103. dwPal[9] = RGB(0 , 255, 0 );
  104. dwPal[10] = RGB(0 , 128, 0 );
  105. dwPal[11] = RGB(0 , 255, 255);
  106. dwPal[12] = RGB(0 , 128, 128);
  107. dwPal[13] = RGB(0 , 0, 255);
  108. dwPal[14] = RGB(0 , 0, 128);
  109. dwPal[15] = RGB(255, 0, 255);
  110. dwPal[16] = RGB(128, 0, 128);
  111. // get magic colors
  112. GetPaletteEntries(hpal, 8, 4, (LPPALETTEENTRY)&dwPal[17]);
  113. hpal3D = CreatePalette((LPLOGPALETTE)dwPal);
  114. }
  115. // init fonts/brushes arrays to null
  116. for (iter = 0; iter < NUM_FONTS; iter++) {
  117. g_fonts[iter].hfont = NULL;
  118. }
  119. for (iter = 0; iter < MAX_COLORS; iter++) {
  120. g_brushes[iter] = NULL;
  121. }
  122. // cleanup
  123. return (TRUE);
  124. }
  125. // final deletion of fonts, brushes, palette
  126. void FAR PASCAL FakewinDestroy(void)
  127. {
  128. int i;
  129. for (i = 0; i < NUM_FONTS; i++) {
  130. if (g_fonts[i].hfont)
  131. DeleteObject(g_fonts[i].hfont);
  132. }
  133. for (i = 0; i < MAX_COLORS; i++) {
  134. if (g_brushes[i])
  135. DeleteObject(g_brushes[i]);
  136. }
  137. if (hpal3D)
  138. DeleteObject(hpal3D);
  139. }
  140. //
  141. // FakewinSetTheme
  142. //
  143. // Reset all the things you're painting that change with each theme:
  144. // colors, brushes, fonts, etc.
  145. //
  146. // Then given the current fonts and win sizes, call FakewinRecalc to
  147. // recalculate all the rectangles for painting.
  148. //
  149. #define bThemed (*lpszTheme)
  150. void FAR FakewinSetTheme(LPTSTR lpszTheme)
  151. {
  152. extern TCHAR szMetrics[];
  153. extern TCHAR szNCM[];
  154. extern TCHAR szIM[];
  155. UINT uret;
  156. int iter;
  157. //
  158. // init colors: get theme's system colors and null out old brushes
  159. GetThemeColors(lpszTheme);
  160. for (iter = 0; iter < MAX_COLORS; iter++) {
  161. if (g_brushes[iter]) DeleteObject(g_brushes[iter]);
  162. g_brushes[iter] = NULL;
  163. }
  164. //
  165. // tweak system color palette for 3D face color in array
  166. if (bPalette) {
  167. PALETTEENTRY pePal[4];
  168. HPALETTE hpal = GetStockObject(DEFAULT_PALETTE);
  169. // get current magic colors
  170. GetPaletteEntries(hpal, 8, 4, pePal);
  171. SetPaletteEntries(hpal3D, 16, 4, pePal);
  172. // set up magic colors in the 3d palette
  173. if (!IsPaletteColor(hpal, g_rgb[COLOR_3DFACE])) {
  174. Set3DPaletteColor(g_rgb[COLOR_3DFACE], COLOR_3DFACE);
  175. Set3DPaletteColor(g_rgb[COLOR_3DSHADOW], COLOR_3DSHADOW);
  176. Set3DPaletteColor(g_rgb[COLOR_3DHILIGHT], COLOR_3DHILIGHT);
  177. }
  178. }
  179. //
  180. // now go get new brushes for the new and tweaked sys colors
  181. for (iter = 0; iter < MAX_COLORS; iter++) {
  182. g_rgb[iter] = NearestColor(iter, g_rgb[iter]);
  183. g_brushes[iter] = CreateSolidBrush(g_rgb[iter]);
  184. }
  185. //
  186. // get window/border/etc size info from theme
  187. if (bThemed && // theme file and active checkbox
  188. (bCBStates[FC_BORDERS] || bCBStates[FC_FONTS])) { // one or both checked
  189. uret = (UINT) GetPrivateProfileString((LPTSTR)szMetrics, (LPTSTR)szNCM,
  190. (LPTSTR)szNULL,
  191. (LPTSTR)pValue, MAX_VALUELEN,
  192. lpszTheme);
  193. Assert(uret, TEXT("problem getting stored nonclient metrics for fakewin setup\n"));
  194. // translate stored data string to NONCLIENTMETRICS bytes
  195. WriteBytesToBuffer((LPTSTR)pValue); // char str read from and binary bytes
  196. // written to pValue. It's OK.
  197. // get it into global NONCLIENTMETRICS struct
  198. #ifdef UNICODE
  199. // NONCLIENTMETRICS are stored in ANSI format in the Theme file
  200. // so we need to convert them to UNICODE.
  201. ConvertNCMetricsToWIDE((LPNONCLIENTMETRICSA)pValue, (LPNONCLIENTMETRICSW)&ncmTheme);
  202. #else
  203. // Not UNICODE so no need to convert from ANSI...
  204. ncmTheme = *((LPNONCLIENTMETRICS)pValue);
  205. #endif
  206. // if _both_ checkboxes are checked, stay with theme file settings for all;
  207. // if neither were checked, you're not in this code branch (see above);
  208. // but if one or the other is unchecked, need to mix and match
  209. if (!bCBStates[FC_BORDERS] || !bCBStates[FC_FONTS]) {
  210. NONCLIENTMETRICS ncmTemp;
  211. // get cur system settings
  212. ncmTemp.cbSize = sizeof(ncmTemp);
  213. SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(ncmTemp),
  214. (void far *)(LPNONCLIENTMETRICS)&ncmTemp, FALSE);
  215. //
  216. // mix them in with theme file settings according to checkbox
  217. // don't use theme's win borders/sizes and font sizes
  218. if (!bCBStates[FC_BORDERS]) {
  219. ncmTheme.iBorderWidth = ncmTemp.iBorderWidth;
  220. ncmTheme.iScrollWidth = ncmTemp.iScrollWidth;
  221. ncmTheme.iScrollHeight = ncmTemp.iScrollHeight;
  222. ncmTheme.iCaptionWidth = ncmTemp.iCaptionWidth;
  223. ncmTheme.iCaptionHeight = ncmTemp.iCaptionHeight;
  224. ncmTheme.iSmCaptionWidth = ncmTemp.iSmCaptionWidth;
  225. ncmTheme.iSmCaptionHeight = ncmTemp.iSmCaptionHeight;
  226. ncmTheme.iMenuWidth = ncmTemp.iMenuWidth;
  227. ncmTheme.iMenuHeight = ncmTemp.iMenuHeight;
  228. TransmitFontCharacteristics(&(ncmTheme.lfCaptionFont),
  229. &(ncmTemp.lfCaptionFont),
  230. TFC_SIZE);
  231. TransmitFontCharacteristics(&(ncmTheme.lfSmCaptionFont),
  232. &(ncmTemp.lfSmCaptionFont),
  233. TFC_SIZE);
  234. TransmitFontCharacteristics(&(ncmTheme.lfMenuFont),
  235. &(ncmTemp.lfMenuFont),
  236. TFC_SIZE);
  237. TransmitFontCharacteristics(&(ncmTheme.lfStatusFont),
  238. &(ncmTemp.lfStatusFont),
  239. TFC_SIZE);
  240. TransmitFontCharacteristics(&(ncmTheme.lfMessageFont),
  241. &(ncmTemp.lfMessageFont),
  242. TFC_SIZE);
  243. }
  244. // don't use theme's font styles
  245. if (!bCBStates[FC_FONTS]) { // coulda been an else clause logically
  246. TransmitFontCharacteristics(&(ncmTheme.lfCaptionFont),
  247. &(ncmTemp.lfCaptionFont),
  248. TFC_STYLE);
  249. TransmitFontCharacteristics(&(ncmTheme.lfSmCaptionFont),
  250. &(ncmTemp.lfSmCaptionFont),
  251. TFC_STYLE);
  252. TransmitFontCharacteristics(&(ncmTheme.lfMenuFont),
  253. &(ncmTemp.lfMenuFont),
  254. TFC_STYLE);
  255. TransmitFontCharacteristics(&(ncmTheme.lfStatusFont),
  256. &(ncmTemp.lfStatusFont),
  257. TFC_STYLE);
  258. TransmitFontCharacteristics(&(ncmTheme.lfMessageFont),
  259. &(ncmTemp.lfMessageFont),
  260. TFC_STYLE);
  261. }
  262. }
  263. }
  264. else { // no theme: cur windows settings
  265. ncmTheme.cbSize = sizeof(ncmTheme);
  266. SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(ncmTheme),
  267. (void far *)(LPNONCLIENTMETRICS)&ncmTheme, FALSE);
  268. }
  269. //
  270. // get icon info from theme
  271. if (bThemed && bCBStates[FC_ICONS]) { // theme file and active checkbox
  272. uret = (UINT) GetPrivateProfileString((LPTSTR)szMetrics, (LPTSTR)szIM,
  273. (LPTSTR)szNULL,
  274. (LPTSTR)pValue, MAX_VALUELEN,
  275. lpszTheme);
  276. Assert(uret, TEXT("problem getting stored icon metrics for fakewin setup\n"));
  277. // translate stored data string to ICONMETRICS bytes
  278. WriteBytesToBuffer((LPTSTR)pValue); // char str read from and binary bytes
  279. // written to pValue. It's OK.
  280. // get it into global ICONMETRICS struct
  281. #ifdef UNICODE
  282. // ICONMETRICS are stored in ANSI format in the Theme file so
  283. // we need to convert to UNICODE.
  284. ConvertIconMetricsToWIDE((LPICONMETRICSA)pValue, (LPICONMETRICSW)&imTheme);
  285. #else
  286. // Not UNICODE so no need to convert ICONMETRICS...
  287. imTheme = *((LPICONMETRICS)pValue);
  288. #endif
  289. }
  290. else {
  291. imTheme.cbSize = sizeof(imTheme);
  292. SystemParametersInfo(SPI_GETICONMETRICS, sizeof(imTheme),
  293. (void far *)(LPICONMETRICS)&imTheme, FALSE);
  294. }
  295. //
  296. // get fonts from theme and create the fonts
  297. GetThemeFonts(lpszTheme);
  298. for (iter = 0; iter < NUM_FONTS; iter++) {
  299. if (g_fonts[iter].hfont) DeleteObject(g_fonts[iter].hfont);
  300. g_fonts[iter].hfont = CreateFontIndirect(&g_fonts[iter].lf);
  301. }
  302. // lastly, call the painting rect recalc
  303. // now that you have new fonts and sizes
  304. FakewinRecalc();
  305. }
  306. //
  307. // GetThemeColors
  308. //
  309. // This routine just gets colors from the theme into the global colors
  310. // array. Luckily, we already have our own parallel arrays of color IDs
  311. // and strings.
  312. //
  313. void GetThemeColors(LPTSTR lpszTheme)
  314. {
  315. int i;
  316. BOOL bGrad = FALSE; // Are gradient captions enabled?
  317. // Init bGrad
  318. SystemParametersInfo(SPI_GETGRADIENTCAPTIONS, 0, (LPVOID)&bGrad, 0);
  319. // can't measure this with extern def'd arrays
  320. #if 0
  321. Assert ((sizeof(iSysColorIndices)/sizeof(int)) == MAX_COLORS,
  322. TEXT("wrong length color array in GetThemeColors\n"));
  323. #endif
  324. // loop through our array and store theme color in their array
  325. for (i = 0; i < MAX_COLORS; i++) {
  326. if (bThemed && bCBStates[FC_COLORS]) { // theme file and active checkbox
  327. // get string from theme
  328. GetPrivateProfileString((LPTSTR)szColorApp,
  329. (LPTSTR)pRegColors[i],
  330. (LPTSTR)szNULL,
  331. (LPTSTR)pValue, MAX_VALUELEN, lpszTheme);
  332. // Check to see if this is one of the Gradient title bar colors.
  333. // If it is and there is no setting in the Theme file use the color
  334. // for the NON-GRADIENT CAPTION instead.
  335. if ((INDEX_GRADIENTACTIVE == i) && !*pValue) {
  336. GetPrivateProfileString((LPTSTR)szColorApp,
  337. (LPTSTR)pRegColors[INDEX_ACTIVE],
  338. (LPTSTR)szNULL,
  339. (LPTSTR)pValue, MAX_VALUELEN, lpszTheme);
  340. }
  341. if ((INDEX_GRADIENTINACTIVE == i) && !*pValue) {
  342. GetPrivateProfileString((LPTSTR)szColorApp,
  343. (LPTSTR)pRegColors[INDEX_INACTIVE],
  344. (LPTSTR)szNULL,
  345. (LPTSTR)pValue, MAX_VALUELEN, lpszTheme);
  346. }
  347. // translate string and store in RGB array with corresponding index
  348. g_rgb[iSysColorIndices[i]] = RGBStringToColor((LPTSTR)pValue);
  349. }
  350. else { // cur windows settings
  351. // If this is one of the gradient colors and the system
  352. // doesn't support gradient (bpp ! > 256) or gradients are
  353. // not currently enabled then get the primary gradient color
  354. // for the gradient colors
  355. // bGrad -- are gradient captions enabled?
  356. // g_bGradient -- enough colors for gradient captions?
  357. if (((COLOR_GRADIENTACTIVECAPTION == iSysColorIndices[i]) ||
  358. (COLOR_GRADIENTINACTIVECAPTION == iSysColorIndices[i])) &&
  359. (!(bGrad && g_bGradient))) {
  360. if (INDEX_GRADIENTACTIVE == i) g_rgb[i] = GetSysColor(COLOR_ACTIVECAPTION);
  361. else if (INDEX_GRADIENTINACTIVE == i) g_rgb[i] = GetSysColor(COLOR_INACTIVECAPTION);
  362. }
  363. else g_rgb[i] = GetSysColor(i);
  364. }
  365. }
  366. }
  367. //
  368. // GetThemeFonts
  369. //
  370. // This routine just gets fonts from the theme into the global fonts
  371. // array. Need to do each font individually into the array.
  372. // Would be cleaner if we were starting this from scratch. Just trying
  373. // to munge it into the form the borrowed code uses.
  374. //
  375. // Note that for Cur Windows Settings, the ncmTheme and imTheme are already
  376. // set to cur win settings, so this just works the same.
  377. //
  378. void GetThemeFonts(LPTSTR lpszTheme)
  379. {
  380. g_fonts[FONT_CAPTION].lf = ncmTheme.lfCaptionFont;
  381. g_fonts[FONT_MENU].lf = ncmTheme.lfMenuFont;
  382. g_fonts[FONT_STATUS].lf = ncmTheme.lfStatusFont;
  383. g_fonts[FONT_MSGBOX].lf = ncmTheme.lfMessageFont;
  384. g_fonts[FONT_ICONTITLE].lf = imTheme.lfFont;
  385. }
  386. // ----------------------------------------------------------------------------
  387. // FakewinRecalc
  388. //
  389. // calculate all of the rectangles based on the given window rect
  390. // ----------------------------------------------------------------------------
  391. void FakewinRecalc(void)
  392. {
  393. // DWORD xyNormal;
  394. // DWORD xyButton;
  395. SIZE sizeExtent;
  396. RECT rc;
  397. HFONT hfontT;
  398. int cxFrame, cyFrame;
  399. int cyCaption;
  400. int i;
  401. HDC hdc;
  402. // inits
  403. hdc = GetDC(NULL);
  404. rc = rFakeWin;
  405. //
  406. // Get our drawing data
  407. //
  408. cxFrame = ((int)ncmTheme.iBorderWidth + 1) * cxFixedBorder + cxFixedEdge;
  409. cyFrame = ((int)ncmTheme.iBorderWidth + 1) * cyFixedBorder + cyFixedEdge;
  410. cyCaption = (int)ncmTheme.iCaptionHeight;
  411. // cxSize = GetSystemMetrics(SM_CXSIZE); // WHAT GIVES ***DEBUG***
  412. cxSize = cyCaption - 2*cyFixedBorder; // Wild-Assed Guess
  413. //
  414. // Get text dimensions, with proper fonts
  415. //
  416. hfontT = SelectObject(hdc, g_fonts[FONT_CAPTION].hfont);
  417. SelectObject(hdc, g_fonts[FONT_MENU].hfont);
  418. //
  419. // rewrite this to use win32 code
  420. //
  421. GetTextExtentPoint32(hdc, szFakeNormal, lstrlen(szFakeNormal), (LPSIZE)&sizeExtent);
  422. cxNormalStr = (int)(sizeExtent.cx);
  423. GetTextExtentPoint32(hdc, szFakeDisabled, lstrlen(szFakeDisabled), (LPSIZE)&sizeExtent);
  424. cxDisabledStr = (int)(sizeExtent.cx);
  425. cyDisabledStr = (int)(sizeExtent.cy);
  426. GetTextExtentPoint32(hdc, szFakeSelected, lstrlen(szFakeSelected), (LPSIZE)&sizeExtent);
  427. cxSelectedStr = (int)(sizeExtent.cx);
  428. // get the average width (USER style) of menu font
  429. GetTextExtentPoint32(hdc, szFakeABC, 52, (LPSIZE)&sizeExtent);
  430. cxAvgCharx2 = 2 * ((int)(sizeExtent.cx) / 52);
  431. // actual menu-handling widths of strings is bigger
  432. cxDisabledStr += cxAvgCharx2;
  433. cxSelectedStr += cxAvgCharx2;
  434. cxNormalStr += cxAvgCharx2;
  435. GetTextExtentPoint32(hdc, szFakeButton, lstrlen(szFakeButton), (LPSIZE)&sizeExtent);
  436. yButtonStr = (int)(sizeExtent.cy);
  437. #ifdef ORIG_OUTDATED_CPL_CODE
  438. xyNormal = GetTextExtent(hdc, szFakeNormal, lstrlen(szFakeNormal));
  439. cxDisabledStr = LOWORD(GetTextExtent(hdc, szFakeDisabled, lstrlen(szFakeDisabled)));
  440. cxSelectedStr = LOWORD(GetTextExtent(hdc, szFakeSelected, lstrlen(szFakeSelected)));
  441. // get the average width (USER style) of menu font
  442. cxAvgCharx2 = 2 * (LOWORD(GetTextExtent(hdc, szFakeABC, 52)) / 52);
  443. // actual menu-handling widths of strings is bigger
  444. cxDisabledStr += cxAvgCharx2;
  445. cxSelectedStr += cxAvgCharx2;
  446. LOWORD(xyNormal) += cxAvgCharx2;
  447. xyButton = GetTextExtent(hdc, szFakeButton, lstrlen(szFakeButton));
  448. #endif
  449. // done with dc
  450. SelectObject(hdc, hfontT);
  451. ReleaseDC(NULL, hdc);
  452. // donna paint dt! already done
  453. #if 0
  454. // Desktop
  455. RCZ(ELEMENT_DESKTOP) = rc;
  456. InflateRect(&rc, -8*cxFixedBorder, -8*cyFixedBorder);
  457. #endif
  458. //
  459. // Windows
  460. //
  461. rc.bottom -= cyFrame + cyCaption;
  462. RCZ(ELEMENT_ACTIVEBORDER) = rc;
  463. OffsetRect(&RCZ(ELEMENT_ACTIVEBORDER), cxFrame,
  464. cyFrame + cyCaption + cyFixedBorder);
  465. RCZ(ELEMENT_ACTIVEBORDER).bottom -= cyCaption;
  466. //
  467. // Inactive window
  468. //
  469. rc.right -= cyCaption;
  470. RCZ(ELEMENT_INACTIVEBORDER) = rc;
  471. // Caption
  472. InflateRect(&rc, -cxFrame, -cyFrame);
  473. rc.bottom = rc.top + cyCaption + cyFixedBorder;
  474. RCZ(ELEMENT_INACTIVECAPTION) = rc;
  475. // close button
  476. InflateRect(&rc, -cxFixedEdge, -cyFixedEdge);
  477. rc.bottom -= cyFixedBorder; // compensate for magic line under caption
  478. RCZ(ELEMENT_INACTIVESYSBUT1) = rc;
  479. RCZ(ELEMENT_INACTIVESYSBUT1).left = rc.right - (cyCaption - cxFixedEdge);
  480. // min/max buttons
  481. RCZ(ELEMENT_INACTIVESYSBUT2) = rc;
  482. RCZ(ELEMENT_INACTIVESYSBUT2).right = RCZ(ELEMENT_INACTIVESYSBUT1).left - cxFixedEdge;
  483. RCZ(ELEMENT_INACTIVESYSBUT2).left = RCZ(ELEMENT_INACTIVESYSBUT2).right -
  484. 2 * (cyCaption - cxFixedEdge);
  485. // cpl code doesn't do this either
  486. #if 0
  487. //
  488. // small caption window
  489. //
  490. RCZ(ELEMENT_SMCAPTION) = RCZ(ELEMENT_ACTIVEBORDER);
  491. RCZ(ELEMENT_SMCAPTION).bottom = RCZ(ELEMENT_SMCAPTION).top;
  492. RCZ(ELEMENT_SMCAPTION).top -= (int)ncmTheme.iSmCaptionHeight + cyFixedEdge + 2 * cyFixedBorder;
  493. RCZ(ELEMENT_SMCAPTION).right -= cxFrame;
  494. RCZ(ELEMENT_SMCAPTION).left = RCZ(ELEMENT_INACTIVECAPTION).right + 2 * cxFrame;
  495. RCZ(ELEMENT_SMCAPSYSBUT) = RCZ(ELEMENT_SMCAPTION);
  496. // deflate inside frame/border to caption and then another edge's worth
  497. RCZ(ELEMENT_SMCAPSYSBUT).right -= 2 * cxFixedEdge + cxFixedBorder;
  498. RCZ(ELEMENT_SMCAPSYSBUT).top += 2 * cxFixedEdge + cxFixedBorder;
  499. RCZ(ELEMENT_SMCAPSYSBUT).bottom -= cxFixedEdge + cxFixedBorder;
  500. RCZ(ELEMENT_SMCAPSYSBUT).left = RCZ(ELEMENT_SMCAPSYSBUT).right -
  501. ((int)ncmTheme.iSmCaptionHeight - cxFixedEdge);
  502. #endif
  503. //
  504. // Active window
  505. //
  506. // Caption
  507. rc = RCZ(ELEMENT_ACTIVEBORDER);
  508. InflateRect(&rc, -cxFrame, -cyFrame);
  509. RCZ(ELEMENT_ACTIVECAPTION) = rc;
  510. RCZ(ELEMENT_ACTIVECAPTION).bottom =
  511. RCZ(ELEMENT_ACTIVECAPTION).top + cyCaption + cyFixedBorder;
  512. // close button
  513. RCZ(ELEMENT_ACTIVESYSBUT1) = RCZ(ELEMENT_ACTIVECAPTION);
  514. InflateRect(&RCZ(ELEMENT_ACTIVESYSBUT1), -cxFixedEdge, -cyFixedEdge);
  515. RCZ(ELEMENT_ACTIVESYSBUT1).bottom -= cyFixedBorder; // compensate for magic line under caption
  516. RCZ(ELEMENT_ACTIVESYSBUT1).left = RCZ(ELEMENT_ACTIVESYSBUT1).right -
  517. (cyCaption - cxFixedEdge);
  518. // min/max buttons
  519. RCZ(ELEMENT_ACTIVESYSBUT2) = RCZ(ELEMENT_ACTIVESYSBUT1);
  520. RCZ(ELEMENT_ACTIVESYSBUT2).right = RCZ(ELEMENT_ACTIVESYSBUT1).left - cxFixedEdge;
  521. RCZ(ELEMENT_ACTIVESYSBUT2).left = RCZ(ELEMENT_ACTIVESYSBUT2).right -
  522. 2 * (cyCaption - cxFixedEdge);
  523. // Menu
  524. rc.top = RCZ(ELEMENT_ACTIVECAPTION).bottom;
  525. RCZ(ELEMENT_MENUNORMAL) = rc;
  526. rc.top = RCZ(ELEMENT_MENUNORMAL).bottom = RCZ(ELEMENT_MENUNORMAL).top + (int)ncmTheme.iMenuHeight;
  527. RCZ(ELEMENT_MENUDISABLED) = RCZ(ELEMENT_MENUSELECTED) = RCZ(ELEMENT_MENUNORMAL);
  528. RCZ(ELEMENT_MENUDISABLED).left = RCZ(ELEMENT_MENUNORMAL).left + cxNormalStr;
  529. RCZ(ELEMENT_MENUDISABLED).right = RCZ(ELEMENT_MENUSELECTED).left =
  530. RCZ(ELEMENT_MENUDISABLED).left + cxDisabledStr;
  531. RCZ(ELEMENT_MENUSELECTED).right = RCZ(ELEMENT_MENUSELECTED).left + cxSelectedStr;
  532. //
  533. // Client
  534. //
  535. RCZ(ELEMENT_WINDOW) = rc;
  536. //
  537. // Scrollbar
  538. //
  539. InflateRect(&rc, -cxFixedEdge, -cyFixedEdge); // take off client edge
  540. RCZ(ELEMENT_SCROLLBAR) = rc;
  541. rc.right = RCZ(ELEMENT_SCROLLBAR).left = rc.right - (int)ncmTheme.iScrollWidth;
  542. RCZ(ELEMENT_SCROLLUP) = RCZ(ELEMENT_SCROLLBAR);
  543. RCZ(ELEMENT_SCROLLUP).bottom = RCZ(ELEMENT_SCROLLBAR).top + (int)ncmTheme.iScrollWidth;
  544. RCZ(ELEMENT_SCROLLDOWN) = RCZ(ELEMENT_SCROLLBAR);
  545. RCZ(ELEMENT_SCROLLDOWN).top = RCZ(ELEMENT_SCROLLBAR).bottom - (int)ncmTheme.iScrollWidth;
  546. //
  547. // Message Box
  548. //
  549. // rc.top = RCZ(ELEMENT_WINDOW).top + (RCZ(ELEMENT_WINDOW).bottom - RCZ(ELEMENT_WINDOW).top) / 2;
  550. rc.top = RCZ(ELEMENT_WINDOW).top + (RCZ(ELEMENT_WINDOW).bottom - RCZ(ELEMENT_WINDOW).top) / 3;
  551. // rc.bottom = RCZ(ELEMENT_DESKTOP).bottom - 2*cyFixedEdge;
  552. rc.bottom = rFakeWin.bottom - 2*cyFixedEdge;
  553. rc.left = RCZ(ELEMENT_WINDOW).left + 2*cyFixedEdge;
  554. rc.right = RCZ(ELEMENT_WINDOW).left + (RCZ(ELEMENT_WINDOW).right - RCZ(ELEMENT_WINDOW).left) / 2 + 3*cyCaption;
  555. RCZ(ELEMENT_MSGBOX) = rc;
  556. // Caption
  557. RCZ(ELEMENT_MSGBOXCAPTION) = rc;
  558. RCZ(ELEMENT_MSGBOXCAPTION).top += cyFixedEdge + cyFixedBorder;
  559. RCZ(ELEMENT_MSGBOXCAPTION).bottom = RCZ(ELEMENT_MSGBOXCAPTION).top + cyCaption + cyFixedBorder;
  560. RCZ(ELEMENT_MSGBOXCAPTION).left += cxFixedEdge + cxFixedBorder;
  561. RCZ(ELEMENT_MSGBOXCAPTION).right -= cxFixedEdge + cxFixedBorder;
  562. RCZ(ELEMENT_MSGBOXSYSBUT) = RCZ(ELEMENT_MSGBOXCAPTION);
  563. InflateRect(&RCZ(ELEMENT_MSGBOXSYSBUT), -cxFixedEdge, -cyFixedEdge);
  564. RCZ(ELEMENT_MSGBOXSYSBUT).left = RCZ(ELEMENT_MSGBOXSYSBUT).right -
  565. (cyCaption - cxFixedEdge);
  566. RCZ(ELEMENT_MSGBOXSYSBUT).bottom -= cyFixedBorder; // line under caption
  567. // Button
  568. RCZ(ELEMENT_BUTTON).bottom = RCZ(ELEMENT_MSGBOX).bottom - (4*cyFixedBorder + cyFixedEdge);
  569. RCZ(ELEMENT_BUTTON).top = RCZ(ELEMENT_BUTTON).bottom - (yButtonStr + 8*cyFixedBorder);
  570. i = (RCZ(ELEMENT_BUTTON).bottom - RCZ(ELEMENT_BUTTON).top) * 3;
  571. RCZ(ELEMENT_BUTTON).left = (rc.left + (rc.right - rc.left)/2) - i/2;
  572. RCZ(ELEMENT_BUTTON).right = RCZ(ELEMENT_BUTTON).left + i;
  573. }
  574. // ----------------------------------------------------------------------------
  575. //
  576. // MyDrawFrame() -
  577. //
  578. // Draws bordered frame, border size cl, and adjusts passed in rect.
  579. //
  580. // ----------------------------------------------------------------------------
  581. void NEAR PASCAL MyDrawFrame(HDC hdc, LPRECT prc, HBRUSH hbrColor, int cl)
  582. {
  583. HBRUSH hbr;
  584. int cx, cy;
  585. RECT rcT;
  586. rcT = *prc;
  587. cx = cl * cxFixedBorder;
  588. cy = cl * cyFixedBorder;
  589. hbr = SelectObject(hdc, hbrColor);
  590. PatBlt(hdc, rcT.left, rcT.top, cx, rcT.bottom - rcT.top, PATCOPY);
  591. rcT.left += cx;
  592. PatBlt(hdc, rcT.left, rcT.top, rcT.right - rcT.left, cy, PATCOPY);
  593. rcT.top += cy;
  594. rcT.right -= cx;
  595. PatBlt(hdc, rcT.right, rcT.top, cx, rcT.bottom - rcT.top, PATCOPY);
  596. rcT.bottom -= cy;
  597. PatBlt(hdc, rcT.left, rcT.bottom, rcT.right - rcT.left, cy, PATCOPY);
  598. hbr = SelectObject(hdc, hbr);
  599. *prc = rcT;
  600. }
  601. /*
  602. ** draw a cyFixedBorder band of 3DFACE at the bottom of the given rectangle.
  603. ** also, adjust the rectangle accordingly.
  604. */
  605. void NEAR PASCAL MyDrawBorderBelow(HDC hdc, LPRECT prc)
  606. {
  607. int i;
  608. i = prc->top;
  609. prc->top = prc->bottom - cyFixedBorder;
  610. FillRect(hdc, prc, g_brushes[COLOR_3DFACE]);
  611. prc->top = i;
  612. prc->bottom -= cyFixedBorder;
  613. }
  614. /*-------------------------------------------------------------------
  615. ** draw a full window caption with system menu, minimize button,
  616. ** maximize button, and text.
  617. **-------------------------------------------------------------------*/
  618. void NEAR PASCAL DrawFullCaption(HDC hdc, LPRECT prc, LPTSTR lpszTitle, UINT flags)
  619. {
  620. int iRight;
  621. int iFont;
  622. SaveDC(hdc);
  623. // special case gross for small caption that already drew on bottom
  624. if (!(flags & DC_SMALLCAP))
  625. MyDrawBorderBelow(hdc, prc);
  626. iRight = prc->right;
  627. prc->right = prc->left + cxSize;
  628. DrawFrameControl(hdc, prc, DFC_CAPTION, DFCS_CAPTIONCLOSE);
  629. prc->left = prc->right;
  630. prc->right = iRight - 2*cxSize;
  631. // iFont = flags & DC_SMALLCAP ? FONT_SMCAPTION : FONT_CAPTION;
  632. iFont = FONT_CAPTION;
  633. DrawCaptionTemp(NULL, hdc, prc, g_fonts[iFont].hfont, NULL, lpszTitle, flags | DC_ICON | DC_TEXT);
  634. prc->left = prc->right;
  635. prc->right = prc->left + cxSize;
  636. DrawFrameControl(hdc, prc, DFC_CAPTION, DFCS_CAPTIONMIN);
  637. prc->left = prc->right;
  638. prc->right = prc->left + cxSize;
  639. DrawFrameControl(hdc, prc, DFC_CAPTION, DFCS_CAPTIONMAX);
  640. RestoreDC(hdc, -1);
  641. }
  642. void FAR PASCAL FakewinDraw(HDC hdc)
  643. {
  644. RECT rcT;
  645. int nMode;
  646. DWORD rgbBk;
  647. HANDLE hOldColors = NULL; // paranoid
  648. HPALETTE hpalOld = NULL;
  649. HICON hiconLogo;
  650. HFONT hfontOld;
  651. //
  652. // inits
  653. //
  654. SaveDC(hdc); // sneaky!
  655. if (hpal3D) {
  656. hpalOld = SelectPalette(hdc, hpal3D, TRUE);
  657. RealizePalette(hdc);
  658. }
  659. hOldColors = SetSysColorsTemp(g_rgb, g_brushes, MAX_COLORS);
  660. // Setup drawing stuff
  661. nMode = SetBkMode(hdc, TRANSPARENT);
  662. rgbBk = GetTextColor(hdc);
  663. hiconLogo = LoadImage(NULL, IDI_APPLICATION, IMAGE_ICON,
  664. // hiconLogo = LoadImage(NULL, IDI_WINLOGO, IMAGE_ICON,
  665. (int)ncmTheme.iCaptionHeight - 2*cxFixedBorder,
  666. (int)ncmTheme.iCaptionHeight - 2*cyFixedBorder, 0);
  667. // we leave the lovely desktop we've already painted there
  668. #if 0
  669. //
  670. // Desktop
  671. //
  672. FillRect(hdc, &RCZ(ELEMENT_DESKTOP), g_brushes[COLOR_BACKGROUND]);
  673. #endif
  674. //
  675. // Inactive window
  676. //
  677. // Border
  678. rcT = RCZ(ELEMENT_INACTIVEBORDER);
  679. DrawEdge(hdc, &rcT, EDGE_RAISED, BF_RECT | BF_ADJUST);
  680. MyDrawFrame(hdc, &rcT, g_brushes[COLOR_INACTIVEBORDER], (int)ncmTheme.iBorderWidth);
  681. MyDrawFrame(hdc, &rcT, g_brushes[COLOR_3DFACE], 1);
  682. // Caption
  683. rcT = RCZ(ELEMENT_INACTIVECAPTION);
  684. MyDrawBorderBelow(hdc, &rcT);
  685. // NOTE: because USER draws icon stuff using its own DC and subsequently
  686. // its own palette, we need to make sure to use the inactivecaption
  687. // brush before USER does so that it will be realized against our palette.
  688. // this might get fixed in USER by better be safe.
  689. // "clip" the caption title under the buttons
  690. rcT.left = RCZ(ELEMENT_INACTIVESYSBUT2).left - cyFixedEdge;
  691. FillRect(hdc, &rcT, g_brushes[g_bGradient ? COLOR_GRADIENTINACTIVECAPTION : COLOR_INACTIVECAPTION]);
  692. rcT.right = rcT.left;
  693. rcT.left = RCZ(ELEMENT_INACTIVECAPTION).left;
  694. DrawCaptionTemp(NULL, hdc, &rcT, g_fonts[FONT_CAPTION].hfont, hiconLogo, szFakeInactive,
  695. DC_ICON | DC_TEXT | (g_bGradient ? DC_GRADIENT : 0));
  696. DrawFrameControl(hdc, &RCZ(ELEMENT_INACTIVESYSBUT1), DFC_CAPTION, DFCS_CAPTIONCLOSE);
  697. rcT = RCZ(ELEMENT_INACTIVESYSBUT2);
  698. rcT.right -= (rcT.right - rcT.left)/2;
  699. DrawFrameControl(hdc, &rcT, DFC_CAPTION, DFCS_CAPTIONMIN);
  700. rcT.left = rcT.right;
  701. rcT.right = RCZ(ELEMENT_INACTIVESYSBUT2).right;
  702. DrawFrameControl(hdc, &rcT, DFC_CAPTION, DFCS_CAPTIONMAX);
  703. // cpl code doesn't do small caption sample
  704. #if 0
  705. //
  706. // small caption window
  707. //
  708. {
  709. HICON hicon;
  710. int temp;
  711. rcT = RCZ(ELEMENT_SMCAPTION);
  712. hicon = LoadImage(NULL, IDI_APPLICATION,
  713. IMAGE_ICON,
  714. (int)ncmTheme.iSmCaptionHeight - 2*cxFixedBorder,
  715. (int)ncmTheme.iSmCaptionHeight - 2*cyFixedBorder,
  716. 0);
  717. DrawEdge(hdc, &rcT, EDGE_RAISED, BF_TOP | BF_LEFT | BF_RIGHT | BF_ADJUST);
  718. MyDrawFrame(hdc, &rcT, g_brushes[COLOR_3DFACE], 1);
  719. // "clip" the caption title under the buttons
  720. temp = rcT.left; // remember start of actual caption
  721. rcT.left = RCZ(ELEMENT_SMCAPSYSBUT).left - cxFixedEdge;
  722. FillRect(hdc, &rcT, g_brushes[COLOR_INACTIVECAPTION]);
  723. rcT.right = rcT.left;
  724. rcT.left = temp; // start of actual caption
  725. DrawCaptionTemp(NULL, hdc, &rcT, g_fonts[FONT_SMCAPTION].hfont, hicon, szFakeSmallCaption, DC_SMALLCAP | DC_ICON | DC_TEXT);
  726. DestroyIcon(hicon);
  727. DrawFrameControl(hdc, &RCZ(ELEMENT_SMCAPSYSBUT), DFC_CAPTION, DFCS_CAPTIONCLOSE);
  728. }
  729. #endif
  730. //
  731. // Active window
  732. //
  733. // Border
  734. rcT = RCZ(ELEMENT_ACTIVEBORDER);
  735. DrawEdge(hdc, &rcT, EDGE_RAISED, BF_RECT | BF_ADJUST);
  736. MyDrawFrame(hdc, &rcT, g_brushes[COLOR_ACTIVEBORDER], (int)ncmTheme.iBorderWidth);
  737. MyDrawFrame(hdc, &rcT, g_brushes[COLOR_3DFACE], 1);
  738. // Caption
  739. rcT = RCZ(ELEMENT_ACTIVECAPTION);
  740. MyDrawBorderBelow(hdc, &rcT);
  741. // "clip" the caption title under the buttons
  742. rcT.left = RCZ(ELEMENT_ACTIVESYSBUT2).left - cxFixedEdge;
  743. FillRect(hdc, &rcT, g_brushes[g_bGradient ? COLOR_GRADIENTACTIVECAPTION : COLOR_ACTIVECAPTION]);
  744. rcT.right = rcT.left;
  745. rcT.left = RCZ(ELEMENT_ACTIVECAPTION).left;
  746. DrawCaptionTemp(NULL, hdc, &rcT, g_fonts[FONT_CAPTION].hfont, hiconLogo, szFakeActive,
  747. DC_ACTIVE | DC_ICON | DC_TEXT | (g_bGradient ? DC_GRADIENT : 0));
  748. DrawFrameControl(hdc, &RCZ(ELEMENT_ACTIVESYSBUT1), DFC_CAPTION, DFCS_CAPTIONCLOSE);
  749. rcT = RCZ(ELEMENT_ACTIVESYSBUT2);
  750. rcT.right -= (rcT.right - rcT.left)/2;
  751. DrawFrameControl(hdc, &rcT, DFC_CAPTION, DFCS_CAPTIONMIN);
  752. rcT.left = rcT.right;
  753. rcT.right = RCZ(ELEMENT_ACTIVESYSBUT2).right;
  754. DrawFrameControl(hdc, &rcT, DFC_CAPTION, DFCS_CAPTIONMAX);
  755. //
  756. // Menu
  757. //
  758. // DrawMenuBarTemp(NULL, hdc, &rcT, hmenuFake, g_fonts[FONT_MENU].hfont);
  759. // inits
  760. SaveDC(hdc); // extra paranoid for changes here
  761. rcT = RCZ(ELEMENT_MENUNORMAL);
  762. hfontOld = SelectObject(hdc, g_fonts[FONT_MENU].hfont);
  763. SetBkMode(hdc, TRANSPARENT);
  764. // menu back color
  765. FillRect(hdc, &rcT, g_brushes[COLOR_MENU]);
  766. // ***DEBUG***
  767. // normal text
  768. rcT.right = RCZ(ELEMENT_MENUDISABLED).left;
  769. if (rcT.right > RCZ(ELEMENT_MENUNORMAL).right)
  770. rcT.right = RCZ(ELEMENT_MENUNORMAL).right; // det by caption width
  771. SetTextColor(hdc, GetSysColor(COLOR_MENUTEXT));
  772. rcT.right--; rcT.bottom--; // adjustment for DT positioning
  773. DrawText(hdc, szFakeNormal, -1, (LPRECT)&rcT,
  774. DT_CENTER | DT_SINGLELINE | DT_VCENTER);
  775. // disabled text
  776. rcT = RCZ(ELEMENT_MENUDISABLED);
  777. if (rcT.right > RCZ(ELEMENT_MENUNORMAL).right) // two checks for really,
  778. rcT.right = RCZ(ELEMENT_MENUNORMAL).right;
  779. if (rcT.left < RCZ(ELEMENT_MENUNORMAL).right) { // really big fonts
  780. int iwidth, iheight;
  781. rcT.right--; rcT.bottom--; // adjustment for DT positioning
  782. iwidth = rcT.right-rcT.left;
  783. iheight = rcT.bottom-rcT.top;
  784. DrawState(hdc, NULL, NULL, (LPARAM)(LPTSTR)szFakeDisabled, 0,
  785. rcT.left + (iwidth-(cxDisabledStr-cxAvgCharx2))/2,
  786. rcT.top + (iheight-cyDisabledStr)/2,
  787. iwidth, iheight, DST_TEXT | DSS_DISABLED);
  788. }
  789. // selected rect back color
  790. rcT = RCZ(ELEMENT_MENUSELECTED);
  791. if (rcT.right > RCZ(ELEMENT_MENUNORMAL).right) // two checks for really,
  792. rcT.right = RCZ(ELEMENT_MENUNORMAL).right;
  793. if (rcT.left < RCZ(ELEMENT_MENUNORMAL).right) { // really big fonts
  794. FillRect(hdc, &rcT, g_brushes[COLOR_HIGHLIGHT]);
  795. // selected text
  796. rcT.right--; rcT.bottom--; // adjustment for DT positioning
  797. SetTextColor(hdc, GetSysColor(COLOR_HIGHLIGHTTEXT));
  798. DrawText(hdc, szFakeSelected, -1, (LPRECT)&rcT,
  799. DT_CENTER | DT_SINGLELINE | DT_VCENTER);
  800. // refinish bottom of selection box
  801. rcT.right++; rcT.bottom++; // readjustment back to FillRect()
  802. MyDrawBorderBelow(hdc, &rcT);
  803. }
  804. // clean up
  805. if (hfontOld)
  806. SelectObject(hdc, hfontOld);
  807. RestoreDC(hdc, -1); // paranoid so restore
  808. //
  809. // Client area
  810. //
  811. rcT = RCZ(ELEMENT_WINDOW);
  812. DrawEdge(hdc, &rcT, EDGE_SUNKEN, BF_RECT | BF_ADJUST);
  813. FillRect(hdc, &rcT, g_brushes[COLOR_WINDOW]);
  814. // window text
  815. SetBkMode(hdc, TRANSPARENT);
  816. SetTextColor(hdc, g_rgb[COLOR_WINDOWTEXT]);
  817. TextOut(hdc, RCZ(ELEMENT_WINDOW).left + 2*cxFixedEdge, RCZ(ELEMENT_WINDOW).top + 2*cyFixedEdge, szFakeWindowText, lstrlen(szFakeWindowText));
  818. //
  819. // scroll bar
  820. //
  821. rcT = RCZ(ELEMENT_SCROLLBAR);
  822. //MyDrawFrame(hdc, &rcT, g_brushes[COLOR_3DSHADOW], 1);
  823. //g_brushes[COLOR_SCROLLBAR]);
  824. // jdk: they did this to get the brush used to paint the ctl background
  825. // FillRect(hdc, &rcT, (HBRUSH)DefWindowProc(hWnd, WM_CTLCOLOR, (WPARAM)hdc, MAKELONG(hWnd, CTLCOLOR_SCROLLBAR)));
  826. // ***DEBUG***
  827. // will this work? or is this the thumb color? and why not MyDrawFrame()?
  828. // seems to be a good approximation
  829. FillRect(hdc, &rcT, g_brushes[COLOR_SCROLLBAR]);
  830. DrawFrameControl(hdc, &RCZ(ELEMENT_SCROLLUP), DFC_SCROLL, DFCS_SCROLLUP);
  831. DrawFrameControl(hdc, &RCZ(ELEMENT_SCROLLDOWN), DFC_SCROLL, DFCS_SCROLLDOWN);
  832. //
  833. // MessageBox
  834. //
  835. rcT = RCZ(ELEMENT_MSGBOX);
  836. DrawEdge(hdc, &rcT, EDGE_RAISED, BF_RECT | BF_ADJUST);
  837. FillRect(hdc, &rcT, g_brushes[COLOR_3DFACE]);
  838. rcT = RCZ(ELEMENT_MSGBOXCAPTION);
  839. MyDrawBorderBelow(hdc, &rcT);
  840. // "clip" the caption title under the buttons
  841. rcT.left = RCZ(ELEMENT_MSGBOXSYSBUT).left - cxFixedEdge;
  842. FillRect(hdc, &rcT, g_brushes[g_bGradient ? COLOR_GRADIENTACTIVECAPTION : COLOR_ACTIVECAPTION]);
  843. rcT.right = rcT.left;
  844. rcT.left = RCZ(ELEMENT_MSGBOXCAPTION).left;
  845. DrawCaptionTemp(NULL, hdc, &rcT, g_fonts[FONT_CAPTION].hfont, hiconLogo, szFakeMsgBox,
  846. DC_ACTIVE | DC_ICON | DC_TEXT | (g_bGradient ? DC_GRADIENT : 0));
  847. DrawFrameControl(hdc, &RCZ(ELEMENT_MSGBOXSYSBUT), DFC_CAPTION, DFCS_CAPTIONCLOSE);
  848. // message box text
  849. SetBkMode(hdc, TRANSPARENT);
  850. SetTextColor(hdc, g_rgb[COLOR_WINDOWTEXT]);
  851. hfontOld = SelectObject(hdc, g_fonts[FONT_MSGBOX].hfont);
  852. TextOut(hdc, RCZ(ELEMENT_MSGBOX).left + 3*cxFixedEdge, RCZ(ELEMENT_MSGBOXCAPTION).bottom + cyFixedEdge,
  853. szFakeMsgBoxText, lstrlen(szFakeMsgBoxText));
  854. if (hfontOld)
  855. SelectObject(hdc, hfontOld);
  856. //
  857. // Button
  858. //
  859. rcT = RCZ(ELEMENT_BUTTON);
  860. DrawFrameControl(hdc, &rcT, DFC_BUTTON, DFCS_BUTTONPUSH);
  861. // cpl code asks: ?????? what font should this use ??????
  862. SetBkMode(hdc, TRANSPARENT);
  863. SetTextColor(hdc, g_rgb[COLOR_BTNTEXT]);
  864. DrawText(hdc, szFakeButton, -1, &rcT, DT_CENTER | DT_NOPREFIX |
  865. DT_SINGLELINE | DT_VCENTER);
  866. //
  867. // Cleanup
  868. //
  869. SetBkColor(hdc, rgbBk);
  870. SetBkMode(hdc, nMode);
  871. if (hiconLogo)
  872. DestroyIcon(hiconLogo);
  873. SetSysColorsTemp((COLORREF FAR *)NULL, (HBRUSH FAR *)NULL, (UINT_PTR)hOldColors);
  874. if (hpalOld) {
  875. SelectPalette(hdc, hpalOld, FALSE);
  876. RealizePalette(hdc);
  877. }
  878. RestoreDC(hdc, -1); // jdk: is this redundant to above cleanup?
  879. }
  880. //
  881. // make the color a solid color if it needs to be.
  882. // on a palette device make is a palette relative color, if we need to.
  883. //
  884. #define COLORFLAG_SOLID 0x0001
  885. UINT g_colorFlags[MAX_COLORS] = {
  886. /* COLOR_SCROLLBAR */ 0,
  887. /* COLOR_DESKTOP */ 0,
  888. /* COLOR_ACTIVECAPTION */ COLORFLAG_SOLID,
  889. /* COLOR_INACTIVECAPTION */ COLORFLAG_SOLID,
  890. /* COLOR_MENU */ COLORFLAG_SOLID,
  891. /* COLOR_WINDOW */ COLORFLAG_SOLID,
  892. /* COLOR_WINDOWFRAME */ COLORFLAG_SOLID,
  893. /* COLOR_MENUTEXT */ COLORFLAG_SOLID,
  894. /* COLOR_WINDOWTEXT */ COLORFLAG_SOLID,
  895. /* COLOR_CAPTIONTEXT */ COLORFLAG_SOLID,
  896. /* COLOR_ACTIVEBORDER */ 0,
  897. /* COLOR_INACTIVEBORDER */ 0,
  898. /* COLOR_APPWORKSPACE */ 0,
  899. /* COLOR_HIGHLIGHT */ COLORFLAG_SOLID,
  900. /* COLOR_HIGHLIGHTTEXT */ COLORFLAG_SOLID,
  901. /* COLOR_3DFACE */ COLORFLAG_SOLID,
  902. /* COLOR_3DSHADOW */ COLORFLAG_SOLID,
  903. /* COLOR_GRAYTEXT */ COLORFLAG_SOLID,
  904. /* COLOR_BTNTEXT */ COLORFLAG_SOLID,
  905. /* COLOR_INACTIVECAPTIONTEXT */ COLORFLAG_SOLID,
  906. /* COLOR_3DHILIGHT */ COLORFLAG_SOLID,
  907. /* COLOR_3DDKSHADOW */ COLORFLAG_SOLID,
  908. /* COLOR_3DLIGHT */ COLORFLAG_SOLID,
  909. /* COLOR_INFOTEXT */ COLORFLAG_SOLID,
  910. /* COLOR_INFOBK */ 0
  911. };
  912. COLORREF NearestColor(int iColor, COLORREF rgb)
  913. {
  914. rgb &= 0x00FFFFFF;
  915. //
  916. // if we are on a palette device, we need to do special stuff...
  917. //
  918. if (bPalette)
  919. {
  920. if (g_colorFlags[iColor] & COLORFLAG_SOLID)
  921. {
  922. rgb = GetNearestPaletteColor(hpal3D, rgb) | RGB_PALETTE;
  923. }
  924. else
  925. {
  926. if (IsPaletteColor(hpal3D, rgb))
  927. rgb |= RGB_PALETTE;
  928. else if (IsPaletteColor(GetStockObject(DEFAULT_PALETTE), rgb))
  929. rgb ^= 0x000001; // force a dither
  930. }
  931. }
  932. else
  933. {
  934. // map color to nearest color if we need to for this UI element.
  935. if (g_colorFlags[iColor] & COLORFLAG_SOLID)
  936. {
  937. HDC hdc = GetDC(NULL);
  938. rgb = GetNearestColor(hdc, rgb);
  939. ReleaseDC(NULL, hdc);
  940. }
  941. }
  942. return rgb;
  943. }
  944. COLORREF GetNearestPaletteColor(HPALETTE hpal, COLORREF rgb)
  945. {
  946. PALETTEENTRY pe;
  947. GetPaletteEntries(hpal, GetNearestPaletteIndex(hpal, rgb & 0x00FFFFFF), 1, &pe);
  948. return RGB(pe.peRed, pe.peGreen, pe.peBlue);
  949. }
  950. BOOL IsPaletteColor(HPALETTE hpal, COLORREF rgb)
  951. {
  952. return GetNearestPaletteColor(hpal, rgb) == (rgb & 0xFFFFFF);
  953. }
  954. // ------------------------ magic color utilities --------------------------
  955. /*
  956. ** set a color in the 3D palette.
  957. */
  958. void NEAR PASCAL Set3DPaletteColor(COLORREF rgb, int iColor)
  959. {
  960. int iPalette;
  961. PALETTEENTRY pe;
  962. if (!hpal3D)
  963. return;
  964. switch (iColor)
  965. {
  966. case COLOR_3DFACE:
  967. iPalette = 16;
  968. break;
  969. case COLOR_3DSHADOW:
  970. iPalette = 17;
  971. break;
  972. case COLOR_3DHILIGHT:
  973. iPalette = 18;
  974. break;
  975. default:
  976. return;
  977. }
  978. pe.peRed = GetRValue(rgb);
  979. pe.peGreen = GetGValue(rgb);
  980. pe.peBlue = GetBValue(rgb);
  981. pe.peFlags = 0;
  982. SetPaletteEntries(hpal3D, iPalette, 1, (LPPALETTEENTRY)&pe);
  983. }
  984. // ------------end--------- magic color utilities --------------------------
  985. // jdk: may need something like these to translate fonts ???
  986. #if 0
  987. void NEAR LF32toLF(LPLOGFONT_32 lplf32, LPLOGFONT lplf);
  988. void NEAR LFtoLF32(LPLOGFONT lplf, LPLOGFONT_32 lplf32);
  989. // ------------------------ manage system settings --------------------------
  990. /*
  991. ** Helper Routine since USER's new METRICS structures are all 32-bit
  992. */
  993. void NEAR LF32toLF(LPLOGFONT_32 lplf32, LPLOGFONT lplf)
  994. {
  995. lplf->lfHeight = (int) lplf32->lfHeight;
  996. lplf->lfWidth = (int) lplf32->lfWidth;
  997. lplf->lfEscapement = (int) lplf32->lfEscapement;
  998. lplf->lfOrientation = (int) lplf32->lfOrientation;
  999. lplf->lfWeight = (int) lplf32->lfWeight;
  1000. *((LPCOMMONFONT) &lplf->lfItalic) = lplf32->lfCommon;
  1001. }
  1002. void NEAR LFtoLF32(LPLOGFONT lplf, LPLOGFONT_32 lplf32)
  1003. {
  1004. lplf32->lfHeight = (LONG)lplf->lfHeight;
  1005. lplf32->lfWidth = (LONG)lplf->lfWidth;
  1006. lplf32->lfEscapement = (LONG)lplf->lfEscapement;
  1007. lplf32->lfOrientation = (LONG)lplf->lfOrientation;
  1008. lplf32->lfWeight = (LONG)lplf->lfWeight;
  1009. lplf32->lfCommon = *((LPCOMMONFONT) &lplf->lfItalic);
  1010. }
  1011. /*
  1012. ** Fill in a NONCLIENTMETRICS structure with latest preview stuff
  1013. */
  1014. void NEAR GetMyNonClientMetrics(LPNONCLIENTMETRICS lpncm)
  1015. {
  1016. lpncm->iBorderWidth = (LONG)(int)ncmTheme.iBorderWidth;
  1017. lpncm->iScrollWidth = lpncm->iScrollHeight = (LONG)(int)ncmTheme.iScrollWidth;
  1018. lpncm->iCaptionWidth = lpncm->iCaptionHeight = (LONG)(int)ncmTheme.iCaptionHeight;
  1019. lpncm->iSmCaptionWidth = lpncm->iSmCaptionHeight = (LONG)(int)ncmTheme.iSmCaptionHeight;
  1020. lpncm->iMenuWidth = lpncm->iMenuHeight = (LONG)(int)ncmTheme.iMenuHeight;
  1021. LFtoLF32(&(g_fonts[FONT_CAPTION].lf), &(lpncm->lfCaptionFont));
  1022. LFtoLF32(&(g_fonts[FONT_SMCAPTION].lf), &(lpncm->lfSmCaptionFont));
  1023. LFtoLF32(&(g_fonts[FONT_MENU].lf), &(lpncm->lfMenuFont));
  1024. LFtoLF32(&(g_fonts[FONT_STATUS].lf), &(lpncm->lfStatusFont));
  1025. LFtoLF32(&(g_fonts[FONT_MSGBOX].lf), &(lpncm->lfMessageFont));
  1026. }
  1027. /*
  1028. ** given a NONCLIENTMETRICS structure, make it preview's current setting
  1029. */
  1030. void NEAR SetMyNonClientMetrics(LPNONCLIENTMETRICS lpncm)
  1031. {
  1032. (int)ncmTheme.iBorderWidth = (int)lpncm->iBorderWidth;
  1033. (int)ncmTheme.iScrollWidth = (int)lpncm->iScrollWidth;
  1034. (int)ncmTheme.iCaptionHeight = (int)lpncm->iCaptionHeight;
  1035. (int)ncmTheme.iSmCaptionHeight = (int)lpncm->iSmCaptionHeight;
  1036. (int)ncmTheme.iMenuHeight = (int)lpncm->iMenuHeight;
  1037. LF32toLF(&(lpncm->lfCaptionFont), &(g_fonts[FONT_CAPTION].lf));
  1038. LF32toLF(&(lpncm->lfSmCaptionFont), &(g_fonts[FONT_SMCAPTION].lf));
  1039. LF32toLF(&(lpncm->lfMenuFont), &(g_fonts[FONT_MENU].lf));
  1040. LF32toLF(&(lpncm->lfStatusFont), &(g_fonts[FONT_STATUS].lf));
  1041. LF32toLF(&(lpncm->lfMessageFont), &(g_fonts[FONT_MSGBOX].lf));
  1042. }
  1043. #endif