xref: /reactos/dll/cpl/desk/advappdlg.c (revision 8a978a17)
1 /*
2  * COPYRIGHT:       See COPYING in the top level directory
3  * PROJECT:         ReactOS Display Control Panel
4  * FILE:            dll/cpl/desk/advappdlg.c
5  * PURPOSE:         Advanced appearance dialog
6  *
7  * PROGRAMMER:      Timo Kreuzer (timo[dot]kreuzer[at]web[dot]de)
8  *
9  */
10 
11 #include "desk.h"
12 
13 /******************************************************************************/
14 
15 typedef struct
16 {
17     int Size;
18     int Size2;
19     int Color1;
20     int Color2;
21     int Font;
22     int FontColor;
23 } ASSIGNMENT;
24 
25 /* This const assigns the color and metric numbers to the elements from the elements list */
26 
27 /*   Size 1 (width)          Size 2 (height)     Color 1                  Color 2                         Font             Fontcolor */
28 const ASSIGNMENT g_Assignment[NUM_ELEMENTS] =
29 {
30     {-1,                     -1,                 COLOR_DESKTOP,           -1,                             -1,              -1},                 /* Desktop */
31     {SIZE_CAPTION_HEIGHT,    -1,                 COLOR_INACTIVECAPTION,   COLOR_GRADIENTINACTIVECAPTION,  FONT_CAPTION,    COLOR_INACTIVECAPTIONTEXT},/* inactive window caption */
32     {SIZE_BORDER_WIDTH,      -1,                 COLOR_INACTIVEBORDER,    -1,                             -1,              -1},                 /* inactive window border */
33     {SIZE_CAPTION_HEIGHT,    -1,                 COLOR_ACTIVECAPTION,     COLOR_GRADIENTACTIVECAPTION,    FONT_CAPTION,    COLOR_CAPTIONTEXT},  /* active window caption */
34     {SIZE_BORDER_WIDTH,      -1,                 COLOR_ACTIVEBORDER,      -1,                             -1,              -1},                 /* active window border */
35     {SIZE_MENU_HEIGHT,       SIZE_MENU_WIDTH,    COLOR_MENU,              COLOR_MENUHILIGHT,              FONT_MENU,       COLOR_MENUTEXT},     /* menu */
36     {SIZE_MENU_HEIGHT,       SIZE_MENU_WIDTH,    COLOR_HIGHLIGHT,         -1,                             -1,              COLOR_HIGHLIGHTTEXT},/* marked element */
37     {-1,                     -1,                 COLOR_WINDOW,            -1 /*COLOR_WINDOWFRAME*/,       -1,              COLOR_WINDOWTEXT},   /* window */
38     {SIZE_SCROLL_WIDTH,      SIZE_SCROLL_HEIGHT, COLOR_SCROLLBAR,         -1,                             -1,              -1},                 /* scroll bar */
39     {-1,                     -1,                 COLOR_3DFACE,            -1,                             -1,              COLOR_BTNTEXT},      /* 3d objects */
40     {SIZE_SM_CAPTION_HEIGHT, -1,                 -1,                      -1,                             FONT_SMCAPTION,  -1},                 /* palette (small) window caption */
41     {SIZE_CAPTION_HEIGHT,    -1,                 -1,                      -1,                             -1,              -1},                 /* caption bar buttons */
42     {-1,                     -1,                 -1,                      -1,                             FONT_MESSAGE,    COLOR_WINDOWTEXT},   /* dialog */
43     {-1,                     -1,                 COLOR_APPWORKSPACE,      -1,                             -1,              -1},                 /* application background */
44     {SIZE_ICON_SPACE_X,      -1,                 -1,                      -1,                             -1,              -1},                 /* icon distance horiz. */
45     {SIZE_ICON_SPACE_Y,      -1,                 -1,                      -1,                             -1,              -1},                 /* icon distance vert. */
46     {-1,                     -1,                 COLOR_INFOBK,            -1,                             FONT_STATUS,     COLOR_INFOTEXT},     /* quickinfo */
47     {SIZE_ICON,              -1,                 -1,                      -1,                             FONT_ICON,       -1},                 /* icon */
48 //  {-1,                     -1,                 -1,                      -1,                             -1,              COLOR_GRAYTEXT},     /* inactive menu item -- FIXME: Access? */
49 };
50 
51 /******************************************************************************/
52 
53 /* Draw the current color on the color picker buttons */
54 static VOID
55 UpdateButtonColor(HWND hwndDlg, GLOBALS* g, INT ID, INT nButton, INT nColor)
56 {
57     HDC hdcColorButton, hdcCompat;
58     RECT rect;
59     HBRUSH hbrush;
60     HWND hwndColorButton;
61     HGDIOBJ hgdiTmp;
62 
63     if (nColor != -1)
64     {
65         /* Create a DC to draw on */
66         hwndColorButton = GetDlgItem(hwndDlg, ID);
67         hdcColorButton = GetDC(hwndColorButton);
68         hdcCompat = CreateCompatibleDC(hdcColorButton);
69         ReleaseDC(hwndColorButton, hdcColorButton);
70 
71         /* Select the button image to it */
72         hgdiTmp = SelectObject(hdcCompat, g->hbmpColor[nButton]);
73 
74         /* Create a brush and draw the rectangle */
75         rect.left = 2;
76         rect.top = 2;
77         rect.right = 22;
78         rect.bottom = 13;
79         hbrush = CreateSolidBrush(g->SchemeAdv.crColor[nColor]);
80         FillRect(hdcCompat, &rect, hbrush);
81         DeleteObject(hbrush);
82 
83         /* hdcCompat is not needed anymore */
84         SelectObject(hdcCompat,hgdiTmp);
85         DeleteDC(hdcCompat);
86 
87         SendDlgItemMessage(hwndDlg, ID, BM_SETIMAGE, (WPARAM)IMAGE_BITMAP, (LPARAM)g->hbmpColor[nButton]);
88         EnableWindow(GetDlgItem(hwndDlg, ID), TRUE);
89     }
90     else
91     {
92         SendDlgItemMessage(hwndDlg, ID, BM_SETIMAGE, (WPARAM)IMAGE_BITMAP, (LPARAM)NULL);
93         EnableWindow(GetDlgItem(hwndDlg, ID), FALSE);
94     }
95 }
96 
97 
98 /* Create the basic bitmaps for the color picker buttons */
99 static VOID
100 InitColorButtons(HWND hwndDlg, GLOBALS* g)
101 {
102     INT i;
103     HDC hdcColorButton, hdcCompat;
104     RECT rect;
105     HBRUSH hbrush;
106     HPEN hPen;
107     HWND hwndColorButton;
108     HGDIOBJ hgdiTemp;
109     COLOR_SCHEME *scheme = &g->SchemeAdv;
110 
111     const POINT Points[3] = {{29,6},{33,6},{31,8}};
112 
113     hwndColorButton = GetDlgItem(hwndDlg, IDC_ADVAPPEARANCE_COLOR1_B);
114     hdcColorButton = GetDC(hwndColorButton);
115     for (i = 0; i <= 2; i++)
116     {
117         /* Create a DC to draw on */
118         hdcCompat = CreateCompatibleDC(hdcColorButton);
119 
120         /* Create the button image */
121         g->hbmpColor[i] = CreateCompatibleBitmap(hdcColorButton, 36, 15);
122 
123         /* Select the button image to the DC */
124         hgdiTemp = SelectObject(hdcCompat, g->hbmpColor[i]);
125 
126         /* Draw the buttons background color */
127         rect.left = 0;
128         rect.top = 0;
129         rect.right = 36;
130         rect.bottom = 15;
131         hbrush = CreateSolidBrush(scheme->crColor[COLOR_BTNFACE]);
132         FillRect(hdcCompat, &rect, hbrush);
133         DeleteObject(hbrush);
134 
135         /* Draw the rectangle */
136         rect.left = 1;
137         rect.top = 1;
138         rect.right = 23;
139         rect.bottom = 14;
140         hbrush = CreateSolidBrush(scheme->crColor[COLOR_BTNTEXT]);
141         FillRect(hdcCompat, &rect, hbrush);
142         DeleteObject(hbrush);
143 
144         /* Draw left side of line */
145         hPen = CreatePen(PS_SOLID, 1, scheme->crColor[COLOR_BTNSHADOW]);
146         SelectObject(hdcCompat, hPen);
147         MoveToEx(hdcCompat, 26, 1, NULL);
148         LineTo(hdcCompat, 26, 14);
149         SelectObject(hdcCompat, GetStockObject(BLACK_PEN));
150         DeleteObject(hPen);
151 
152         /* Draw right side of line */
153         hPen = CreatePen(PS_SOLID, 1, scheme->crColor[COLOR_BTNHIGHLIGHT]);
154         SelectObject(hdcCompat,hPen);
155         MoveToEx(hdcCompat, 27, 1, NULL);
156         LineTo(hdcCompat, 27, 14);
157         SelectObject(hdcCompat, GetStockObject(BLACK_PEN));
158         DeleteObject(hPen);
159 
160         /* Draw triangle */
161         hPen = CreatePen(PS_SOLID, 1, scheme->crColor[COLOR_BTNTEXT]);
162         hbrush = CreateSolidBrush(scheme->crColor[COLOR_BTNTEXT]);
163         SelectObject(hdcCompat, hPen);
164         SelectObject(hdcCompat, hbrush);
165         SetPolyFillMode(hdcCompat, WINDING);
166 
167         /* FIXME: HACK, see Points definition */
168         Polygon(hdcCompat, Points, 3);
169 
170         /* Cleanup */
171         SelectObject(hdcCompat,hgdiTemp);
172         DeleteDC(hdcCompat);
173         DeleteObject(hPen);
174         DeleteObject(hbrush);
175     }
176 
177     ReleaseDC(hwndColorButton, hdcColorButton);
178 
179     /* Set the images of the buttons */
180     SendDlgItemMessage(hwndDlg, IDC_ADVAPPEARANCE_COLOR1_B, BM_SETIMAGE, (WPARAM)IMAGE_BITMAP, (LPARAM)g->hbmpColor[0]);
181     SendDlgItemMessage(hwndDlg, IDC_ADVAPPEARANCE_COLOR2_B, BM_SETIMAGE, (WPARAM)IMAGE_BITMAP, (LPARAM)g->hbmpColor[1]);
182     SendDlgItemMessage(hwndDlg, IDC_ADVAPPEARANCE_FONTCOLOR_B, BM_SETIMAGE, (WPARAM)IMAGE_BITMAP, (LPARAM)g->hbmpColor[2]);
183 }
184 
185 
186 /* This is the callback function to add the installed fonts to the font combo */
187 static int CALLBACK
188 EnumFontFamExProc(ENUMLOGFONTEX *lpelfe, NEWTEXTMETRICEX *lpntme, DWORD dwFontType, LPARAM lParam)
189 {
190     /* Don't enumerate more than 100 fonts */
191     if (SendMessage((HWND)lParam, CB_GETCOUNT, 0, 0) >= 100)
192         return 0;
193 
194     /* Only add the string once */
195     if (SendMessage((HWND)lParam, CB_FINDSTRINGEXACT, -1, (WPARAM)&(lpelfe->elfLogFont.lfFaceName)) != CB_ERR)
196         return 2;
197 
198     SendMessage((HWND)lParam, CB_ADDSTRING, 0, (WPARAM)&(lpelfe->elfLogFont.lfFaceName));
199 
200     return 1;
201 }
202 
203 
204 /* Update all the controls with the current values for the selected screen element */
205 static VOID
206 UpdateControls(HWND hwndDlg, GLOBALS *g)
207 {
208     INT iElement;
209     HDC hdcDlg;
210 
211     iElement = g->CurrentElement;
212 
213     /* First enable / disable the controls */
214     EnableWindow(GetDlgItem(hwndDlg, IDC_ADVAPPEARANCE_SIZE_E), (g_Assignment[iElement].Size != -1));
215     EnableWindow(GetDlgItem(hwndDlg, IDC_ADVAPPEARANCE_SIZE_UD), (g_Assignment[iElement].Size != -1));
216     EnableWindow(GetDlgItem(hwndDlg, IDC_ADVAPPEARANCE_SIZE_T), (g_Assignment[iElement].Size != -1));
217     EnableWindow(GetDlgItem(hwndDlg, IDC_ADVAPPEARANCE_COLOR1_T), (g_Assignment[iElement].Color1 != -1));
218     EnableWindow(GetDlgItem(hwndDlg, IDC_ADVAPPEARANCE_COLOR2_T), (g_Assignment[iElement].Color2 != -1));
219     EnableWindow(GetDlgItem(hwndDlg, IDC_ADVAPPEARANCE_FONT_T), (g_Assignment[iElement].Font != -1));
220     EnableWindow(GetDlgItem(hwndDlg, IDC_ADVAPPEARANCE_FONT_C), (g_Assignment[iElement].Font != -1));
221     EnableWindow(GetDlgItem(hwndDlg, IDC_ADVAPPEARANCE_FONTSIZE_T), (g_Assignment[iElement].Font != -1));
222     EnableWindow(GetDlgItem(hwndDlg, IDC_ADVAPPEARANCE_FONTSIZE_E), (g_Assignment[iElement].Font != -1));
223     EnableWindow(GetDlgItem(hwndDlg, IDC_ADVAPPEARANCE_FONTCOLOR_T), (g_Assignment[iElement].FontColor != -1));
224     EnableWindow(GetDlgItem(hwndDlg, IDC_ADVAPPEARANCE_FONTBOLD), (g_Assignment[iElement].Font != -1));
225     EnableWindow(GetDlgItem(hwndDlg, IDC_ADVAPPEARANCE_FONTITALIC), (g_Assignment[iElement].Font != -1));
226 
227     /* Update the colors of the color buttons */
228     UpdateButtonColor(hwndDlg, g, IDC_ADVAPPEARANCE_COLOR1_B, 0, g_Assignment[iElement].Color1);
229     UpdateButtonColor(hwndDlg, g, IDC_ADVAPPEARANCE_COLOR2_B, 1, g_Assignment[iElement].Color2);
230     UpdateButtonColor(hwndDlg, g, IDC_ADVAPPEARANCE_FONTCOLOR_B, 2, g_Assignment[iElement].FontColor);
231 
232     if (g_Assignment[iElement].Size != -1)
233         SetDlgItemInt(hwndDlg, IDC_ADVAPPEARANCE_SIZE_E,  SchemeGetMetric(&g->SchemeAdv, g_Assignment[iElement].Size), FALSE);
234     else
235         SetDlgItemText(hwndDlg, IDC_ADVAPPEARANCE_SIZE_E, TEXT(""));
236 
237     hdcDlg = GetDC(hwndDlg);
238     if (g_Assignment[iElement].Font != -1)
239     {
240         PLOGFONTW plfFont = SchemeGetFont(&g->SchemeAdv, g_Assignment[iElement].Font);
241 
242         SetDlgItemText(hwndDlg, IDC_ADVAPPEARANCE_FONT_C, plfFont->lfFaceName);
243         SetDlgItemInt(hwndDlg, IDC_ADVAPPEARANCE_FONTSIZE_E, -MulDiv(plfFont->lfHeight, 72, GetDeviceCaps(hdcDlg, LOGPIXELSY)), FALSE);
244         SendDlgItemMessage(hwndDlg, IDC_ADVAPPEARANCE_FONT_C, CB_FINDSTRINGEXACT, -1, (WPARAM)plfFont->lfFaceName);
245         SendDlgItemMessage(hwndDlg, IDC_ADVAPPEARANCE_FONTBOLD, BM_SETCHECK, plfFont->lfWeight == FW_BOLD?1:0, 0);
246         SendDlgItemMessage(hwndDlg, IDC_ADVAPPEARANCE_FONTITALIC, BM_SETCHECK, plfFont->lfItalic, 0);
247     }
248     else
249     {
250         SetDlgItemText(hwndDlg, IDC_ADVAPPEARANCE_FONT_C, NULL);
251         SetDlgItemText(hwndDlg, IDC_ADVAPPEARANCE_FONTSIZE_E, NULL);
252         SendDlgItemMessage(hwndDlg, IDC_ADVAPPEARANCE_FONTBOLD, BM_SETCHECK, 0, 0);
253         SendDlgItemMessage(hwndDlg, IDC_ADVAPPEARANCE_FONTITALIC, BM_SETCHECK, 0, 0);
254     }
255 
256     ReleaseDC(hwndDlg, hdcDlg);
257 }
258 
259 
260 static VOID
261 SaveCurrentValues(HWND hwndDlg, GLOBALS *g)
262 {
263     BOOL bTranslated;
264     HDC hdcDlg = GetDC(hwndDlg);
265 
266     if (g_Assignment[g->CurrentElement].Size != -1)
267     {
268         SchemeSetMetric(&g->SchemeAdv, g_Assignment[g->CurrentElement].Size, GetDlgItemInt(hwndDlg, IDC_ADVAPPEARANCE_SIZE_E, &bTranslated, FALSE));
269     }
270 
271     if (g_Assignment[g->CurrentElement].Font != -1)
272     {
273         PLOGFONTW plfFont = SchemeGetFont(&g->SchemeAdv, g_Assignment[g->CurrentElement].Font);
274         plfFont->lfHeight = -MulDiv(GetDlgItemInt(hwndDlg, IDC_ADVAPPEARANCE_FONTSIZE_E, &bTranslated, FALSE), GetDeviceCaps(hdcDlg, LOGPIXELSY), 72);
275         plfFont->lfWeight = (SendDlgItemMessage(hwndDlg, IDC_ADVAPPEARANCE_FONTBOLD, BM_GETCHECK, 0, 0) == 1) ? FW_BOLD : FW_NORMAL;
276         plfFont->lfItalic = (BYTE)SendDlgItemMessage(hwndDlg, IDC_ADVAPPEARANCE_FONTITALIC, BM_GETCHECK, 0, 0);
277         GetDlgItemText(hwndDlg, IDC_ADVAPPEARANCE_FONT_C, plfFont->lfFaceName, LF_FACESIZE);
278     }
279 
280     ReleaseDC(hwndDlg, hdcDlg);
281 }
282 
283 
284 /* Select a color using a color picker */
285 static BOOL
286 GetColor(HWND hwndDlg, GLOBALS* g, INT nButton)
287 {
288     CHOOSECOLOR cc;
289     COLORREF crCustom[16] = { 0 };
290     COLORREF crColor;
291     INT ID = 0;
292     INT ColorIndex = 0;
293 
294     /* Get the color index from the element index and button number */
295     switch (nButton)
296     {
297         case 0:
298             ColorIndex = g_Assignment[g->CurrentElement].Color1;
299             ID = IDC_ADVAPPEARANCE_COLOR1_B;
300             break;
301 
302         case 1:
303             ColorIndex = g_Assignment[g->CurrentElement].Color2;
304             ID = IDC_ADVAPPEARANCE_COLOR2_B;
305             break;
306 
307         case 2:
308             ColorIndex = g_Assignment[g->CurrentElement].FontColor;
309             ID = IDC_ADVAPPEARANCE_FONTCOLOR_B;
310             break;
311     }
312 
313     crColor = g->SchemeAdv.crColor[ColorIndex];
314 
315     /* Prepare cc structure */
316     cc.lStructSize = sizeof(CHOOSECOLOR);
317     cc.hwndOwner = hwndDlg;
318     cc.hInstance = NULL;
319     cc.rgbResult = crColor;
320     cc.lpCustColors = crCustom;
321     cc.Flags = CC_ANYCOLOR | CC_FULLOPEN | CC_RGBINIT;
322     cc.lCustData = 0;
323     cc.lpfnHook = NULL;
324     cc.lpTemplateName = NULL;
325 
326     /* Create the colorpicker */
327     if (ChooseColor(&cc))
328     {
329         g->SchemeAdv.crColor[ColorIndex] = cc.rgbResult;
330         if (crColor != cc.rgbResult)
331         {
332             UpdateButtonColor(hwndDlg, g, ID, nButton, ColorIndex);
333             SendDlgItemMessage(hwndDlg, IDC_APPEARANCE_PREVIEW, PVM_UPDATETHEME, 0, (LPARAM)&g->SchemeAdv);
334             return TRUE;
335         }
336     }
337 
338     return FALSE;
339 }
340 
341 
342 /* Initialize the advanced appearance dialog */
343 static VOID
344 AdvAppearanceDlg_Init(HWND hwndDlg, GLOBALS *g)
345 {
346     INT i, iElement, iListIndex, iDeskIndex = 0;
347     TCHAR tstrText[80];
348     LOGFONT lfFont;
349     LOGFONT lfButtonFont;
350     HFONT hMyFont;
351     HDC hScreenDC;
352     TCHAR Size[4];
353 
354     /* Copy the current theme values */
355     g->SchemeAdv = g->Scheme;
356 
357     SendDlgItemMessage(hwndDlg, IDC_APPEARANCE_PREVIEW, PVM_UPDATETHEME, 0, (LPARAM)&g->SchemeAdv);
358 
359     /* Add the elements to the combo */
360     for (iElement = 0; iElement < NUM_ELEMENTS; iElement++)
361     {
362         LoadString(hApplet, IDS_ELEMENT_0 + iElement, (LPTSTR)&tstrText, 79);
363         iListIndex = SendDlgItemMessage(hwndDlg, IDC_ADVAPPEARANCE_ELEMENT, CB_ADDSTRING, 0, (LPARAM)&tstrText);
364         SendDlgItemMessage(hwndDlg, IDC_ADVAPPEARANCE_ELEMENT, CB_SETITEMDATA, (WPARAM)iListIndex, (LPARAM)iElement);
365     }
366 
367     /* Get the list index of the desktop element */
368     for (iListIndex = 0; iListIndex < NUM_ELEMENTS; iListIndex++)
369     {
370         iElement = SendDlgItemMessage(hwndDlg, IDC_ADVAPPEARANCE_ELEMENT, CB_GETITEMDATA, (WPARAM)iListIndex, 0);
371         if (iElement == 0)
372         {
373             iDeskIndex = iListIndex;
374             break;
375         }
376     }
377 
378     SendDlgItemMessage(hwndDlg, IDC_ADVAPPEARANCE_ELEMENT, CB_SETCURSEL, iDeskIndex, 0);
379 
380     /* Create font for bold button */
381     lfButtonFont = g->Scheme.ncMetrics.lfMessageFont;
382     lfButtonFont.lfWeight = FW_BOLD;
383     lfButtonFont.lfItalic = FALSE;
384     hMyFont = CreateFontIndirect(&lfButtonFont);
385     if (hMyFont)
386     {
387         if (g->hBoldFont)
388             DeleteObject(g->hBoldFont);
389 
390         g->hBoldFont = hMyFont;
391     }
392 
393     /* Create font for italic button */
394     lfButtonFont.lfWeight = FW_REGULAR;
395     lfButtonFont.lfItalic = TRUE;
396     hMyFont = CreateFontIndirect(&lfButtonFont);
397     if (hMyFont)
398     {
399         if (g->hItalicFont)
400             DeleteObject(g->hItalicFont);
401 
402         g->hItalicFont = hMyFont;
403     }
404 
405     /* Set the fonts for the font style buttons */
406     SendDlgItemMessage(hwndDlg, IDC_ADVAPPEARANCE_FONTBOLD, WM_SETFONT, (WPARAM)g->hBoldFont, (LPARAM)TRUE);
407     SendDlgItemMessage(hwndDlg, IDC_ADVAPPEARANCE_FONTITALIC, WM_SETFONT, (WPARAM)g->hItalicFont, (LPARAM)TRUE);
408 
409     /* Draw Bitmaps for the colorbuttons */
410     InitColorButtons(hwndDlg, g);
411 
412     /* Make the UpDown control count correctly */
413     SendMessage(GetDlgItem(hwndDlg, IDC_ADVAPPEARANCE_SIZE_UD), UDM_SETRANGE, 0L, MAKELONG (200, 1));
414 
415     /* Fill font selection combo */
416     lfFont.lfCharSet = DEFAULT_CHARSET;
417     lfFont.lfFaceName[0] = (TCHAR)0;
418     lfFont.lfPitchAndFamily = 0;
419     hScreenDC = GetDC(0);
420     EnumFontFamiliesEx(hScreenDC, &lfFont, (FONTENUMPROC)EnumFontFamExProc, (LPARAM)GetDlgItem(hwndDlg, IDC_ADVAPPEARANCE_FONT_C), 0);
421     ReleaseDC(0, hScreenDC);
422 
423     /* Fill font size combo */
424     for (i = 6; i <= 24; i++)
425     {
426         StringCbPrintf(Size, sizeof(Size), TEXT("%d"), i);
427         SendDlgItemMessage(hwndDlg, IDC_ADVAPPEARANCE_FONTSIZE_E, CB_ADDSTRING, 0, (LPARAM)&Size);
428     }
429 
430     /* Update the controls */
431     iListIndex = SendDlgItemMessage(hwndDlg, IDC_ADVAPPEARANCE_ELEMENT, CB_GETCURSEL, 0, 0);
432     g->CurrentElement = SendDlgItemMessage(hwndDlg, IDC_ADVAPPEARANCE_ELEMENT, CB_GETITEMDATA, (WPARAM)iListIndex, 0);
433     UpdateControls(hwndDlg, g);
434 }
435 
436 
437 static VOID
438 AdvAppearanceDlg_CleanUp(HWND hwndDlg, GLOBALS* g)
439 {
440     DeleteObject(g->hBoldFont);
441     DeleteObject(g->hItalicFont);
442 }
443 
444 
445 static VOID
446 SelectComboByElement(HWND hwnd, INT id, LPARAM lParam)
447 {
448     INT nCount;
449     INT i;
450 
451     nCount = SendDlgItemMessage(hwnd, id, CB_GETCOUNT, 0, 0);
452     if (nCount == CB_ERR)
453         return;
454 
455     for (i = 0; i < nCount; i++)
456     {
457         if (SendDlgItemMessage(hwnd, id, CB_GETITEMDATA, (WPARAM)i, 0) == lParam)
458         {
459             SendDlgItemMessage(hwnd, id, CB_SETCURSEL, (WPARAM)i, 0);
460             break;
461         }
462     }
463 }
464 
465 
466 static VOID
467 GetSelectedComboText(HWND hwnd, INT id, LPWSTR lpStr)
468 {
469     INT nCount;
470 
471     nCount = SendDlgItemMessage(hwnd, id, CB_GETCURSEL, 0, 0);
472     if (nCount == CB_ERR)
473     {
474         *lpStr = 0;
475         return;
476     }
477 
478     nCount = SendDlgItemMessage(hwnd, id, CB_GETLBTEXT, (WPARAM)nCount, (LPARAM)lpStr);
479     if (nCount == CB_ERR)
480     {
481         *lpStr = 0;
482     }
483 }
484 
485 
486 static INT
487 GetSelectedComboInt(HWND hwnd, INT id)
488 {
489     TCHAR szBuffer[80];
490     INT nCount;
491 
492     nCount = SendDlgItemMessage(hwnd, id, CB_GETCURSEL, 0, 0);
493     if (nCount == CB_ERR)
494         return 0;
495 
496     nCount = SendDlgItemMessage(hwnd, id, CB_GETLBTEXT, (WPARAM)nCount, (LPARAM)szBuffer);
497     if (nCount == CB_ERR)
498         return 0;
499 
500     return _ttoi(szBuffer);
501 }
502 
503 INT_PTR CALLBACK
504 AdvAppearanceDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
505 {
506     INT iSelection, iProperty;
507     GLOBALS* g;
508     PLOGFONTW plfFont;
509 
510     g = (GLOBALS*)GetWindowLongPtr(hwndDlg, DWLP_USER);
511 
512     switch (uMsg)
513     {
514         case WM_INITDIALOG:
515             g = (GLOBALS*)lParam;
516             SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)g);
517             AdvAppearanceDlg_Init(hwndDlg, g);
518             break;
519 
520         case WM_DESTROY:
521             AdvAppearanceDlg_CleanUp(hwndDlg, g);
522             break;
523 
524         case WM_COMMAND:
525             if (g == NULL)
526                 return TRUE;
527 
528             switch(LOWORD(wParam))
529             {
530                 case IDOK:
531                     SaveCurrentValues(hwndDlg, g);
532                     EndDialog(hwndDlg, IDOK);
533                     break;
534 
535                 case IDCANCEL:
536                     g->SchemeAdv = g->Scheme;
537                     EndDialog(hwndDlg, IDCANCEL);
538                     break;
539 
540                 case IDC_APPEARANCE_PREVIEW:
541                     SaveCurrentValues(hwndDlg, g);
542                     SelectComboByElement(hwndDlg, IDC_ADVAPPEARANCE_ELEMENT, lParam);
543                     g->CurrentElement = (INT)lParam;
544                     UpdateControls(hwndDlg, g);
545                     break;
546 
547                 case IDC_ADVAPPEARANCE_ELEMENT:
548                     if (HIWORD(wParam) == CBN_SELCHANGE)
549                     {
550                         SaveCurrentValues(hwndDlg, g);
551                         iSelection = SendDlgItemMessage(hwndDlg, IDC_ADVAPPEARANCE_ELEMENT, CB_GETCURSEL, 0, 0);
552                         g->CurrentElement = SendDlgItemMessage(hwndDlg, IDC_ADVAPPEARANCE_ELEMENT, CB_GETITEMDATA, iSelection, 0);
553                         UpdateControls(hwndDlg, g);
554                     }
555                     break;
556 
557                 case IDC_ADVAPPEARANCE_SIZE_E:
558                     if (HIWORD(wParam) == EN_CHANGE)
559                     {
560                         iProperty = g_Assignment[g->CurrentElement].Size;
561                         if (iProperty == -1)
562                             return TRUE;
563 
564                         iSelection = LOWORD(SendDlgItemMessage(hwndDlg, IDC_ADVAPPEARANCE_SIZE_UD, UDM_GETPOS,0,0L));
565                         SchemeSetMetric(&g->SchemeAdv, iProperty, iSelection);
566                         SendDlgItemMessage(hwndDlg, IDC_APPEARANCE_PREVIEW, PVM_SETSIZE, iProperty, iSelection);
567 
568                         iProperty = g_Assignment[g->CurrentElement].Size2;
569                         if (iProperty != -1)
570                             SchemeSetMetric(&g->SchemeAdv, iProperty, iSelection);
571                     }
572                     break;
573 
574                 case IDC_ADVAPPEARANCE_FONT_C:
575                     if (HIWORD(wParam) == CBN_SELCHANGE)
576                     {
577                         iProperty = g_Assignment[g->CurrentElement].Font;
578                         if (iProperty == -1)
579                             return TRUE;
580 
581                         plfFont = SchemeGetFont(&g->SchemeAdv, iProperty);
582                         GetSelectedComboText(hwndDlg, IDC_ADVAPPEARANCE_FONT_C, plfFont->lfFaceName);
583                         SendDlgItemMessage(hwndDlg, IDC_APPEARANCE_PREVIEW, PVM_SETFONT, iProperty, (LPARAM)plfFont);
584                     }
585                     break;
586 
587                 case IDC_ADVAPPEARANCE_FONTSIZE_E:
588                     if ((HIWORD(wParam) == CBN_SELCHANGE || HIWORD(wParam) == CBN_EDITCHANGE))
589                     {
590                         HDC hdcDlg;
591 
592                         iProperty =  g_Assignment[g->CurrentElement].Font;
593                         if (iProperty == -1)
594                             return TRUE;
595 
596                         hdcDlg = GetDC(hwndDlg);
597 
598                         plfFont = SchemeGetFont(&g->SchemeAdv, iProperty);
599                         iSelection = GetSelectedComboInt(hwndDlg, IDC_ADVAPPEARANCE_FONTSIZE_E);
600                         plfFont->lfHeight = -MulDiv(iSelection , GetDeviceCaps(hdcDlg, LOGPIXELSY), 72);
601                         SendDlgItemMessage(hwndDlg, IDC_APPEARANCE_PREVIEW, PVM_UPDATETHEME, 0, (LPARAM)&g->SchemeAdv);
602 
603                         ReleaseDC(hwndDlg, hdcDlg);
604                     }
605                     break;
606 
607                 case IDC_ADVAPPEARANCE_FONTBOLD:
608                     if (HIWORD(wParam) == BN_CLICKED)
609                     {
610                         iProperty = g_Assignment[g->CurrentElement].Font;
611                         if (iProperty == -1)
612                             return TRUE;
613 
614                         plfFont = SchemeGetFont(&g->SchemeAdv, iProperty);
615                         iSelection = (INT)SendDlgItemMessage(hwndDlg, IDC_ADVAPPEARANCE_FONTBOLD, BM_GETCHECK, 0, 0);
616                         plfFont->lfWeight = (iSelection == BST_CHECKED) ? FW_BOLD : FW_NORMAL;
617                         SendDlgItemMessage(hwndDlg, IDC_APPEARANCE_PREVIEW, PVM_SETFONT, iProperty, (LPARAM)plfFont);
618                     }
619                     break;
620 
621                 case IDC_ADVAPPEARANCE_FONTITALIC:
622                     if (HIWORD(wParam) == BN_CLICKED)
623                     {
624                         iProperty = g_Assignment[g->CurrentElement].Font;
625                         if (iProperty == -1)
626                             return TRUE;
627 
628                         plfFont = SchemeGetFont(&g->SchemeAdv, iProperty);
629                         iSelection = (INT)SendDlgItemMessage(hwndDlg, IDC_ADVAPPEARANCE_FONTITALIC, BM_GETCHECK, 0, 0);
630                         plfFont->lfItalic = (iSelection == BST_CHECKED) ? TRUE : FALSE;
631                         SendDlgItemMessage(hwndDlg, IDC_APPEARANCE_PREVIEW, PVM_SETFONT, iProperty, (LPARAM)plfFont);
632                     }
633                     break;
634 
635                 case IDC_ADVAPPEARANCE_COLOR1_B:
636                     GetColor(hwndDlg, g, 0);
637                     break;
638 
639                 case IDC_ADVAPPEARANCE_COLOR2_B:
640                     GetColor(hwndDlg, g, 1);
641                     break;
642 
643                 case IDC_ADVAPPEARANCE_FONTCOLOR_B:
644                     GetColor(hwndDlg, g, 2);
645                     break;
646 
647                 default:
648                     return FALSE;
649             }
650             break;
651 
652         default:
653             return FALSE;
654     }
655 
656     return TRUE;
657 }
658