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