2 * PROJECT: ReactOS Timedate 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
12 static const TCHAR szPreviewWndClass
[] = TEXT("PreviewWndClass");
14 typedef struct _PREVIEW_DATA
27 DWORD clrActiveCaptionText
;
28 DWORD clrInactiveCaptionText
;
39 RECT rcInactiveCaption
;
40 RECT rcInactiveCaptionButtons
;
44 RECT rcActiveCaptionButtons
;
46 RECT rcSelectedMenuItem
;
52 RECT rcDialogCaptionButtons
;
64 LOGFONT lfCaptionFont
;
66 LOGFONT lfMessageFont
;
74 } PREVIEW_DATA
, *PPREVIEW_DATA
;
79 DrawCaptionButtons(HDC hdc
, LPRECT lpRect
, BOOL bMinMax
)
85 rc3
.left
= lpRect
->right
- 2 - 16;
86 rc3
.top
= lpRect
->top
+ 2;
87 rc3
.right
= lpRect
->right
- 2;
88 rc3
.bottom
= lpRect
->bottom
- 2;
90 DrawFrameControl(hdc
, &rc3
, DFC_CAPTION
, DFCS_CAPTIONCLOSE
);
94 rc4
.left
= rc3
.left
- 16 - 2;
96 rc4
.right
= rc3
.right
- 16 - 2;
97 rc4
.bottom
= rc3
.bottom
;
99 DrawFrameControl(hdc
, &rc4
, DFC_CAPTION
, DFCS_CAPTIONMAX
);
101 rc5
.left
= rc4
.left
- 16;
103 rc5
.right
= rc4
.right
- 16;
104 rc5
.bottom
= rc4
.bottom
;
106 DrawFrameControl(hdc
, &rc5
, DFC_CAPTION
, DFCS_CAPTIONMIN
);
111 DrawScrollbar(HDC hdc
, LPRECT rc
, HBRUSH hbrScrollbar
)
118 width
= rc
->right
- rc
->left
;
120 rcTop
.left
= rc
->left
;
121 rcTop
.right
= rc
->right
;
123 rcTop
.bottom
= rc
->top
+ width
;
125 rcMiddle
.left
= rc
->left
;
126 rcMiddle
.right
= rc
->right
;
127 rcMiddle
.top
= rc
->top
+ width
;
128 rcMiddle
.bottom
= rc
->bottom
- width
;
130 rcBottom
.left
= rc
->left
;
131 rcBottom
.right
= rc
->right
;
132 rcBottom
.top
= rc
->bottom
- width
;
133 rcBottom
.bottom
= rc
->bottom
;
135 DrawFrameControl(hdc
, &rcTop
, DFC_SCROLL
, DFCS_SCROLLUP
);
136 DrawFrameControl(hdc
, &rcBottom
, DFC_SCROLL
, DFCS_SCROLLDOWN
);
138 FillRect(hdc
, &rcMiddle
, hbrScrollbar
);
143 OnCreate(HWND hwnd
, PPREVIEW_DATA pPreviewData
)
145 NONCLIENTMETRICS NonClientMetrics
;
147 pPreviewData
->clrScrollbar
= GetSysColor(COLOR_SCROLLBAR
);
148 pPreviewData
->hbrScrollbar
= CreateSolidBrush(pPreviewData
->clrScrollbar
);
150 pPreviewData
->clrDesktop
= GetSysColor(COLOR_DESKTOP
);
151 pPreviewData
->hbrDesktop
= CreateSolidBrush(pPreviewData
->clrDesktop
);
152 pPreviewData
->clrWindow
= GetSysColor(COLOR_WINDOW
);
153 pPreviewData
->hbrWindow
= CreateSolidBrush(pPreviewData
->clrWindow
);
155 pPreviewData
->clrActiveCaptionText
= GetSysColor(COLOR_CAPTIONTEXT
);
156 pPreviewData
->clrInactiveCaptionText
= GetSysColor(COLOR_INACTIVECAPTIONTEXT
);
157 pPreviewData
->clrWindowText
= GetSysColor(COLOR_WINDOWTEXT
);
158 pPreviewData
->clrButtonText
= GetSysColor(COLOR_BTNTEXT
);
160 pPreviewData
->cxEdge
= GetSystemMetrics(SM_CXEDGE
);
161 pPreviewData
->cyEdge
= GetSystemMetrics(SM_CXEDGE
);
163 pPreviewData
->cyCaption
= 20; //GetSystemMetrics(SM_CYCAPTION);
166 NonClientMetrics
.cbSize
= sizeof(NONCLIENTMETRICS
);
167 SystemParametersInfo(SPI_GETNONCLIENTMETRICS
, sizeof(NONCLIENTMETRICS
), &NonClientMetrics
, 0);
169 pPreviewData
->lfCaptionFont
= NonClientMetrics
.lfCaptionFont
;
170 pPreviewData
->hCaptionFont
= CreateFontIndirect(&pPreviewData
->lfCaptionFont
);
172 pPreviewData
->lfMenuFont
= NonClientMetrics
.lfMenuFont
;
173 pPreviewData
->hMenuFont
= CreateFontIndirect(&pPreviewData
->lfMenuFont
);
175 pPreviewData
->lfMessageFont
= NonClientMetrics
.lfMessageFont
;
176 pPreviewData
->hMessageFont
= CreateFontIndirect(&pPreviewData
->lfMessageFont
);
178 /* Load and modify the menu */
179 pPreviewData
->hMenu
= LoadMenu(hApplet
, MAKEINTRESOURCE(IDR_PREVIEW_MENU
));
180 EnableMenuItem(pPreviewData
->hMenu
, ID_MENU_DISABLED
,
181 MF_BYCOMMAND
| MF_DISABLED
);
182 HiliteMenuItem(hwnd
, pPreviewData
->hMenu
,
183 ID_MENU_SELECTED
, MF_BYCOMMAND
| MF_HILITE
);
185 // GetMenuItemRect(hwnd, pPreviewData->hMenu,
186 // ID_MENU_SELECTED, &pPreviewData->rcSelectedMenuItem);
189 AllocAndLoadString(&pPreviewData
->lpInAct
, hApplet
, IDS_INACTWIN
);
190 AllocAndLoadString(&pPreviewData
->lpAct
, hApplet
, IDS_ACTWIN
);
191 AllocAndLoadString(&pPreviewData
->lpWinTxt
, hApplet
, IDS_WINTEXT
);
192 AllocAndLoadString(&pPreviewData
->lpMessBox
, hApplet
, IDS_MESSBOX
);
193 AllocAndLoadString(&pPreviewData
->lpMessText
, hApplet
, IDS_MESSTEXT
);
194 AllocAndLoadString(&pPreviewData
->lpButText
, hApplet
, IDS_BUTTEXT
);
199 OnSize(INT cx
, INT cy
, PPREVIEW_DATA pPreviewData
)
203 /* Get Desktop rectangle */
204 pPreviewData
->rcDesktop
.left
= 0;
205 pPreviewData
->rcDesktop
.top
= 0;
206 pPreviewData
->rcDesktop
.right
= cx
;
207 pPreviewData
->rcDesktop
.bottom
= cy
;
209 /* Calculate the inactive window rectangle */
210 pPreviewData
->rcInactiveFrame
.left
= pPreviewData
->rcDesktop
.left
+ 8;
211 pPreviewData
->rcInactiveFrame
.top
= pPreviewData
->rcDesktop
.top
+ 8;
212 pPreviewData
->rcInactiveFrame
.right
= pPreviewData
->rcDesktop
.right
- 25;
213 pPreviewData
->rcInactiveFrame
.bottom
= pPreviewData
->rcDesktop
.bottom
- 30;
215 /* Calculate the inactive caption rectangle */
216 pPreviewData
->rcInactiveCaption
.left
= pPreviewData
->rcInactiveFrame
.left
+ pPreviewData
->cxEdge
+ 1/*3*/ + 1;
217 pPreviewData
->rcInactiveCaption
.top
= pPreviewData
->rcInactiveFrame
.top
+ pPreviewData
->cyEdge
+ 1/*3*/ + 1;
218 pPreviewData
->rcInactiveCaption
.right
= pPreviewData
->rcInactiveFrame
.right
- pPreviewData
->cxEdge
- 1/*3*/ - 1;
219 pPreviewData
->rcInactiveCaption
.bottom
= pPreviewData
->rcInactiveFrame
.top
+ pPreviewData
->cyCaption
/*20*/ + 2;
221 /* Calculate the inactive caption buttons rectangle */
222 pPreviewData
->rcInactiveCaptionButtons
.left
= pPreviewData
->rcInactiveCaption
.right
- 2 - 2 - 3 * 16;
223 pPreviewData
->rcInactiveCaptionButtons
.top
= pPreviewData
->rcInactiveCaption
.top
+ 2;
224 pPreviewData
->rcInactiveCaptionButtons
.right
= pPreviewData
->rcInactiveCaption
.right
- 2;
225 pPreviewData
->rcInactiveCaptionButtons
.bottom
= pPreviewData
->rcInactiveCaption
.bottom
- 2;
227 /* Calculate the active window rectangle */
228 pPreviewData
->rcActiveFrame
.left
= pPreviewData
->rcInactiveFrame
.left
+ 3 + 1;
229 pPreviewData
->rcActiveFrame
.top
= pPreviewData
->rcInactiveCaption
.bottom
+ 1;
230 pPreviewData
->rcActiveFrame
.right
= pPreviewData
->rcDesktop
.right
- 10;
231 pPreviewData
->rcActiveFrame
.bottom
= pPreviewData
->rcDesktop
.bottom
- 25;
233 /* Calculate the active caption rectangle */
234 pPreviewData
->rcActiveCaption
.left
= pPreviewData
->rcActiveFrame
.left
+ 3 + 1;
235 pPreviewData
->rcActiveCaption
.top
= pPreviewData
->rcActiveFrame
.top
+ 3 + 1;
236 pPreviewData
->rcActiveCaption
.right
= pPreviewData
->rcActiveFrame
.right
- 3 - 1;
237 pPreviewData
->rcActiveCaption
.bottom
= pPreviewData
->rcActiveFrame
.top
+ pPreviewData
->cyCaption
/*20*/ + 2;
239 /* Calculate the active caption buttons rectangle */
240 pPreviewData
->rcActiveCaptionButtons
.left
= pPreviewData
->rcActiveCaption
.right
- 2 - 2 - 3 * 16;
241 pPreviewData
->rcActiveCaptionButtons
.top
= pPreviewData
->rcActiveCaption
.top
+ 2;
242 pPreviewData
->rcActiveCaptionButtons
.right
= pPreviewData
->rcActiveCaption
.right
- 2;
243 pPreviewData
->rcActiveCaptionButtons
.bottom
= pPreviewData
->rcActiveCaption
.bottom
- 2;
245 /* Calculate the active menu bar rectangle */
246 pPreviewData
->rcActiveMenuBar
.left
= pPreviewData
->rcActiveFrame
.left
+ 3 + 1;
247 pPreviewData
->rcActiveMenuBar
.top
= pPreviewData
->rcActiveCaption
.bottom
+ 1;
248 pPreviewData
->rcActiveMenuBar
.right
= pPreviewData
->rcActiveFrame
.right
- 3 - 1;
249 pPreviewData
->rcActiveMenuBar
.bottom
= pPreviewData
->rcActiveMenuBar
.top
+ 20;
251 /* Calculate the active client rectangle */
252 pPreviewData
->rcActiveClient
.left
= pPreviewData
->rcActiveFrame
.left
+ 3 + 1;
253 pPreviewData
->rcActiveClient
.top
= pPreviewData
->rcActiveMenuBar
.bottom
; // + 1;
254 pPreviewData
->rcActiveClient
.right
= pPreviewData
->rcActiveFrame
.right
- 3 - 1;
255 pPreviewData
->rcActiveClient
.bottom
= pPreviewData
->rcActiveFrame
.bottom
- 3 - 1;
257 /* Calculate the active scroll rectangle */
258 pPreviewData
->rcActiveScroll
.left
= pPreviewData
->rcActiveClient
.right
- 2 - 16;
259 pPreviewData
->rcActiveScroll
.top
= pPreviewData
->rcActiveClient
.top
+ 2;
260 pPreviewData
->rcActiveScroll
.right
= pPreviewData
->rcActiveClient
.right
- 2;
261 pPreviewData
->rcActiveScroll
.bottom
= pPreviewData
->rcActiveClient
.bottom
- 2;
265 pPreviewData
->rcDialogFrame
.left
= pPreviewData
->rcActiveClient
.left
+ 4;
266 pPreviewData
->rcDialogFrame
.top
= (pPreviewData
->rcDesktop
.bottom
* 60) / 100;
267 pPreviewData
->rcDialogFrame
.right
= (pPreviewData
->rcDesktop
.right
* 65) / 100;
268 pPreviewData
->rcDialogFrame
.bottom
= pPreviewData
->rcDesktop
.bottom
- 5;
270 /* Calculate the dialog caption rectangle */
271 pPreviewData
->rcDialogCaption
.left
= pPreviewData
->rcDialogFrame
.left
+ 3;
272 pPreviewData
->rcDialogCaption
.top
= pPreviewData
->rcDialogFrame
.top
+ 3;
273 pPreviewData
->rcDialogCaption
.right
= pPreviewData
->rcDialogFrame
.right
- 3;
274 pPreviewData
->rcDialogCaption
.bottom
= pPreviewData
->rcDialogFrame
.top
+ 20 + 1;
276 /* Calculate the inactive caption buttons rectangle */
277 pPreviewData
->rcDialogCaptionButtons
.left
= pPreviewData
->rcDialogCaption
.right
- 2 - 16;
278 pPreviewData
->rcDialogCaptionButtons
.top
= pPreviewData
->rcDialogCaption
.top
+ 2;
279 pPreviewData
->rcDialogCaptionButtons
.right
= pPreviewData
->rcDialogCaption
.right
- 2;
280 pPreviewData
->rcDialogCaptionButtons
.bottom
= pPreviewData
->rcDialogCaption
.bottom
- 2;
282 /* Calculate the dialog client rectangle */
283 pPreviewData
->rcDialogClient
.left
= pPreviewData
->rcDialogFrame
.left
+ 3;
284 pPreviewData
->rcDialogClient
.top
= pPreviewData
->rcDialogCaption
.bottom
+ 1;
285 pPreviewData
->rcDialogClient
.right
= pPreviewData
->rcDialogFrame
.right
- 3;
286 pPreviewData
->rcDialogClient
.bottom
= pPreviewData
->rcDialogFrame
.bottom
- 3;
288 /* Calculate the dialog button rectangle */
292 pPreviewData
->rcDialogButton
.left
=
293 (pPreviewData
->rcDialogClient
.right
+ pPreviewData
->rcDialogClient
.left
- width
) / 2;
294 pPreviewData
->rcDialogButton
.right
= pPreviewData
->rcDialogButton
.left
+ width
;
295 pPreviewData
->rcDialogButton
.bottom
= pPreviewData
->rcDialogClient
.bottom
- 2;
296 pPreviewData
->rcDialogButton
.top
= pPreviewData
->rcDialogButton
.bottom
- height
;
301 OnPaint(HWND hwnd
, PPREVIEW_DATA pPreviewData
)
308 hdc
= BeginPaint(hwnd
, &ps
);
311 FillRect(hdc
, &pPreviewData
->rcDesktop
, pPreviewData
->hbrDesktop
);
313 /* Inactive Window */
314 DrawEdge(hdc
, &pPreviewData
->rcInactiveFrame
, EDGE_RAISED
, BF_RECT
| BF_MIDDLE
);
315 SetTextColor(hdc
, pPreviewData
->clrInactiveCaptionText
);
316 DrawCaptionTemp(NULL
, hdc
, &pPreviewData
->rcInactiveCaption
, pPreviewData
->hCaptionFont
,
317 NULL
, pPreviewData
->lpInAct
, DC_GRADIENT
| DC_ICON
| DC_TEXT
);
318 DrawCaptionButtons(hdc
, &pPreviewData
->rcInactiveCaption
, TRUE
);
321 DrawEdge(hdc
, &pPreviewData
->rcActiveFrame
, EDGE_RAISED
, BF_RECT
| BF_MIDDLE
);
322 SetTextColor(hdc
, pPreviewData
->clrActiveCaptionText
);
323 DrawCaptionTemp(NULL
, hdc
, &pPreviewData
->rcActiveCaption
, pPreviewData
->hCaptionFont
,
324 NULL
, pPreviewData
->lpAct
, DC_ACTIVE
| DC_GRADIENT
| DC_ICON
| DC_TEXT
);
325 DrawCaptionButtons(hdc
, &pPreviewData
->rcActiveCaption
, TRUE
);
327 /* FIXME: Draw the menu bar */
328 DrawMenuBarTemp(hwnd
, hdc
, &pPreviewData
->rcActiveMenuBar
,
329 pPreviewData
->hMenu
/*HMENU hMenu*/,
330 pPreviewData
->hMessageFont
/*HFONT hFont*/);
332 /* Draw the client area */
333 CopyRect(&rc
, &pPreviewData
->rcActiveClient
);
334 DrawEdge(hdc
, &rc
, EDGE_SUNKEN
, BF_RECT
| BF_ADJUST
);
335 FillRect(hdc
, &rc
, pPreviewData
->hbrWindow
);
337 /* Draw the client text */
338 CopyRect(&rc
, &pPreviewData
->rcActiveClient
);
341 SetTextColor(hdc
, pPreviewData
->clrWindowText
);
342 hOldFont
= SelectObject(hdc
, pPreviewData
->hMessageFont
);
343 DrawText(hdc
, pPreviewData
->lpWinTxt
, lstrlen(pPreviewData
->lpWinTxt
), &rc
, DT_LEFT
);
344 SelectObject(hdc
, hOldFont
);
346 /* Draw the scroll bar */
347 DrawScrollbar(hdc
, &pPreviewData
->rcActiveScroll
, pPreviewData
->hbrScrollbar
);
350 DrawEdge(hdc
, &pPreviewData
->rcDialogFrame
, EDGE_RAISED
, BF_RECT
| BF_MIDDLE
);
351 SetTextColor(hdc
, pPreviewData
->clrActiveCaptionText
);
352 DrawCaptionTemp(NULL
, hdc
, &pPreviewData
->rcDialogCaption
, pPreviewData
->hCaptionFont
,
353 NULL
, pPreviewData
->lpMessBox
, DC_ACTIVE
| DC_GRADIENT
| DC_ICON
| DC_TEXT
);
354 DrawCaptionButtons(hdc
, &pPreviewData
->rcDialogCaption
, FALSE
);
356 /* Draw the dialog text */
357 CopyRect(&rc
, &pPreviewData
->rcDialogClient
);
360 SetTextColor(hdc
, RGB(0,0,0));
361 hOldFont
= SelectObject(hdc
, pPreviewData
->hMessageFont
);
362 DrawText(hdc
, pPreviewData
->lpMessText
, lstrlen(pPreviewData
->lpMessText
), &rc
, DT_LEFT
);
363 SelectObject(hdc
, hOldFont
);
366 DrawFrameControl(hdc
, &pPreviewData
->rcDialogButton
, DFC_BUTTON
, DFCS_BUTTONPUSH
);
367 CopyRect(&rc
, &pPreviewData
->rcDialogButton
);
368 SetTextColor(hdc
, pPreviewData
->clrButtonText
);
369 hOldFont
= SelectObject(hdc
, pPreviewData
->hMessageFont
);
370 DrawText(hdc
, pPreviewData
->lpButText
, lstrlen(pPreviewData
->lpButText
), &rc
, DT_VCENTER
| DT_CENTER
| DT_SINGLELINE
);
371 SelectObject(hdc
, hOldFont
);
378 OnLButtonDown(HWND hwnd
, int xPos
, int yPos
, PPREVIEW_DATA pPreviewData
)
380 UINT type
= IDX_DESKTOP
;
386 if (PtInRect(&pPreviewData
->rcInactiveFrame
, pt
))
387 type
= IDX_INACTIVE_BORDER
;
389 if (PtInRect(&pPreviewData
->rcInactiveCaption
, pt
))
390 type
= IDX_INACTIVE_CAPTION
;
392 if (PtInRect(&pPreviewData
->rcInactiveCaptionButtons
, pt
))
393 type
= IDX_CAPTION_BUTTON
;
395 if (PtInRect(&pPreviewData
->rcActiveFrame
, pt
))
396 type
= IDX_ACTIVE_BORDER
;
398 if (PtInRect(&pPreviewData
->rcActiveCaption
, pt
))
399 type
= IDX_ACTIVE_CAPTION
;
401 if (PtInRect(&pPreviewData
->rcActiveCaptionButtons
, pt
))
402 type
= IDX_CAPTION_BUTTON
;
404 if (PtInRect(&pPreviewData
->rcActiveMenuBar
, pt
))
407 // if (PtInRect(&pPreviewData->rcSelectedMenuItem, pt))
408 // type = IDX_SELECTION;
410 if (PtInRect(&pPreviewData
->rcActiveClient
, pt
))
413 if (PtInRect(&pPreviewData
->rcActiveScroll
, pt
))
414 type
= IDX_SCROLLBAR
;
416 if (PtInRect(&pPreviewData
->rcDialogFrame
, pt
))
419 if (PtInRect(&pPreviewData
->rcDialogCaption
, pt
))
420 type
= IDX_ACTIVE_CAPTION
;
422 if (PtInRect(&pPreviewData
->rcDialogCaptionButtons
, pt
))
423 type
= IDX_CAPTION_BUTTON
;
425 if (PtInRect(&pPreviewData
->rcDialogButton
, pt
))
426 type
= IDX_3D_OBJECTS
;
428 SendMessage(GetParent(hwnd
), WM_USER
, 0, type
);
433 OnDestroy(PPREVIEW_DATA pPreviewData
)
435 DeleteObject(pPreviewData
->hbrScrollbar
);
436 DeleteObject(pPreviewData
->hbrDesktop
);
437 DeleteObject(pPreviewData
->hbrWindow
);
439 DeleteObject(pPreviewData
->hCaptionFont
);
440 DeleteObject(pPreviewData
->hMenuFont
);
441 DeleteObject(pPreviewData
->hMessageFont
);
443 DestroyMenu(pPreviewData
->hMenu
);
445 LocalFree((HLOCAL
)pPreviewData
->lpInAct
);
446 LocalFree((HLOCAL
)pPreviewData
->lpAct
);
447 LocalFree((HLOCAL
)pPreviewData
->lpWinTxt
);
448 LocalFree((HLOCAL
)pPreviewData
->lpMessBox
);
449 LocalFree((HLOCAL
)pPreviewData
->lpMessText
);
450 LocalFree((HLOCAL
)pPreviewData
->lpButText
);
454 static LRESULT CALLBACK
455 PreviewWndProc(HWND hwnd
,
460 PPREVIEW_DATA pPreviewData
;
462 pPreviewData
= (PPREVIEW_DATA
)GetWindowLongPtr(hwnd
, GWLP_USERDATA
);
467 pPreviewData
= (PPREVIEW_DATA
)HeapAlloc(GetProcessHeap(),
469 sizeof(PREVIEW_DATA
));
473 SetWindowLongPtr(hwnd
, GWLP_USERDATA
, (LONG_PTR
)pPreviewData
);
474 OnCreate(hwnd
, pPreviewData
);
478 OnSize(LOWORD(lParam
), HIWORD(lParam
), pPreviewData
);
482 OnPaint(hwnd
, pPreviewData
);
486 OnLButtonDown(hwnd
, LOWORD(lParam
), HIWORD(lParam
), pPreviewData
);
490 OnDestroy(pPreviewData
);
491 HeapFree(GetProcessHeap(), 0, pPreviewData
);
506 RegisterPreviewControl(IN HINSTANCE hInstance
)
510 wc
.cbSize
= sizeof(WNDCLASSEX
);
511 wc
.lpfnWndProc
= PreviewWndProc
;
512 wc
.hInstance
= hInstance
;
513 wc
.hCursor
= LoadCursor(NULL
, IDC_ARROW
);
514 wc
.hbrBackground
= (HBRUSH
)NULL
; //(COLOR_BTNFACE + 1);
515 wc
.lpszClassName
= szPreviewWndClass
;
517 return RegisterClassEx(&wc
) != (ATOM
)0;
522 UnregisterPreviewControl(IN HINSTANCE hInstance
)
524 UnregisterClass(szPreviewWndClass
,