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