Eric's cute control made me smile, so I've added some text to the windows.
[reactos.git] / reactos / dll / cpl / desk / preview.c
1 /*
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 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 DWORD clrDesktop;
17 HBRUSH hbrDesktop;
18
19 DWORD clrWindow;
20 HBRUSH hbrWindow;
21
22 INT cxEdge;
23 INT cyEdge;
24
25 INT cyCaption;
26
27 RECT rcDesktop;
28 RECT rcInactiveFrame;
29 RECT rcInactiveCaption;
30
31 RECT rcActiveFrame;
32 RECT rcActiveCaption;
33 RECT rcActiveClient;
34 RECT rcActiveScroll;
35
36 RECT rcDialogFrame;
37 RECT rcDialogCaption;
38 RECT rcDialogClient;
39
40 RECT rcDialogButton;
41
42 LOGFONT CaptionFont;
43 LOGFONT DialogFont;
44 LOGFONT MenuFont;
45
46 } PREVIEW_DATA, *PPREVIEW_DATA;
47
48
49 static VOID
50 DrawCaptionButtons(HDC hdc, LPRECT lpRect, BOOL bMinMax)
51 {
52 RECT rc3;
53 RECT rc4;
54 RECT rc5;
55
56 rc3.left = lpRect->right - 2 - 16;
57 rc3.top = lpRect->top + 2;
58 rc3.right = lpRect->right - 2;
59 rc3.bottom = lpRect->bottom - 2;
60
61 DrawFrameControl(hdc, &rc3, DFC_CAPTION, DFCS_CAPTIONCLOSE);
62
63 if (bMinMax)
64 {
65 rc4.left = rc3.left - 16 - 2;
66 rc4.top = rc3.top;
67 rc4.right = rc3.right - 16 - 2;
68 rc4.bottom = rc3.bottom;
69
70 DrawFrameControl(hdc, &rc4, DFC_CAPTION, DFCS_CAPTIONMAX);
71
72 rc5.left = rc4.left - 16;
73 rc5.top = rc4.top;
74 rc5.right = rc4.right - 16;
75 rc5.bottom = rc4.bottom;
76
77 DrawFrameControl(hdc, &rc5, DFC_CAPTION, DFCS_CAPTIONMIN);
78 }
79 }
80
81
82 static VOID
83 OnSize(INT cx, INT cy, PPREVIEW_DATA pPreviewData)
84 {
85 int width, height;
86
87 /* Get Desktop rectangle */
88 pPreviewData->rcDesktop.left = 0;
89 pPreviewData->rcDesktop.top = 0;
90 pPreviewData->rcDesktop.right = cx;
91 pPreviewData->rcDesktop.bottom = cy;
92
93 /* Calculate the inactive window rectangle */
94 pPreviewData->rcInactiveFrame.left = pPreviewData->rcDesktop.left + 8;
95 pPreviewData->rcInactiveFrame.top = pPreviewData->rcDesktop.top + 8;
96 pPreviewData->rcInactiveFrame.right = pPreviewData->rcDesktop.right - 25;
97 pPreviewData->rcInactiveFrame.bottom = pPreviewData->rcDesktop.bottom - 30;
98
99 /* Calculate the inactive caption rectangle */
100 pPreviewData->rcInactiveCaption.left = pPreviewData->rcInactiveFrame.left + pPreviewData->cxEdge + 1/*3*/ + 1;
101 pPreviewData->rcInactiveCaption.top = pPreviewData->rcInactiveFrame.top + pPreviewData->cyEdge + 1/*3*/ + 1;
102 pPreviewData->rcInactiveCaption.right = pPreviewData->rcInactiveFrame.right - pPreviewData->cxEdge - 1/*3*/ - 1;
103 pPreviewData->rcInactiveCaption.bottom = pPreviewData->rcInactiveFrame.top + pPreviewData->cyCaption /*20*/ + 2;
104
105 /* Calculate the active window rectangle */
106 pPreviewData->rcActiveFrame.left = pPreviewData->rcInactiveFrame.left + 3 + 1;
107 pPreviewData->rcActiveFrame.top = pPreviewData->rcInactiveCaption.bottom + 2;
108 pPreviewData->rcActiveFrame.right = pPreviewData->rcDesktop.right - 10;
109 pPreviewData->rcActiveFrame.bottom = pPreviewData->rcDesktop.bottom - 25;
110
111 /* Calculate the active caption rectangle */
112 pPreviewData->rcActiveCaption.left = pPreviewData->rcActiveFrame.left + 3 + 1;
113 pPreviewData->rcActiveCaption.top = pPreviewData->rcActiveFrame.top + 3 + 1;
114 pPreviewData->rcActiveCaption.right = pPreviewData->rcActiveFrame.right - 3 - 1;
115 pPreviewData->rcActiveCaption.bottom = pPreviewData->rcActiveFrame.top + pPreviewData->cyCaption/*20*/ + 2;
116
117 /* FIXME: Calculate the active menu bar rectangle */
118
119 /* Calculate the active client rectangle */
120 pPreviewData->rcActiveClient.left = pPreviewData->rcActiveFrame.left + 3 + 1;
121 pPreviewData->rcActiveClient.top = pPreviewData->rcActiveCaption.bottom + 20 + 2;
122 pPreviewData->rcActiveClient.right = pPreviewData->rcActiveFrame.right - 3 - 1;
123 pPreviewData->rcActiveClient.bottom = pPreviewData->rcActiveFrame.bottom - 3 - 1;
124
125 /* Calculate the active scroll rectangle */
126 pPreviewData->rcActiveScroll.left = pPreviewData->rcActiveClient.right - 2 - 16;
127 pPreviewData->rcActiveScroll.top = pPreviewData->rcActiveClient.top + 2;
128 pPreviewData->rcActiveScroll.right = pPreviewData->rcActiveClient.right - 2;
129 pPreviewData->rcActiveScroll.bottom = pPreviewData->rcActiveClient.bottom - 2;
130
131
132 /* Dialog window */
133 pPreviewData->rcDialogFrame.left = pPreviewData->rcActiveClient.left + 4;
134 pPreviewData->rcDialogFrame.top = (pPreviewData->rcDesktop.bottom * 60) / 100;
135 pPreviewData->rcDialogFrame.right = (pPreviewData->rcDesktop.right * 65) / 100;
136 pPreviewData->rcDialogFrame.bottom = pPreviewData->rcDesktop.bottom - 5;
137
138 /* Calculate the dialog caption rectangle */
139 pPreviewData->rcDialogCaption.left = pPreviewData->rcDialogFrame.left + 3;
140 pPreviewData->rcDialogCaption.top = pPreviewData->rcDialogFrame.top + 3;
141 pPreviewData->rcDialogCaption.right = pPreviewData->rcDialogFrame.right - 3;
142 pPreviewData->rcDialogCaption.bottom = pPreviewData->rcDialogFrame.top + 20 + 2;
143
144 /* Calculate the dialog client rectangle */
145 pPreviewData->rcDialogClient.left = pPreviewData->rcDialogFrame.left + 3;
146 pPreviewData->rcDialogClient.top = pPreviewData->rcDialogCaption.bottom + 1;
147 pPreviewData->rcDialogClient.right = pPreviewData->rcDialogFrame.right - 3;
148 pPreviewData->rcDialogClient.bottom = pPreviewData->rcDialogFrame.bottom - 3;
149
150 /* Calculate the dialog button rectangle */
151 width = 80;
152 height = 28;
153
154 pPreviewData->rcDialogButton.left =
155 (pPreviewData->rcDialogClient.right + pPreviewData->rcDialogClient.left - width) / 2;
156 pPreviewData->rcDialogButton.right = pPreviewData->rcDialogButton.left + width;
157 pPreviewData->rcDialogButton.bottom = pPreviewData->rcDialogClient.bottom - 2;
158 pPreviewData->rcDialogButton.top = pPreviewData->rcDialogButton.bottom - height;
159 }
160
161
162 static VOID
163 DrawScrollbar(HDC hdc, LPRECT rc)
164 {
165
166 }
167
168
169 static LRESULT CALLBACK
170 PreviewWndProc(HWND hwnd,
171 UINT uMsg,
172 WPARAM wParam,
173 LPARAM lParam)
174 {
175 PPREVIEW_DATA pPreviewData;
176 HDC hdc;
177 PAINTSTRUCT ps;
178 RECT rc;
179
180 static TCHAR szInAct[32];
181 static TCHAR szAct[32];
182 static TCHAR szWinTxt[32];
183 static TCHAR szMessBox[32];
184 static TCHAR szMessText[32];
185 static TCHAR szButText[4];
186
187 pPreviewData = (PPREVIEW_DATA)GetWindowLongPtr(hwnd, GWLP_USERDATA);
188
189 switch (uMsg)
190 {
191 case WM_CREATE:
192 {
193 NONCLIENTMETRICS NonClientMetrics;
194
195 pPreviewData = (PPREVIEW_DATA)HeapAlloc(GetProcessHeap(),
196 HEAP_ZERO_MEMORY,
197 sizeof(PREVIEW_DATA));
198 if (!pPreviewData)
199 return -1;
200
201 SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)pPreviewData);
202 pPreviewData->clrDesktop = GetSysColor(COLOR_DESKTOP);
203 pPreviewData->hbrDesktop = CreateSolidBrush(pPreviewData->clrDesktop);
204 pPreviewData->clrWindow = GetSysColor(COLOR_WINDOW);
205 pPreviewData->hbrWindow = CreateSolidBrush(pPreviewData->clrWindow);
206
207 pPreviewData->cxEdge = GetSystemMetrics(SM_CXEDGE);
208 pPreviewData->cyEdge = GetSystemMetrics(SM_CXEDGE);
209
210 pPreviewData->cyCaption = 20; //GetSystemMetrics(SM_CYCAPTION);
211
212 /* load font info */
213 NonClientMetrics.cbSize = sizeof(NONCLIENTMETRICS);
214 SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICS), &NonClientMetrics, 0);
215 pPreviewData->CaptionFont = NonClientMetrics.lfCaptionFont;
216 pPreviewData->MenuFont = NonClientMetrics.lfMenuFont;
217 pPreviewData->DialogFont = NonClientMetrics.lfMessageFont;
218
219 LoadString(hApplet, IDS_INACTWIN, szInAct, sizeof(szInAct));
220 LoadString(hApplet, IDS_ACTWIN, szAct, sizeof(szAct));
221 LoadString(hApplet, IDS_WINTEXT, szWinTxt, sizeof(szWinTxt));
222 LoadString(hApplet, IDS_MESSBOX, szMessBox, sizeof(szMessBox));
223 LoadString(hApplet, IDS_MESSTEXT, szMessText, sizeof(szMessText));
224 LoadString(hApplet, IDS_BUTTEXT, szButText, sizeof(szButText));
225
226 break;
227 }
228
229 case WM_SIZE:
230 OnSize(LOWORD(lParam), HIWORD(lParam), pPreviewData);
231 break;
232
233 case WM_PAINT:
234 {
235 RECT tmpRc;
236
237 hdc = BeginPaint(hwnd, &ps);
238
239 /* Desktop */
240 FillRect(hdc, &pPreviewData->rcDesktop, pPreviewData->hbrDesktop);
241
242 /* Inactive Window */
243 DrawEdge(hdc, &pPreviewData->rcInactiveFrame, EDGE_RAISED, BF_RECT | BF_MIDDLE);
244 DrawCaption(hwnd, hdc, &pPreviewData->rcInactiveCaption, DC_GRADIENT | DC_TEXT);
245 DrawCaptionButtons(hdc, &pPreviewData->rcInactiveCaption, TRUE);
246 CopyMemory(&tmpRc, &pPreviewData->rcInactiveCaption, sizeof(RECT));
247 tmpRc.left += 4;
248 tmpRc.top += 2;
249 SelectObject(hdc, CreateFontIndirect(&pPreviewData->CaptionFont));
250 SetTextColor(hdc, RGB(212,208,200));
251 DrawText(hdc, szInAct, lstrlen(szInAct), &tmpRc, DT_LEFT);
252 DeleteObject(SelectObject(hdc, GetStockObject(SYSTEM_FONT)));
253
254
255 /* Active Window */
256 DrawEdge(hdc, &pPreviewData->rcActiveFrame, EDGE_RAISED, BF_RECT | BF_MIDDLE);
257 DrawCaption(hwnd, hdc, &pPreviewData->rcActiveCaption, DC_ACTIVE | DC_GRADIENT | DC_TEXT);
258 DrawCaptionButtons(hdc, &pPreviewData->rcActiveCaption, TRUE);
259 CopyMemory(&tmpRc, &pPreviewData->rcActiveCaption, sizeof(RECT));
260 tmpRc.left += 4;
261 tmpRc.top += 2;
262 SetTextColor(hdc, RGB(255,255,255)); // FIXME: don't hardcode colors
263 SelectObject(hdc, CreateFontIndirect(&pPreviewData->CaptionFont));
264 DrawText(hdc, szAct, lstrlen(szAct), &tmpRc, DT_LEFT);
265 DeleteObject(SelectObject(hdc, GetStockObject(SYSTEM_FONT)));
266
267 /* FIXME: Draw the menu bar */
268 CopyRect(&rc, &pPreviewData->rcActiveClient);
269 DrawEdge(hdc, &rc, EDGE_SUNKEN, BF_RECT | BF_ADJUST);
270 FillRect(hdc, &rc, pPreviewData->hbrWindow);
271
272 /* Draw the client text */
273 CopyMemory(&tmpRc, &pPreviewData->rcActiveClient, sizeof(RECT));
274 tmpRc.left += 4;
275 tmpRc.top += 2;
276 SetTextColor(hdc, RGB(0,0,0));
277 SelectObject(hdc, CreateFontIndirect(&pPreviewData->DialogFont));
278 DrawText(hdc, szWinTxt, lstrlen(szWinTxt), &tmpRc, DT_LEFT);
279 DeleteObject(SelectObject(hdc, GetStockObject(SYSTEM_FONT)));
280
281 /* Draw the scroll bar */
282 DrawScrollbar(hdc, &pPreviewData->rcActiveScroll);
283
284
285 /* Dialog Window */
286 DrawEdge(hdc, &pPreviewData->rcDialogFrame, EDGE_RAISED, BF_RECT | BF_MIDDLE);
287 DrawCaption(hwnd, hdc, &pPreviewData->rcDialogCaption, DC_ACTIVE | DC_GRADIENT | DC_TEXT);
288 DrawCaptionButtons(hdc, &pPreviewData->rcDialogCaption, FALSE);
289 CopyMemory(&tmpRc, &pPreviewData->rcDialogCaption, sizeof(RECT));
290 tmpRc.left += 4;
291 tmpRc.top += 2;
292 SetTextColor(hdc, RGB(255,255,255));
293 SelectObject(hdc, CreateFontIndirect(&pPreviewData->CaptionFont));
294 DrawText(hdc, szMessBox, lstrlen(szMessBox), &tmpRc, DT_LEFT);
295 DeleteObject(SelectObject(hdc, GetStockObject(SYSTEM_FONT)));
296
297 /* draw the dialog text */
298 CopyMemory(&tmpRc, &pPreviewData->rcDialogClient, sizeof(RECT));
299 tmpRc.left += 4;
300 tmpRc.top += 2;
301 SetTextColor(hdc, RGB(0,0,0));
302 SelectObject(hdc, CreateFontIndirect(&pPreviewData->DialogFont));
303 DrawText(hdc, szMessText, lstrlen(szMessText), &tmpRc, DT_LEFT);
304 DeleteObject(SelectObject(hdc, GetStockObject(SYSTEM_FONT)));
305
306 /* Draw Button */
307 DrawFrameControl(hdc, &pPreviewData->rcDialogButton, DFC_BUTTON, DFCS_BUTTONPUSH);
308 CopyMemory(&tmpRc, &pPreviewData->rcDialogButton, sizeof(RECT));
309 tmpRc.top += 6;
310 SelectObject(hdc, CreateFontIndirect(&pPreviewData->DialogFont));
311 DrawText(hdc, szButText, lstrlen(szButText), &tmpRc, DT_CENTER);
312 DeleteObject(SelectObject(hdc, GetStockObject(SYSTEM_FONT)));
313
314
315 EndPaint(hwnd, &ps);
316 break;
317 }
318
319 case WM_DESTROY:
320 DeleteObject(pPreviewData->hbrDesktop);
321 DeleteObject(pPreviewData->hbrWindow);
322
323 HeapFree(GetProcessHeap(), 0, pPreviewData);
324 break;
325
326 default:
327 DefWindowProc(hwnd,
328 uMsg,
329 wParam,
330 lParam);
331 }
332
333 return TRUE;
334 }
335
336
337 BOOL
338 RegisterPreviewControl(IN HINSTANCE hInstance)
339 {
340 WNDCLASSEX wc = {0};
341
342 wc.cbSize = sizeof(WNDCLASSEX);
343 wc.lpfnWndProc = PreviewWndProc;
344 wc.hInstance = hInstance;
345 wc.hCursor = LoadCursor(NULL, IDC_ARROW);
346 wc.hbrBackground = (HBRUSH)NULL; //(COLOR_BTNFACE + 1);
347 wc.lpszClassName = szPreviewWndClass;
348
349 return RegisterClassEx(&wc) != (ATOM)0;
350 }
351
352
353 VOID
354 UnregisterPreviewControl(IN HINSTANCE hInstance)
355 {
356 UnregisterClass(szPreviewWndClass,
357 hInstance);
358 }