- Fix KiDispatchException to unmask KI_EXCEPTION_INTERNAL when setting the exception...
[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) - 2;
166 pPreviewData->cyEdge = GetSystemMetrics(SM_CXEDGE) - 2;
167
168 pPreviewData->cySizeFrame = GetSystemMetrics(SM_CYSIZEFRAME) - 1;
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 + pPreviewData->cySizeFrame + 1;
220 pPreviewData->rcInactiveCaption.top = pPreviewData->rcInactiveFrame.top + pPreviewData->cyEdge + pPreviewData->cySizeFrame + 1;
221 pPreviewData->rcInactiveCaption.right = pPreviewData->rcInactiveFrame.right - pPreviewData->cxEdge - pPreviewData->cySizeFrame - 1;
222 pPreviewData->rcInactiveCaption.bottom = pPreviewData->rcInactiveCaption.top + pPreviewData->cyCaption;
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 + pPreviewData->cySizeFrame;
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 + pPreviewData->cxEdge + pPreviewData->cySizeFrame + 1;
238 pPreviewData->rcActiveCaption.top = pPreviewData->rcActiveFrame.top + pPreviewData->cxEdge + pPreviewData->cySizeFrame + 1;
239 pPreviewData->rcActiveCaption.right = pPreviewData->rcActiveFrame.right - pPreviewData->cxEdge - pPreviewData->cySizeFrame - 1;
240 pPreviewData->rcActiveCaption.bottom = pPreviewData->rcActiveCaption.top + pPreviewData->cyCaption;
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 + pPreviewData->cxEdge + pPreviewData->cySizeFrame + 1;
250 pPreviewData->rcActiveMenuBar.top = pPreviewData->rcActiveCaption.bottom + 1;
251 pPreviewData->rcActiveMenuBar.right = pPreviewData->rcActiveFrame.right - pPreviewData->cxEdge - pPreviewData->cySizeFrame - 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 + pPreviewData->cxEdge + pPreviewData->cySizeFrame + 1;
256 pPreviewData->rcActiveClient.top = pPreviewData->rcActiveMenuBar.bottom;
257 pPreviewData->rcActiveClient.right = pPreviewData->rcActiveFrame.right - pPreviewData->cxEdge - pPreviewData->cySizeFrame - 1;
258 pPreviewData->rcActiveClient.bottom = pPreviewData->rcActiveFrame.bottom - pPreviewData->cyEdge - pPreviewData->cySizeFrame - 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 #ifdef _MSC_VER
316
317 #if _UNICODE
318 typedef BOOL (WINAPI * DCT_PROC)(HWND hwnd, HDC hdc, const RECT *rect, HFONT hFont, HICON hIcon, LPCWSTR str, UINT uFlags);
319 #define DCT_ORD 178
320 #else
321 typedef BOOL (WINAPI * DCT_PROC)(HWND hwnd, HDC hdc, const RECT *rect, HFONT hFont, HICON hIcon, LPCSTR str, UINT uFlags);
322 #define DCT_ORD 177
323 #endif
324
325 typedef DWORD (WINAPI * DMBT_PROC)(HWND hwnd, HDC hDC, LPRECT lprect, HMENU hMenu, HFONT hFont);
326 #define DMBT_ORD 186
327
328 #endif
329
330 static VOID
331 OnPaint(HWND hwnd, PPREVIEW_DATA pPreviewData)
332 {
333 PAINTSTRUCT ps;
334 HFONT hOldFont;
335 HDC hdc;
336 RECT rc;
337
338 #ifdef _MSC_VER
339 DCT_PROC DrawCaptionTemp;
340 DMBT_PROC DrawMenuBarTemp;
341 HMODULE hUser32;
342
343 hUser32 = LoadLibrary(_T("user32.dll"));
344 if(hUser32 == NULL)
345 return FALSE;
346
347 DrawCaptionTemp = (DCT_PROC)GetProcAddress(hUser32, (LPCSTR)DCT_ORD);
348 DrawMenuBarTemp = (DMBT_PROC)GetProcAddress(hUser32, (LPCSTR)DMBT_ORD);
349 #endif
350
351 hdc = BeginPaint(hwnd, &ps);
352
353 /* Desktop */
354 FillRect(hdc, &pPreviewData->rcDesktop, pPreviewData->hbrDesktop);
355
356 /* Inactive Window */
357 DrawEdge(hdc, &pPreviewData->rcInactiveFrame, EDGE_RAISED, BF_RECT | BF_MIDDLE);
358 SetTextColor(hdc, pPreviewData->clrInactiveCaptionText);
359 DrawCaptionTemp(NULL, hdc, &pPreviewData->rcInactiveCaption, pPreviewData->hCaptionFont,
360 NULL, pPreviewData->lpInAct, DC_GRADIENT | DC_ICON | DC_TEXT);
361 DrawCaptionButtons(hdc, &pPreviewData->rcInactiveCaption, TRUE, pPreviewData->cyCaption - 2);
362
363 /* Active Window */
364 DrawEdge(hdc, &pPreviewData->rcActiveFrame, EDGE_RAISED, BF_RECT | BF_MIDDLE);
365 SetTextColor(hdc, pPreviewData->clrActiveCaptionText);
366 DrawCaptionTemp(NULL, hdc, &pPreviewData->rcActiveCaption, pPreviewData->hCaptionFont,
367 NULL, pPreviewData->lpAct, DC_ACTIVE | DC_GRADIENT | DC_ICON | DC_TEXT);
368 DrawCaptionButtons(hdc, &pPreviewData->rcActiveCaption, TRUE, pPreviewData->cyCaption - 2);
369
370 /* Draw the menu bar */
371 DrawMenuBarTemp(hwnd, hdc, &pPreviewData->rcActiveMenuBar,
372 pPreviewData->hMenu,
373 pPreviewData->hMenuFont);
374
375 /* Draw the client area */
376 CopyRect(&rc, &pPreviewData->rcActiveClient);
377 DrawEdge(hdc, &rc, EDGE_SUNKEN, BF_RECT | BF_ADJUST);
378 FillRect(hdc, &rc, pPreviewData->hbrWindow);
379
380 /* Draw the client text */
381 CopyRect(&rc, &pPreviewData->rcActiveClient);
382 rc.left += 4;
383 rc.top += 2;
384 SetTextColor(hdc, pPreviewData->clrWindowText);
385 hOldFont = SelectObject(hdc, pPreviewData->hMessageFont);
386 DrawText(hdc, pPreviewData->lpWinTxt, lstrlen(pPreviewData->lpWinTxt), &rc, DT_LEFT);
387 SelectObject(hdc, hOldFont);
388
389 /* Draw the scroll bar */
390 DrawScrollbar(hdc, &pPreviewData->rcActiveScroll, pPreviewData->hbrScrollbar);
391
392 /* Dialog Window */
393 DrawEdge(hdc, &pPreviewData->rcDialogFrame, EDGE_RAISED, BF_RECT | BF_MIDDLE);
394 SetTextColor(hdc, pPreviewData->clrActiveCaptionText);
395 DrawCaptionTemp(NULL, hdc, &pPreviewData->rcDialogCaption, pPreviewData->hCaptionFont,
396 NULL, pPreviewData->lpMessBox, DC_ACTIVE | DC_GRADIENT | DC_ICON | DC_TEXT);
397 DrawCaptionButtons(hdc, &pPreviewData->rcDialogCaption, FALSE, pPreviewData->cyCaption - 2);
398
399 /* Draw the dialog text */
400 CopyRect(&rc, &pPreviewData->rcDialogClient);
401 rc.left += 4;
402 rc.top += 2;
403 SetTextColor(hdc, RGB(0,0,0));
404 hOldFont = SelectObject(hdc, pPreviewData->hMessageFont);
405 DrawText(hdc, pPreviewData->lpMessText, lstrlen(pPreviewData->lpMessText), &rc, DT_LEFT);
406 SelectObject(hdc, hOldFont);
407
408 /* Draw Button */
409 DrawFrameControl(hdc, &pPreviewData->rcDialogButton, DFC_BUTTON, DFCS_BUTTONPUSH);
410 CopyRect(&rc, &pPreviewData->rcDialogButton);
411 SetTextColor(hdc, pPreviewData->clrButtonText);
412 hOldFont = SelectObject(hdc, pPreviewData->hMessageFont);
413 DrawText(hdc, pPreviewData->lpButText, lstrlen(pPreviewData->lpButText), &rc, DT_VCENTER | DT_CENTER | DT_SINGLELINE);
414 SelectObject(hdc, hOldFont);
415
416 EndPaint(hwnd, &ps);
417 }
418
419
420 static VOID
421 OnLButtonDown(HWND hwnd, int xPos, int yPos, PPREVIEW_DATA pPreviewData)
422 {
423 UINT type = IDX_DESKTOP;
424 POINT pt;
425
426 pt.x = xPos;
427 pt.y = yPos;
428
429 if (PtInRect(&pPreviewData->rcInactiveFrame, pt))
430 type = IDX_INACTIVE_BORDER;
431
432 if (PtInRect(&pPreviewData->rcInactiveCaption, pt))
433 type = IDX_INACTIVE_CAPTION;
434
435 if (PtInRect(&pPreviewData->rcInactiveCaptionButtons, pt))
436 type = IDX_CAPTION_BUTTON;
437
438 if (PtInRect(&pPreviewData->rcActiveFrame, pt))
439 type = IDX_ACTIVE_BORDER;
440
441 if (PtInRect(&pPreviewData->rcActiveCaption, pt))
442 type = IDX_ACTIVE_CAPTION;
443
444 if (PtInRect(&pPreviewData->rcActiveCaptionButtons, pt))
445 type = IDX_CAPTION_BUTTON;
446
447 if (PtInRect(&pPreviewData->rcActiveMenuBar, pt))
448 type = IDX_MENU;
449
450 // if (PtInRect(&pPreviewData->rcSelectedMenuItem, pt))
451 // type = IDX_SELECTION;
452
453 if (PtInRect(&pPreviewData->rcActiveClient, pt))
454 type = IDX_WINDOW;
455
456 if (PtInRect(&pPreviewData->rcActiveScroll, pt))
457 type = IDX_SCROLLBAR;
458
459 if (PtInRect(&pPreviewData->rcDialogFrame, pt))
460 type = IDX_DIALOG;
461
462 if (PtInRect(&pPreviewData->rcDialogCaption, pt))
463 type = IDX_ACTIVE_CAPTION;
464
465 if (PtInRect(&pPreviewData->rcDialogCaptionButtons, pt))
466 type = IDX_CAPTION_BUTTON;
467
468 if (PtInRect(&pPreviewData->rcDialogButton, pt))
469 type = IDX_3D_OBJECTS;
470
471 SendMessage(GetParent(hwnd),
472 WM_COMMAND,
473 MAKEWPARAM(GetWindowLongPtrW(hwnd, GWLP_ID), 0),
474 (LPARAM)type);
475 }
476
477
478 static VOID
479 OnDestroy(PPREVIEW_DATA pPreviewData)
480 {
481 DeleteObject(pPreviewData->hbrScrollbar);
482 DeleteObject(pPreviewData->hbrDesktop);
483 DeleteObject(pPreviewData->hbrWindow);
484
485 DeleteObject(pPreviewData->hCaptionFont);
486 DeleteObject(pPreviewData->hMenuFont);
487 DeleteObject(pPreviewData->hMessageFont);
488
489 DestroyMenu(pPreviewData->hMenu);
490
491 LocalFree((HLOCAL)pPreviewData->lpInAct);
492 LocalFree((HLOCAL)pPreviewData->lpAct);
493 LocalFree((HLOCAL)pPreviewData->lpWinTxt);
494 LocalFree((HLOCAL)pPreviewData->lpMessBox);
495 LocalFree((HLOCAL)pPreviewData->lpMessText);
496 LocalFree((HLOCAL)pPreviewData->lpButText);
497 }
498
499
500 static LRESULT CALLBACK
501 PreviewWndProc(HWND hwnd,
502 UINT uMsg,
503 WPARAM wParam,
504 LPARAM lParam)
505 {
506 PPREVIEW_DATA pPreviewData;
507
508 pPreviewData = (PPREVIEW_DATA)GetWindowLongPtr(hwnd, GWLP_USERDATA);
509
510 switch (uMsg)
511 {
512 case WM_CREATE:
513 pPreviewData = (PPREVIEW_DATA)HeapAlloc(GetProcessHeap(),
514 HEAP_ZERO_MEMORY,
515 sizeof(PREVIEW_DATA));
516 if (!pPreviewData)
517 return -1;
518
519 SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)pPreviewData);
520 OnCreate(hwnd, pPreviewData);
521 break;
522
523 case WM_SIZE:
524 OnSize(LOWORD(lParam), HIWORD(lParam), pPreviewData);
525 break;
526
527 case WM_PAINT:
528 OnPaint(hwnd, pPreviewData);
529 break;
530
531 case WM_LBUTTONDOWN:
532 OnLButtonDown(hwnd, LOWORD(lParam), HIWORD(lParam), pPreviewData);
533 break;
534
535 case WM_DESTROY:
536 OnDestroy(pPreviewData);
537 HeapFree(GetProcessHeap(), 0, pPreviewData);
538 break;
539
540 case PVM_GETCYCAPTION:
541 return pPreviewData->cyCaption;
542
543 case PVM_SETCYCAPTION:
544 if ((INT)lParam > 0)
545 {
546 pPreviewData->cyCaption = (INT)lParam;
547 CalculateItemSize(pPreviewData);
548 InvalidateRect(hwnd, NULL, FALSE);
549 }
550 break;
551
552 case PVM_GETCYMENU:
553 return pPreviewData->cyMenu;
554
555 case PVM_SETCYMENU:
556 if ((INT)lParam > 0)
557 {
558 pPreviewData->cyMenu = (INT)lParam;
559 CalculateItemSize(pPreviewData);
560 InvalidateRect(hwnd, NULL, FALSE);
561 }
562 break;
563
564 case PVM_GETCXSCROLLBAR:
565 return pPreviewData->cxScrollbar;
566
567 case PVM_SETCXSCROLLBAR:
568 if ((INT)lParam > 0)
569 {
570 pPreviewData->cxScrollbar = (INT)lParam;
571 CalculateItemSize(pPreviewData);
572 InvalidateRect(hwnd, NULL, FALSE);
573 }
574 break;
575
576 case PVM_GETCYSIZEFRAME:
577 return pPreviewData->cySizeFrame;
578
579 case PVM_SETCYSIZEFRAME:
580 if ((INT)lParam > 0)
581 {
582 pPreviewData->cySizeFrame = (INT)lParam;
583 CalculateItemSize(pPreviewData);
584 InvalidateRect(hwnd, NULL, FALSE);
585 }
586 break;
587
588 case PVM_SETCAPTIONFONT:
589 CopyMemory(&pPreviewData->lfCaptionFont, (LOGFONT*)lParam, sizeof(LOGFONT));
590 DeleteObject(pPreviewData->hCaptionFont);
591 pPreviewData->hCaptionFont = CreateFontIndirect(&pPreviewData->lfCaptionFont);
592 CalculateItemSize(pPreviewData);
593 InvalidateRect(hwnd, NULL, FALSE);
594 break;
595
596 case PVM_SETMENUFONT:
597 CopyMemory(&pPreviewData->lfMenuFont, (LOGFONT*)lParam, sizeof(LOGFONT));
598 DeleteObject(pPreviewData->hMenuFont);
599 pPreviewData->hMenuFont = CreateFontIndirect(&pPreviewData->lfMenuFont);
600 CalculateItemSize(pPreviewData);
601 InvalidateRect(hwnd, NULL, FALSE);
602 break;
603
604 case PVM_SETDIALOGFONT:
605 CopyMemory(&pPreviewData->lfMessageFont, (LOGFONT*)lParam, sizeof(LOGFONT));
606 DeleteObject(pPreviewData->hMessageFont);
607 pPreviewData->hMessageFont = CreateFontIndirect(&pPreviewData->lfMessageFont);
608 CalculateItemSize(pPreviewData);
609 InvalidateRect(hwnd, NULL, FALSE);
610 break;
611
612 default:
613 DefWindowProc(hwnd,
614 uMsg,
615 wParam,
616 lParam);
617 }
618
619 return TRUE;
620 }
621
622
623 BOOL
624 RegisterPreviewControl(IN HINSTANCE hInstance)
625 {
626 WNDCLASSEX wc = {0};
627
628 wc.cbSize = sizeof(WNDCLASSEX);
629 wc.lpfnWndProc = PreviewWndProc;
630 wc.hInstance = hInstance;
631 wc.hCursor = LoadCursor(NULL, IDC_ARROW);
632 wc.hbrBackground = (HBRUSH)NULL;
633 wc.lpszClassName = szPreviewWndClass;
634
635 return RegisterClassEx(&wc) != (ATOM)0;
636 }
637
638
639 VOID
640 UnregisterPreviewControl(IN HINSTANCE hInstance)
641 {
642 UnregisterClass(szPreviewWndClass,
643 hInstance);
644 }