[WINHTTP] Sync with Wine Staging 3.9. CORE-14656
[reactos.git] / dll / cpl / desk / preview.c
1 /*
2 * PROJECT: ReactOS Desktop Control Panel
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: dll/cpl/desk/preview.c
5 * PURPOSE: Draws the preview control
6 * COPYRIGHT: Copyright 2006, 2007 Eric Kohl
7 */
8
9 #include "desk.h"
10
11 static const TCHAR szPreviewWndClass[] = TEXT("PreviewWndClass");
12
13 typedef struct _PREVIEW_DATA
14 {
15 HDC hdcPreview;
16
17 HWND hwndParent;
18
19 COLOR_SCHEME Scheme;
20
21 HBRUSH hbrScrollbar;
22 HBRUSH hbrDesktop;
23 HBRUSH hbrWindow;
24
25 INT cxEdge;
26 INT cyEdge;
27
28 INT cySizeFrame;
29
30 INT cyCaption;
31 INT cyBorder;
32 INT cyMenu;
33 INT cxScrollbar;
34
35 RECT rcDesktop;
36 RECT rcInactiveFrame;
37 RECT rcInactiveCaption;
38 RECT rcInactiveCaptionButtons;
39
40 RECT rcActiveFrame;
41 RECT rcActiveCaption;
42 RECT rcActiveCaptionButtons;
43 RECT rcActiveMenuBar;
44 RECT rcSelectedMenuItem;
45 RECT rcActiveClient;
46 RECT rcActiveScroll;
47
48 RECT rcDialogFrame;
49 RECT rcDialogCaption;
50 RECT rcDialogCaptionButtons;
51 RECT rcDialogClient;
52
53 RECT rcDialogButton;
54
55 LPTSTR lpInAct;
56 LPTSTR lpAct;
57 LPTSTR lpWinTxt;
58 LPTSTR lpMessBox;
59 LPTSTR lpMessText;
60 LPTSTR lpButText;
61
62 HFONT hCaptionFont;
63 HFONT hMenuFont;
64 HFONT hMessageFont;
65 HFONT hClientFont;
66
67 HMENU hMenu;
68
69 } PREVIEW_DATA, *PPREVIEW_DATA;
70
71
72 static VOID UpdatePreviewTheme(HWND hwnd, PPREVIEW_DATA pPreviewData, COLOR_SCHEME *scheme)
73 {
74 if (pPreviewData->hbrScrollbar != NULL)
75 DeleteObject(pPreviewData->hbrScrollbar);
76 pPreviewData->hbrScrollbar = CreateSolidBrush(scheme->crColor[COLOR_SCROLLBAR]);
77 if (pPreviewData->hbrDesktop != NULL)
78 DeleteObject(pPreviewData->hbrDesktop);
79
80 pPreviewData->hbrDesktop = CreateSolidBrush(scheme->crColor[COLOR_DESKTOP]);
81 if (pPreviewData->hbrWindow != NULL)
82 DeleteObject(pPreviewData->hbrWindow);
83 pPreviewData->hbrWindow = CreateSolidBrush(scheme->crColor[COLOR_WINDOW]);
84
85 pPreviewData->cxEdge = 2; /* SM_CXEDGE */
86 pPreviewData->cyEdge = 2; /* SM_CYEDGE */
87
88 pPreviewData->cySizeFrame = scheme->ncMetrics.iBorderWidth; /* SM_CYSIZEFRAME */
89
90 pPreviewData->cyCaption = scheme->ncMetrics.iCaptionHeight+1; /* SM_CYCAPTION */
91 pPreviewData->cyMenu = scheme->ncMetrics.iMenuHeight -1; /* SM_CYMENU */
92 pPreviewData->cxScrollbar = scheme->ncMetrics.iScrollWidth; /* SM_CXVSCROLL */
93 pPreviewData->cyBorder = scheme->ncMetrics.iBorderWidth; /* SM_CYBORDER */
94
95 if (pPreviewData->hCaptionFont != NULL)
96 DeleteObject(pPreviewData->hCaptionFont);
97 pPreviewData->hCaptionFont = CreateFontIndirect(&scheme->ncMetrics.lfCaptionFont);
98
99 if (pPreviewData->hMenuFont != NULL)
100 DeleteObject(pPreviewData->hMenuFont);
101 pPreviewData->hMenuFont = CreateFontIndirect(&scheme->ncMetrics.lfMenuFont);
102
103 if (pPreviewData->hMessageFont != NULL)
104 DeleteObject(pPreviewData->hMessageFont);
105 pPreviewData->hMessageFont = CreateFontIndirect(&scheme->ncMetrics.lfMessageFont);
106
107 pPreviewData->Scheme = *scheme;
108 InvalidateRect(hwnd, NULL, FALSE);
109 }
110
111 static VOID
112 OnCreate(HWND hwnd, PPREVIEW_DATA pPreviewData)
113 {
114 COLOR_SCHEME *scheme;
115
116 pPreviewData->hClientFont = (HFONT)GetStockObject(DEFAULT_GUI_FONT);
117
118 /* Load and modify the menu */
119 pPreviewData->hMenu = LoadMenu(hApplet, MAKEINTRESOURCE(IDR_PREVIEW_MENU));
120 EnableMenuItem(pPreviewData->hMenu,
121 1, MF_BYPOSITION | MF_GRAYED);
122 HiliteMenuItem(hwnd, pPreviewData->hMenu,
123 2, MF_BYPOSITION | MF_HILITE);
124
125 // GetMenuItemRect(hwnd, pPreviewData->hMenu,
126 // 2, &pPreviewData->rcSelectedMenuItem);
127
128 AllocAndLoadString(&pPreviewData->lpInAct, hApplet, IDS_INACTWIN);
129 AllocAndLoadString(&pPreviewData->lpAct, hApplet, IDS_ACTWIN);
130 AllocAndLoadString(&pPreviewData->lpWinTxt, hApplet, IDS_WINTEXT);
131 AllocAndLoadString(&pPreviewData->lpMessBox, hApplet, IDS_MESSBOX);
132 AllocAndLoadString(&pPreviewData->lpMessText, hApplet, IDS_MESSTEXT);
133 AllocAndLoadString(&pPreviewData->lpButText, hApplet, IDS_BUTTEXT);
134
135 scheme = &pPreviewData->Scheme;
136 LoadCurrentScheme(scheme);
137
138 UpdatePreviewTheme(hwnd, pPreviewData, scheme);
139 }
140
141
142 static VOID
143 CalculateItemSize(PPREVIEW_DATA pPreviewData)
144 {
145 int width, height;
146
147 /* Calculate the inactive window rectangle */
148 pPreviewData->rcInactiveFrame.left = pPreviewData->rcDesktop.left + 8;
149 pPreviewData->rcInactiveFrame.top = pPreviewData->rcDesktop.top + 8;
150 pPreviewData->rcInactiveFrame.right = pPreviewData->rcDesktop.right - 25;
151 pPreviewData->rcInactiveFrame.bottom = pPreviewData->rcDesktop.bottom - 30;
152
153 /* Calculate the inactive caption rectangle */
154 pPreviewData->rcInactiveCaption.left = pPreviewData->rcInactiveFrame.left + pPreviewData->cxEdge + pPreviewData->cySizeFrame + 1;
155 pPreviewData->rcInactiveCaption.top = pPreviewData->rcInactiveFrame.top + pPreviewData->cyEdge + pPreviewData->cySizeFrame + 1;
156 pPreviewData->rcInactiveCaption.right = pPreviewData->rcInactiveFrame.right - pPreviewData->cxEdge - pPreviewData->cySizeFrame - 1;
157 pPreviewData->rcInactiveCaption.bottom = pPreviewData->rcInactiveCaption.top + pPreviewData->cyCaption - pPreviewData->cyBorder;
158
159 /* Calculate the inactive caption buttons rectangle */
160 pPreviewData->rcInactiveCaptionButtons.left = pPreviewData->rcInactiveCaption.right - 2 - 2 - 3 * 16;
161 pPreviewData->rcInactiveCaptionButtons.top = pPreviewData->rcInactiveCaption.top + 2;
162 pPreviewData->rcInactiveCaptionButtons.right = pPreviewData->rcInactiveCaption.right - 2;
163 pPreviewData->rcInactiveCaptionButtons.bottom = pPreviewData->rcInactiveCaption.bottom - 2;
164
165 /* Calculate the active window rectangle */
166 pPreviewData->rcActiveFrame.left = pPreviewData->rcInactiveFrame.left + 3 + pPreviewData->cySizeFrame;
167 pPreviewData->rcActiveFrame.top = pPreviewData->rcInactiveCaption.bottom + 1;
168 pPreviewData->rcActiveFrame.right = pPreviewData->rcDesktop.right - 10;
169 pPreviewData->rcActiveFrame.bottom = pPreviewData->rcDesktop.bottom - 25;
170
171 /* Calculate the active caption rectangle */
172 pPreviewData->rcActiveCaption.left = pPreviewData->rcActiveFrame.left + pPreviewData->cxEdge + pPreviewData->cySizeFrame + 1;
173 pPreviewData->rcActiveCaption.top = pPreviewData->rcActiveFrame.top + pPreviewData->cxEdge + pPreviewData->cySizeFrame + 1;
174 pPreviewData->rcActiveCaption.right = pPreviewData->rcActiveFrame.right - pPreviewData->cxEdge - pPreviewData->cySizeFrame - 1;
175 pPreviewData->rcActiveCaption.bottom = pPreviewData->rcActiveCaption.top + pPreviewData->cyCaption - pPreviewData->cyBorder;
176
177 /* Calculate the active caption buttons rectangle */
178 pPreviewData->rcActiveCaptionButtons.left = pPreviewData->rcActiveCaption.right - 2 - 2 - 3 * 16;
179 pPreviewData->rcActiveCaptionButtons.top = pPreviewData->rcActiveCaption.top + 2;
180 pPreviewData->rcActiveCaptionButtons.right = pPreviewData->rcActiveCaption.right - 2;
181 pPreviewData->rcActiveCaptionButtons.bottom = pPreviewData->rcActiveCaption.bottom - 2;
182
183 /* Calculate the active menu bar rectangle */
184 pPreviewData->rcActiveMenuBar.left = pPreviewData->rcActiveFrame.left + pPreviewData->cxEdge + pPreviewData->cySizeFrame + 1;
185 pPreviewData->rcActiveMenuBar.top = pPreviewData->rcActiveCaption.bottom + 1;
186 pPreviewData->rcActiveMenuBar.right = pPreviewData->rcActiveFrame.right - pPreviewData->cxEdge - pPreviewData->cySizeFrame - 1;
187 pPreviewData->rcActiveMenuBar.bottom = pPreviewData->rcActiveMenuBar.top + pPreviewData->cyMenu + 1;
188
189 /* Calculate the active client rectangle */
190 pPreviewData->rcActiveClient.left = pPreviewData->rcActiveFrame.left + pPreviewData->cxEdge + pPreviewData->cySizeFrame + 1;
191 pPreviewData->rcActiveClient.top = pPreviewData->rcActiveMenuBar.bottom;
192 pPreviewData->rcActiveClient.right = pPreviewData->rcActiveFrame.right - pPreviewData->cxEdge - pPreviewData->cySizeFrame - 1;
193 pPreviewData->rcActiveClient.bottom = pPreviewData->rcActiveFrame.bottom - pPreviewData->cyEdge - pPreviewData->cySizeFrame - 1;
194
195 /* Calculate the active scroll rectangle */
196 pPreviewData->rcActiveScroll.left = pPreviewData->rcActiveClient.right - 2 - pPreviewData->cxScrollbar;
197 pPreviewData->rcActiveScroll.top = pPreviewData->rcActiveClient.top + 2;
198 pPreviewData->rcActiveScroll.right = pPreviewData->rcActiveClient.right - 2;
199 pPreviewData->rcActiveScroll.bottom = pPreviewData->rcActiveClient.bottom - 2;
200
201
202 /* Dialog window */
203 pPreviewData->rcDialogFrame.left = pPreviewData->rcActiveClient.left + 4;
204 pPreviewData->rcDialogFrame.top = (pPreviewData->rcDesktop.bottom * 60) / 100;
205 pPreviewData->rcDialogFrame.right = (pPreviewData->rcDesktop.right * 65) / 100;
206 pPreviewData->rcDialogFrame.bottom = pPreviewData->rcDesktop.bottom - 5;
207
208 /* Calculate the dialog caption rectangle */
209 pPreviewData->rcDialogCaption.left = pPreviewData->rcDialogFrame.left + 3;
210 pPreviewData->rcDialogCaption.top = pPreviewData->rcDialogFrame.top + 3;
211 pPreviewData->rcDialogCaption.right = pPreviewData->rcDialogFrame.right - 3;
212 pPreviewData->rcDialogCaption.bottom = pPreviewData->rcDialogFrame.top + pPreviewData->cyCaption + 1 + 1;
213
214 /* Calculate the inactive caption buttons rectangle */
215 pPreviewData->rcDialogCaptionButtons.left = pPreviewData->rcDialogCaption.right - 2 - 16;
216 pPreviewData->rcDialogCaptionButtons.top = pPreviewData->rcDialogCaption.top + 2;
217 pPreviewData->rcDialogCaptionButtons.right = pPreviewData->rcDialogCaption.right - 2;
218 pPreviewData->rcDialogCaptionButtons.bottom = pPreviewData->rcDialogCaption.bottom - 2;
219
220 /* Calculate the dialog client rectangle */
221 pPreviewData->rcDialogClient.left = pPreviewData->rcDialogFrame.left + 3;
222 pPreviewData->rcDialogClient.top = pPreviewData->rcDialogCaption.bottom + 1;
223 pPreviewData->rcDialogClient.right = pPreviewData->rcDialogFrame.right - 3;
224 pPreviewData->rcDialogClient.bottom = pPreviewData->rcDialogFrame.bottom - 3;
225
226 /* Calculate the dialog button rectangle */
227 width = 80;
228 height = 28;
229
230 pPreviewData->rcDialogButton.left =
231 (pPreviewData->rcDialogClient.right + pPreviewData->rcDialogClient.left - width) / 2;
232 pPreviewData->rcDialogButton.right = pPreviewData->rcDialogButton.left + width;
233 pPreviewData->rcDialogButton.bottom = pPreviewData->rcDialogClient.bottom - 2;
234 pPreviewData->rcDialogButton.top = pPreviewData->rcDialogButton.bottom - height;
235 }
236
237
238 static VOID
239 OnSize(INT cx, INT cy, PPREVIEW_DATA pPreviewData)
240 {
241 /* Get Desktop rectangle */
242 pPreviewData->rcDesktop.left = 0;
243 pPreviewData->rcDesktop.top = 0;
244 pPreviewData->rcDesktop.right = cx;
245 pPreviewData->rcDesktop.bottom = cy;
246
247 CalculateItemSize(pPreviewData);
248 }
249
250 static VOID
251 OnPaint(HWND hwnd, PPREVIEW_DATA pPreviewData)
252 {
253 PAINTSTRUCT ps;
254 HFONT hOldFont;
255 HDC hdc;
256 RECT rc;
257 COLOR_SCHEME *scheme;
258
259 scheme = &pPreviewData->Scheme;
260
261 hdc = BeginPaint(hwnd, &ps);
262
263 if (pPreviewData->hdcPreview)
264 {
265 BitBlt(hdc,0,0, pPreviewData->rcDesktop.right, pPreviewData->rcDesktop.bottom, pPreviewData->hdcPreview, 0,0, SRCCOPY);
266 EndPaint(hwnd, &ps);
267 return;
268 }
269
270 /* Desktop */
271 FillRect(hdc, &pPreviewData->rcDesktop, pPreviewData->hbrDesktop);
272
273 /* Inactive Window */
274 MyDrawEdge(hdc, &pPreviewData->rcInactiveFrame, EDGE_RAISED, BF_RECT | BF_MIDDLE | MY_BF_INACTIVEBORDER, scheme);
275 SetTextColor(hdc, scheme->crColor[COLOR_INACTIVECAPTIONTEXT]);
276 MyDrawCaptionTemp(NULL, hdc, &pPreviewData->rcInactiveCaption, pPreviewData->hCaptionFont,
277 NULL, pPreviewData->lpInAct, DC_GRADIENT | DC_ICON | DC_TEXT, scheme);
278 MyDrawCaptionButtons(hdc, &pPreviewData->rcInactiveCaption, TRUE, pPreviewData->cyCaption - 2, scheme);
279
280 /* Active Window */
281 MyDrawEdge(hdc, &pPreviewData->rcActiveFrame, EDGE_RAISED, BF_RECT | BF_MIDDLE | MY_BF_ACTIVEBORDER, scheme);
282 SetTextColor(hdc, scheme->crColor[COLOR_CAPTIONTEXT]);
283 MyDrawCaptionTemp(NULL, hdc, &pPreviewData->rcActiveCaption, pPreviewData->hCaptionFont,
284 NULL, pPreviewData->lpAct, DC_ACTIVE | DC_GRADIENT | DC_ICON | DC_TEXT, scheme);
285 MyDrawCaptionButtons(hdc, &pPreviewData->rcActiveCaption, TRUE, pPreviewData->cyCaption - 2, scheme);
286
287 /* Draw the menu bar */
288 MyDrawMenuBarTemp(hwnd, hdc, &pPreviewData->rcActiveMenuBar,
289 pPreviewData->hMenu,
290 pPreviewData->hMenuFont, scheme);
291
292 /* Draw the client area */
293 CopyRect(&rc, &pPreviewData->rcActiveClient);
294 MyDrawEdge(hdc, &rc, EDGE_SUNKEN, BF_RECT | BF_ADJUST, scheme);
295 FillRect(hdc, &rc, pPreviewData->hbrWindow);
296
297 /* Draw the client text */
298 CopyRect(&rc, &pPreviewData->rcActiveClient);
299 rc.left += 4;
300 rc.top += 2;
301 SetTextColor(hdc, scheme->crColor[COLOR_WINDOWTEXT]);
302 hOldFont = SelectObject(hdc, pPreviewData->hClientFont);
303 DrawText(hdc, pPreviewData->lpWinTxt, -1, &rc, DT_LEFT);
304 SelectObject(hdc, hOldFont);
305
306 /* Draw the scroll bar */
307 MyDrawScrollbar(hdc, &pPreviewData->rcActiveScroll, pPreviewData->hbrScrollbar, scheme);
308
309 /* Dialog Window */
310 MyDrawEdge(hdc, &pPreviewData->rcDialogFrame, EDGE_RAISED, BF_RECT | BF_MIDDLE, scheme);
311 SetTextColor(hdc, scheme->crColor[COLOR_WINDOW]);
312 MyDrawCaptionTemp(NULL, hdc, &pPreviewData->rcDialogCaption, pPreviewData->hCaptionFont,
313 NULL, pPreviewData->lpMessBox, DC_ACTIVE | DC_GRADIENT | DC_ICON | DC_TEXT, scheme);
314 MyDrawCaptionButtons(hdc, &pPreviewData->rcDialogCaption, FALSE, pPreviewData->cyCaption - 2, scheme);
315
316 /* Draw the dialog text */
317 CopyRect(&rc, &pPreviewData->rcDialogClient);
318 rc.left += 4;
319 rc.top += 2;
320 SetTextColor(hdc, scheme->crColor[COLOR_WINDOWTEXT]);
321 hOldFont = SelectObject(hdc, pPreviewData->hMessageFont);
322 DrawText(hdc, pPreviewData->lpMessText, -1, &rc, DT_LEFT);
323 SelectObject(hdc, hOldFont);
324
325 /* Draw Button */
326 MyDrawFrameControl(hdc, &pPreviewData->rcDialogButton, DFC_BUTTON, DFCS_BUTTONPUSH, scheme);
327 CopyRect(&rc, &pPreviewData->rcDialogButton);
328 SetTextColor(hdc, scheme->crColor[COLOR_BTNTEXT]);
329 hOldFont = SelectObject(hdc, pPreviewData->hMessageFont);
330 DrawText(hdc, pPreviewData->lpButText, -1, &rc, DT_VCENTER | DT_CENTER | DT_SINGLELINE);
331 SelectObject(hdc, hOldFont);
332
333 EndPaint(hwnd, &ps);
334 }
335
336
337 static VOID
338 OnLButtonDown(HWND hwnd, int xPos, int yPos, PPREVIEW_DATA pPreviewData)
339 {
340 UINT type = IDX_DESKTOP;
341 POINT pt;
342
343 pt.x = xPos;
344 pt.y = yPos;
345
346 if (PtInRect(&pPreviewData->rcInactiveFrame, pt))
347 type = IDX_INACTIVE_BORDER;
348
349 if (PtInRect(&pPreviewData->rcInactiveCaption, pt))
350 type = IDX_INACTIVE_CAPTION;
351
352 if (PtInRect(&pPreviewData->rcInactiveCaptionButtons, pt))
353 type = IDX_CAPTION_BUTTON;
354
355 if (PtInRect(&pPreviewData->rcActiveFrame, pt))
356 type = IDX_ACTIVE_BORDER;
357
358 if (PtInRect(&pPreviewData->rcActiveCaption, pt))
359 type = IDX_ACTIVE_CAPTION;
360
361 if (PtInRect(&pPreviewData->rcActiveCaptionButtons, pt))
362 type = IDX_CAPTION_BUTTON;
363
364 // if (PtInRect(&pPreviewData->rcSelectedMenuItem, pt))
365 // type = IDX_SELECTION;
366
367 if (PtInRect(&pPreviewData->rcActiveMenuBar, pt))
368 type = IDX_MENU;
369
370 if (PtInRect(&pPreviewData->rcActiveClient, pt))
371 type = IDX_WINDOW;
372
373 if (PtInRect(&pPreviewData->rcActiveScroll, pt))
374 type = IDX_SCROLLBAR;
375
376 if (PtInRect(&pPreviewData->rcDialogFrame, pt))
377 type = IDX_DIALOG;
378
379 if (PtInRect(&pPreviewData->rcDialogCaption, pt))
380 type = IDX_ACTIVE_CAPTION;
381
382 if (PtInRect(&pPreviewData->rcDialogCaptionButtons, pt))
383 type = IDX_CAPTION_BUTTON;
384
385 if (PtInRect(&pPreviewData->rcDialogButton, pt))
386 type = IDX_3D_OBJECTS;
387
388 SendMessage(GetParent(hwnd),
389 WM_COMMAND,
390 MAKEWPARAM(GetWindowLongPtrW(hwnd, GWLP_ID), 0),
391 (LPARAM)type);
392 }
393
394
395 static VOID
396 OnDestroy(PPREVIEW_DATA pPreviewData)
397 {
398 DeleteObject(pPreviewData->hbrScrollbar);
399 DeleteObject(pPreviewData->hbrDesktop);
400 DeleteObject(pPreviewData->hbrWindow);
401
402 DeleteObject(pPreviewData->hCaptionFont);
403 DeleteObject(pPreviewData->hMenuFont);
404 DeleteObject(pPreviewData->hMessageFont);
405
406 DestroyMenu(pPreviewData->hMenu);
407
408 LocalFree((HLOCAL)pPreviewData->lpInAct);
409 LocalFree((HLOCAL)pPreviewData->lpAct);
410 LocalFree((HLOCAL)pPreviewData->lpWinTxt);
411 LocalFree((HLOCAL)pPreviewData->lpMessBox);
412 LocalFree((HLOCAL)pPreviewData->lpMessText);
413 LocalFree((HLOCAL)pPreviewData->lpButText);
414 }
415
416
417 static LRESULT CALLBACK
418 PreviewWndProc(HWND hwnd,
419 UINT uMsg,
420 WPARAM wParam,
421 LPARAM lParam)
422 {
423 PPREVIEW_DATA pPreviewData;
424
425 pPreviewData = (PPREVIEW_DATA)GetWindowLongPtr(hwnd, GWLP_USERDATA);
426
427 switch (uMsg)
428 {
429 case WM_CREATE:
430 pPreviewData = (PPREVIEW_DATA)HeapAlloc(GetProcessHeap(),
431 HEAP_ZERO_MEMORY,
432 sizeof(PREVIEW_DATA));
433 if (!pPreviewData)
434 return -1;
435
436 SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)pPreviewData);
437 OnCreate(hwnd, pPreviewData);
438 break;
439
440 case WM_SIZE:
441 OnSize(LOWORD(lParam), HIWORD(lParam), pPreviewData);
442 break;
443
444 case WM_PAINT:
445 OnPaint(hwnd, pPreviewData);
446 break;
447
448 case WM_LBUTTONDOWN:
449 OnLButtonDown(hwnd, LOWORD(lParam), HIWORD(lParam), pPreviewData);
450 break;
451
452 case WM_DESTROY:
453 OnDestroy(pPreviewData);
454 HeapFree(GetProcessHeap(), 0, pPreviewData);
455 break;
456
457 case PVM_UPDATETHEME:
458 UpdatePreviewTheme(hwnd, pPreviewData, (COLOR_SCHEME *)lParam);
459 CalculateItemSize(pPreviewData);
460 InvalidateRect(hwnd, NULL, FALSE);
461 break;
462
463 case PVM_SETSIZE:
464 SchemeSetMetric(&pPreviewData->Scheme, wParam, lParam);
465 pPreviewData->cySizeFrame = pPreviewData->Scheme.ncMetrics.iBorderWidth; /* SM_CYSIZEFRAME */
466 pPreviewData->cyCaption = pPreviewData->Scheme.ncMetrics.iCaptionHeight+1; /* SM_CYCAPTION */
467 pPreviewData->cyMenu = pPreviewData->Scheme.ncMetrics.iMenuHeight -1; /* SM_CYMENU */
468 pPreviewData->cxScrollbar = pPreviewData->Scheme.ncMetrics.iScrollWidth; /* SM_CXVSCROLL */
469 pPreviewData->cyBorder = pPreviewData->Scheme.ncMetrics.iBorderWidth; /* SM_CYBORDER */
470 CalculateItemSize(pPreviewData);
471 InvalidateRect(hwnd, NULL, FALSE);
472 break;
473
474 case PVM_SETFONT:
475 {
476 PLOGFONTW plfFont;
477 HFONT* phFont;
478
479 switch(wParam)
480 {
481 case FONT_CAPTION: phFont = &pPreviewData->hCaptionFont; break;
482 case FONT_MENU: phFont = &pPreviewData->hMenuFont; break;
483 case FONT_MESSAGE: phFont = &pPreviewData->hMessageFont; break;
484 default: return TRUE;
485 }
486
487 plfFont = SchemeGetFont(&pPreviewData->Scheme, wParam);
488 memcpy(plfFont, (PVOID)lParam, sizeof(LOGFONTW));
489
490 DeleteObject(*phFont);
491 *phFont = CreateFontIndirect(plfFont);
492
493 InvalidateRect(hwnd, NULL, FALSE);
494 break;
495 }
496
497 case PVM_SETCOLOR:
498 pPreviewData->Scheme.crColor[wParam] = lParam;
499 switch(wParam)
500 {
501 case COLOR_SCROLLBAR:
502 DeleteObject(pPreviewData->hbrScrollbar);
503 pPreviewData->hbrScrollbar = CreateSolidBrush(pPreviewData->Scheme.crColor[wParam]);
504 break;
505 case COLOR_DESKTOP:
506 DeleteObject(pPreviewData->hbrDesktop);
507 pPreviewData->hbrDesktop = CreateSolidBrush(pPreviewData->Scheme.crColor[wParam]);
508 break;
509 case COLOR_WINDOW:
510 DeleteObject(pPreviewData->hbrWindow);
511 pPreviewData->hbrWindow = CreateSolidBrush(pPreviewData->Scheme.crColor[wParam]);
512 break;
513 }
514
515 CalculateItemSize(pPreviewData);
516 InvalidateRect(hwnd, NULL, FALSE);
517 break;
518
519 case PVM_GETSIZE:
520 return SchemeGetMetric(&pPreviewData->Scheme, wParam);
521 case PVM_GETFONT:
522 return (LRESULT)SchemeGetFont(&pPreviewData->Scheme, wParam);
523 case PVM_GETCOLOR:
524 return pPreviewData->Scheme.crColor[wParam];
525
526 case PVM_SET_HDC_PREVIEW:
527 pPreviewData->hdcPreview = (HDC)lParam;
528 InvalidateRect(hwnd, NULL, FALSE);
529 break;
530
531 default:
532 return DefWindowProc(hwnd, uMsg, wParam, lParam);
533 }
534 return FALSE;
535 }
536
537
538 BOOL
539 RegisterPreviewControl(IN HINSTANCE hInstance)
540 {
541 WNDCLASSEX wc = {0};
542
543 wc.cbSize = sizeof(wc);
544 wc.lpfnWndProc = PreviewWndProc;
545 wc.hInstance = hInstance;
546 wc.hCursor = LoadCursor(NULL, IDC_ARROW);
547 wc.hbrBackground = (HBRUSH)NULL;
548 wc.lpszClassName = szPreviewWndClass;
549
550 return RegisterClassEx(&wc) != (ATOM)0;
551 }
552
553
554 VOID
555 UnregisterPreviewControl(IN HINSTANCE hInstance)
556 {
557 UnregisterClass(szPreviewWndClass, hInstance);
558 }