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