[DESK.CPL]
[reactos.git] / reactos / 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 #include "theme.h"
11 #include "preview.h"
12 #include "draw.h"
13
14 static const TCHAR szPreviewWndClass[] = TEXT("PreviewWndClass");
15
16 typedef struct _PREVIEW_DATA
17 {
18 HWND hwndParent;
19
20 THEME Theme;
21
22 HBRUSH hbrScrollbar;
23 HBRUSH hbrDesktop;
24 HBRUSH hbrWindow;
25
26 INT cxEdge;
27 INT cyEdge;
28
29 INT cySizeFrame;
30
31 INT cyCaption;
32 INT cyBorder;
33 INT cyMenu;
34 INT cxScrollbar;
35
36 RECT rcDesktop;
37 RECT rcInactiveFrame;
38 RECT rcInactiveCaption;
39 RECT rcInactiveCaptionButtons;
40
41 RECT rcActiveFrame;
42 RECT rcActiveCaption;
43 RECT rcActiveCaptionButtons;
44 RECT rcActiveMenuBar;
45 RECT rcSelectedMenuItem;
46 RECT rcActiveClient;
47 RECT rcActiveScroll;
48
49 RECT rcDialogFrame;
50 RECT rcDialogCaption;
51 RECT rcDialogCaptionButtons;
52 RECT rcDialogClient;
53
54 RECT rcDialogButton;
55
56 LPTSTR lpInAct;
57 LPTSTR lpAct;
58 LPTSTR lpWinTxt;
59 LPTSTR lpMessBox;
60 LPTSTR lpMessText;
61 LPTSTR lpButText;
62
63 HFONT hCaptionFont;
64 HFONT hMenuFont;
65 HFONT hMessageFont;
66 HFONT hClientFont;
67
68 HMENU hMenu;
69
70 } PREVIEW_DATA, *PPREVIEW_DATA;
71
72
73 static VOID UpdatePreviewTheme(HWND hwnd, PPREVIEW_DATA pPreviewData, THEME *theme)
74 {
75 if (pPreviewData->hbrScrollbar != NULL)
76 DeleteObject(pPreviewData->hbrScrollbar);
77 pPreviewData->hbrScrollbar = CreateSolidBrush(theme->crColor[COLOR_SCROLLBAR]);
78 if (pPreviewData->hbrDesktop != NULL)
79 DeleteObject(pPreviewData->hbrDesktop);
80 pPreviewData->hbrDesktop = CreateSolidBrush(theme->crColor[COLOR_DESKTOP]);
81 if (pPreviewData->hbrWindow != NULL)
82 DeleteObject(pPreviewData->hbrWindow);
83 pPreviewData->hbrWindow = CreateSolidBrush(theme->crColor[COLOR_WINDOW]);
84
85 pPreviewData->cxEdge = theme->Size[SIZE_EDGE_X] - 2; /* SM_CXEDGE */
86 pPreviewData->cyEdge = theme->Size[SIZE_EDGE_Y] - 2; /* SM_CYEDGE */
87
88 pPreviewData->cySizeFrame = theme->Size[SIZE_FRAME_Y] - 1; /* SM_CYSIZEFRAME */
89
90 pPreviewData->cyCaption = theme->Size[SIZE_CAPTION_Y]; /* SM_CYCAPTION */
91 pPreviewData->cyMenu = theme->Size[SIZE_MENU_Y]; /* SM_CYMENU */
92 pPreviewData->cxScrollbar = theme->Size[SIZE_SCROLL_X]; /* SM_CXVSCROLL */
93 pPreviewData->cyBorder = theme->Size[SIZE_BORDER_Y]; /* SM_CYBORDER */
94
95 if (pPreviewData->hCaptionFont != NULL)
96 DeleteObject(pPreviewData->hCaptionFont);
97 pPreviewData->hCaptionFont = CreateFontIndirect(&theme->lfFont[FONT_CAPTION]);
98
99 if (pPreviewData->hMenuFont != NULL)
100 DeleteObject(pPreviewData->hMenuFont);
101 pPreviewData->hMenuFont = CreateFontIndirect(&theme->lfFont[FONT_MENU]);
102
103 if (pPreviewData->hMessageFont != NULL)
104 DeleteObject(pPreviewData->hMessageFont);
105 pPreviewData->hMessageFont = CreateFontIndirect(&theme->lfFont[FONT_DIALOG]);
106
107 pPreviewData->Theme = *theme;
108 InvalidateRect(hwnd, NULL, FALSE);
109 }
110
111 static VOID
112 OnCreate(HWND hwnd, PPREVIEW_DATA pPreviewData)
113 {
114 THEME *theme;
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 theme = &pPreviewData->Theme;
136 LoadCurrentTheme(theme);
137
138 UpdatePreviewTheme(hwnd, pPreviewData, theme);
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 THEME *theme;
258
259 theme = &pPreviewData->Theme;
260
261 hdc = BeginPaint(hwnd, &ps);
262
263 /* Desktop */
264 FillRect(hdc, &pPreviewData->rcDesktop, pPreviewData->hbrDesktop);
265
266 /* Inactive Window */
267 MyDrawEdge(hdc, &pPreviewData->rcInactiveFrame, EDGE_RAISED, BF_RECT | BF_MIDDLE, theme);
268 SetTextColor(hdc, theme->crColor[COLOR_INACTIVECAPTIONTEXT]);
269 MyDrawCaptionTemp(NULL, hdc, &pPreviewData->rcInactiveCaption, pPreviewData->hCaptionFont,
270 NULL, pPreviewData->lpInAct, DC_GRADIENT | DC_ICON | DC_TEXT, theme);
271 MyDrawCaptionButtons(hdc, &pPreviewData->rcInactiveCaption, TRUE, pPreviewData->cyCaption - 2, theme);
272
273 /* Active Window */
274 MyDrawEdge(hdc, &pPreviewData->rcActiveFrame, EDGE_RAISED, BF_RECT | BF_MIDDLE, theme);
275 SetTextColor(hdc, theme->crColor[COLOR_CAPTIONTEXT]);
276 MyDrawCaptionTemp(NULL, hdc, &pPreviewData->rcActiveCaption, pPreviewData->hCaptionFont,
277 NULL, pPreviewData->lpAct, DC_ACTIVE | DC_GRADIENT | DC_ICON | DC_TEXT, theme);
278 MyDrawCaptionButtons(hdc, &pPreviewData->rcActiveCaption, TRUE, pPreviewData->cyCaption - 2, theme);
279
280 /* Draw the menu bar */
281 MyDrawMenuBarTemp(hwnd, hdc, &pPreviewData->rcActiveMenuBar,
282 pPreviewData->hMenu,
283 pPreviewData->hMenuFont, theme);
284
285 /* Draw the client area */
286 CopyRect(&rc, &pPreviewData->rcActiveClient);
287 MyDrawEdge(hdc, &rc, EDGE_SUNKEN, BF_RECT | BF_ADJUST, theme);
288 FillRect(hdc, &rc, pPreviewData->hbrWindow);
289
290 /* Draw the client text */
291 CopyRect(&rc, &pPreviewData->rcActiveClient);
292 rc.left += 4;
293 rc.top += 2;
294 SetTextColor(hdc, theme->crColor[COLOR_WINDOWTEXT]);
295 hOldFont = SelectObject(hdc, pPreviewData->hClientFont);
296 DrawText(hdc, pPreviewData->lpWinTxt, -1, &rc, DT_LEFT);
297 SelectObject(hdc, hOldFont);
298
299 /* Draw the scroll bar */
300 MyDrawScrollbar(hdc, &pPreviewData->rcActiveScroll, pPreviewData->hbrScrollbar, theme);
301
302 /* Dialog Window */
303 MyDrawEdge(hdc, &pPreviewData->rcDialogFrame, EDGE_RAISED, BF_RECT | BF_MIDDLE, theme);
304 SetTextColor(hdc, theme->crColor[COLOR_WINDOW]);
305 MyDrawCaptionTemp(NULL, hdc, &pPreviewData->rcDialogCaption, pPreviewData->hCaptionFont,
306 NULL, pPreviewData->lpMessBox, DC_ACTIVE | DC_GRADIENT | DC_ICON | DC_TEXT, theme);
307 MyDrawCaptionButtons(hdc, &pPreviewData->rcDialogCaption, FALSE, pPreviewData->cyCaption - 2, theme);
308
309 /* Draw the dialog text */
310 CopyRect(&rc, &pPreviewData->rcDialogClient);
311 rc.left += 4;
312 rc.top += 2;
313 SetTextColor(hdc, theme->crColor[COLOR_BTNTEXT]);
314 hOldFont = SelectObject(hdc, pPreviewData->hMessageFont);
315 DrawText(hdc, pPreviewData->lpMessText, -1, &rc, DT_LEFT);
316 SelectObject(hdc, hOldFont);
317
318 /* Draw Button */
319 MyDrawFrameControl(hdc, &pPreviewData->rcDialogButton, DFC_BUTTON, DFCS_BUTTONPUSH, theme);
320 CopyRect(&rc, &pPreviewData->rcDialogButton);
321 SetTextColor(hdc, theme->crColor[COLOR_BTNTEXT]);
322 hOldFont = SelectObject(hdc, pPreviewData->hMessageFont);
323 DrawText(hdc, pPreviewData->lpButText, -1, &rc, DT_VCENTER | DT_CENTER | DT_SINGLELINE);
324 SelectObject(hdc, hOldFont);
325
326 EndPaint(hwnd, &ps);
327 }
328
329
330 static VOID
331 OnLButtonDown(HWND hwnd, int xPos, int yPos, PPREVIEW_DATA pPreviewData)
332 {
333 UINT type = IDX_DESKTOP;
334 POINT pt;
335
336 pt.x = xPos;
337 pt.y = yPos;
338
339 if (PtInRect(&pPreviewData->rcInactiveFrame, pt))
340 type = IDX_INACTIVE_BORDER;
341
342 if (PtInRect(&pPreviewData->rcInactiveCaption, pt))
343 type = IDX_INACTIVE_CAPTION;
344
345 if (PtInRect(&pPreviewData->rcInactiveCaptionButtons, pt))
346 type = IDX_CAPTION_BUTTON;
347
348 if (PtInRect(&pPreviewData->rcActiveFrame, pt))
349 type = IDX_ACTIVE_BORDER;
350
351 if (PtInRect(&pPreviewData->rcActiveCaption, pt))
352 type = IDX_ACTIVE_CAPTION;
353
354 if (PtInRect(&pPreviewData->rcActiveCaptionButtons, pt))
355 type = IDX_CAPTION_BUTTON;
356
357 // if (PtInRect(&pPreviewData->rcSelectedMenuItem, pt))
358 // type = IDX_SELECTION;
359
360 if (PtInRect(&pPreviewData->rcActiveMenuBar, pt))
361 type = IDX_MENU;
362
363 if (PtInRect(&pPreviewData->rcActiveClient, pt))
364 type = IDX_WINDOW;
365
366 if (PtInRect(&pPreviewData->rcActiveScroll, pt))
367 type = IDX_SCROLLBAR;
368
369 if (PtInRect(&pPreviewData->rcDialogFrame, pt))
370 type = IDX_DIALOG;
371
372 if (PtInRect(&pPreviewData->rcDialogCaption, pt))
373 type = IDX_ACTIVE_CAPTION;
374
375 if (PtInRect(&pPreviewData->rcDialogCaptionButtons, pt))
376 type = IDX_CAPTION_BUTTON;
377
378 if (PtInRect(&pPreviewData->rcDialogButton, pt))
379 type = IDX_3D_OBJECTS;
380
381 SendMessage(GetParent(hwnd),
382 WM_COMMAND,
383 MAKEWPARAM(GetWindowLongPtrW(hwnd, GWLP_ID), 0),
384 (LPARAM)type);
385 }
386
387
388 static VOID
389 OnDestroy(PPREVIEW_DATA pPreviewData)
390 {
391 DeleteObject(pPreviewData->hbrScrollbar);
392 DeleteObject(pPreviewData->hbrDesktop);
393 DeleteObject(pPreviewData->hbrWindow);
394
395 DeleteObject(pPreviewData->hCaptionFont);
396 DeleteObject(pPreviewData->hMenuFont);
397 DeleteObject(pPreviewData->hMessageFont);
398
399 DestroyMenu(pPreviewData->hMenu);
400
401 LocalFree((HLOCAL)pPreviewData->lpInAct);
402 LocalFree((HLOCAL)pPreviewData->lpAct);
403 LocalFree((HLOCAL)pPreviewData->lpWinTxt);
404 LocalFree((HLOCAL)pPreviewData->lpMessBox);
405 LocalFree((HLOCAL)pPreviewData->lpMessText);
406 LocalFree((HLOCAL)pPreviewData->lpButText);
407 }
408
409
410 static LRESULT CALLBACK
411 PreviewWndProc(HWND hwnd,
412 UINT uMsg,
413 WPARAM wParam,
414 LPARAM lParam)
415 {
416 PPREVIEW_DATA pPreviewData;
417
418 pPreviewData = (PPREVIEW_DATA)GetWindowLongPtr(hwnd, GWLP_USERDATA);
419
420 switch (uMsg)
421 {
422 case WM_CREATE:
423 pPreviewData = (PPREVIEW_DATA)HeapAlloc(GetProcessHeap(),
424 HEAP_ZERO_MEMORY,
425 sizeof(PREVIEW_DATA));
426 if (!pPreviewData)
427 return -1;
428
429 SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)pPreviewData);
430 OnCreate(hwnd, pPreviewData);
431 break;
432
433 case WM_SIZE:
434 OnSize(LOWORD(lParam), HIWORD(lParam), pPreviewData);
435 break;
436
437 case WM_PAINT:
438 OnPaint(hwnd, pPreviewData);
439 break;
440
441 case WM_LBUTTONDOWN:
442 OnLButtonDown(hwnd, LOWORD(lParam), HIWORD(lParam), pPreviewData);
443 break;
444
445 case WM_DESTROY:
446 OnDestroy(pPreviewData);
447 HeapFree(GetProcessHeap(), 0, pPreviewData);
448 break;
449
450 case PVM_GETCYCAPTION:
451 return pPreviewData->cyCaption;
452
453 case PVM_SETCYCAPTION:
454 if ((INT)lParam > 0)
455 {
456 pPreviewData->cyCaption = (INT)lParam;
457 CalculateItemSize(pPreviewData);
458 InvalidateRect(hwnd, NULL, FALSE);
459 }
460 break;
461
462 case PVM_GETCYMENU:
463 return pPreviewData->cyMenu;
464
465 case PVM_SETCYMENU:
466 if ((INT)lParam > 0)
467 {
468 pPreviewData->cyMenu = (INT)lParam;
469 CalculateItemSize(pPreviewData);
470 InvalidateRect(hwnd, NULL, FALSE);
471 }
472 break;
473
474 case PVM_GETCXSCROLLBAR:
475 return pPreviewData->cxScrollbar;
476
477 case PVM_SETCXSCROLLBAR:
478 if ((INT)lParam > 0)
479 {
480 pPreviewData->cxScrollbar = (INT)lParam;
481 CalculateItemSize(pPreviewData);
482 InvalidateRect(hwnd, NULL, FALSE);
483 }
484 break;
485
486 case PVM_GETCYSIZEFRAME:
487 return pPreviewData->cySizeFrame;
488
489 case PVM_SETCYSIZEFRAME:
490 if ((INT)lParam > 0)
491 {
492 pPreviewData->cySizeFrame = (INT)lParam;
493 CalculateItemSize(pPreviewData);
494 InvalidateRect(hwnd, NULL, FALSE);
495 }
496 break;
497
498 case PVM_UPDATETHEME:
499 UpdatePreviewTheme(hwnd, pPreviewData, (THEME *)lParam);
500 break;
501
502 default:
503 return DefWindowProc(hwnd, uMsg, wParam, lParam);
504 }
505 return FALSE;
506 }
507
508
509 BOOL
510 RegisterPreviewControl(IN HINSTANCE hInstance)
511 {
512 WNDCLASSEX wc = {0};
513
514 wc.cbSize = sizeof(WNDCLASSEX);
515 wc.lpfnWndProc = PreviewWndProc;
516 wc.hInstance = hInstance;
517 wc.hCursor = LoadCursor(NULL, IDC_ARROW);
518 wc.hbrBackground = (HBRUSH)NULL;
519 wc.lpszClassName = szPreviewWndClass;
520
521 return RegisterClassEx(&wc) != (ATOM)0;
522 }
523
524
525 VOID
526 UnregisterPreviewControl(IN HINSTANCE hInstance)
527 {
528 UnregisterClass(szPreviewWndClass, hInstance);
529 }