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