[CONSOLE.CPL]: Rewrite the way we deal with console font samples in the console prope...
[reactos.git] / reactos / dll / cpl / console / layout.c
1 /*
2 * PROJECT: ReactOS Console Configuration DLL
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: dll/cpl/console/layout.c
5 * PURPOSE: Layout dialog
6 * PROGRAMMERS: Johannes Anderwald (johannes.anderwald@reactos.org)
7 * Hermes Belusca-Maito (hermes.belusca@sfr.fr)
8 */
9
10 #include "console.h"
11
12 #define NDEBUG
13 #include <debug.h>
14
15 const WCHAR szPreviewText[] =
16 L"C:\\ReactOS> dir \n" \
17 L"SYSTEM <DIR> 13-04-15 5:00a\n" \
18 L"SYSTEM32 <DIR> 13-04-15 5:00a\n" \
19 L"readme txt 1739 13-04-15 5:00a\n" \
20 L"explorer exe 3329536 13-04-15 5:00a\n" \
21 L"vgafonts cab 18736 13-04-15 5:00a\n" \
22 L"setuplog txt 313 13-04-15 5:00a\n" \
23 L"win ini 7005 13-04-15 5:00a\n" ;
24
25
26 VOID
27 PaintConsole(
28 IN LPDRAWITEMSTRUCT drawItem,
29 IN PCONSOLE_STATE_INFO pConInfo)
30 {
31 HBRUSH hBrush;
32 RECT cRect, fRect;
33 DWORD startx, starty;
34 DWORD endx, endy;
35 DWORD sizex, sizey;
36
37 FillRect(drawItem->hDC, &drawItem->rcItem, GetSysColorBrush(COLOR_BACKGROUND));
38
39 // FIXME: Use: SM_CXSIZE, SM_CYSIZE, SM_CXVSCROLL, SM_CYHSCROLL, SM_CXMIN, SM_CYMIN, SM_CXFRAME, SM_CYFRAME
40 /* Use it for scaling */
41 sizex = drawItem->rcItem.right - drawItem->rcItem.left;
42 sizey = drawItem->rcItem.bottom - drawItem->rcItem.top ;
43
44 if ( pConInfo->WindowPosition.x == MAXDWORD &&
45 pConInfo->WindowPosition.y == MAXDWORD )
46 {
47 startx = sizex / 3;
48 starty = sizey / 3;
49 }
50 else
51 {
52 // TODO:
53 // Calculate pos correctly when console centered
54 startx = pConInfo->WindowPosition.x;
55 starty = pConInfo->WindowPosition.y;
56 }
57
58 // TODO:
59 // Stretch console when bold fonts are selected
60 endx = startx + pConInfo->WindowSize.X; // drawItem->rcItem.right - startx + 15;
61 endy = starty + pConInfo->WindowSize.Y; // starty + sizey / 3;
62
63 /* Draw console size */
64 SetRect(&cRect, startx, starty, endx, endy);
65 FillRect(drawItem->hDC, &cRect, GetSysColorBrush(COLOR_WINDOWFRAME));
66
67 /* Draw console border */
68 SetRect(&fRect, startx + 1, starty + 1, cRect.right - 1, cRect.bottom - 1);
69 FrameRect(drawItem->hDC, &fRect, GetSysColorBrush(COLOR_ACTIVEBORDER));
70
71 /* Draw left box */
72 SetRect(&fRect, startx + 3, starty + 3, startx + 5, starty + 5);
73 FillRect(drawItem->hDC, &fRect, GetSysColorBrush(COLOR_ACTIVEBORDER));
74
75 /* Draw window title */
76 SetRect(&fRect, startx + 7, starty + 3, cRect.right - 9, starty + 5);
77 FillRect(drawItem->hDC, &fRect, GetSysColorBrush(COLOR_ACTIVECAPTION));
78
79 /* Draw first right box */
80 SetRect(&fRect, fRect.right + 1, starty + 3, fRect.right + 3, starty + 5);
81 FillRect(drawItem->hDC, &fRect, GetSysColorBrush(COLOR_ACTIVEBORDER));
82
83 /* Draw second right box */
84 SetRect(&fRect, fRect.right + 1, starty + 3, fRect.right + 3, starty + 5);
85 FillRect(drawItem->hDC, &fRect, GetSysColorBrush(COLOR_ACTIVEBORDER));
86
87 /* Draw scrollbar */
88 SetRect(&fRect, cRect.right - 5, fRect.bottom + 1, cRect.right - 3, cRect.bottom - 3);
89 FillRect(drawItem->hDC, &fRect, GetSysColorBrush(COLOR_SCROLLBAR));
90
91 /* Draw console background */
92 hBrush = CreateSolidBrush(pConInfo->ColorTable[BkgdAttribFromAttrib(pConInfo->ScreenAttributes)]);
93 SetRect(&fRect, startx + 3, starty + 6, cRect.right - 6, cRect.bottom - 3);
94 FillRect(drawItem->hDC, &fRect, hBrush);
95 DeleteObject(hBrush);
96 }
97
98 BOOL
99 PaintText(
100 IN LPDRAWITEMSTRUCT drawItem,
101 IN PCONSOLE_STATE_INFO pConInfo,
102 IN TEXT_TYPE TextMode)
103 {
104 USHORT CurrentAttrib;
105 COLORREF pbkColor, ptColor;
106 COLORREF nbkColor, ntColor;
107 HBRUSH hBrush;
108 HFONT hOldFont;
109
110 if (TextMode == Screen)
111 CurrentAttrib = pConInfo->ScreenAttributes;
112 else if (TextMode == Popup)
113 CurrentAttrib = pConInfo->PopupAttributes;
114 else
115 return FALSE;
116
117 nbkColor = pConInfo->ColorTable[BkgdAttribFromAttrib(CurrentAttrib)];
118 ntColor = pConInfo->ColorTable[TextAttribFromAttrib(CurrentAttrib)];
119
120 hBrush = CreateSolidBrush(nbkColor);
121 if (!hBrush) return FALSE;
122
123 hOldFont = SelectObject(drawItem->hDC, hCurrentFont);
124 //if (hOldFont == NULL)
125 //{
126 // DeleteObject(hBrush);
127 // return FALSE;
128 //}
129
130 FillRect(drawItem->hDC, &drawItem->rcItem, hBrush);
131
132 ptColor = SetTextColor(drawItem->hDC, ntColor);
133 pbkColor = SetBkColor(drawItem->hDC, nbkColor);
134 DrawTextW(drawItem->hDC, szPreviewText, wcslen(szPreviewText), &drawItem->rcItem, 0);
135 SetTextColor(drawItem->hDC, ptColor);
136 SetBkColor(drawItem->hDC, pbkColor);
137
138 SelectObject(drawItem->hDC, hOldFont);
139
140 DeleteObject(hBrush);
141
142 return TRUE;
143 }
144
145 INT_PTR
146 CALLBACK
147 LayoutProc(HWND hwndDlg,
148 UINT uMsg,
149 WPARAM wParam,
150 LPARAM lParam)
151 {
152 switch (uMsg)
153 {
154 case WM_INITDIALOG:
155 {
156 /* Multi-monitor support */
157 LONG xVirtScr, yVirtScr; // Coordinates of the top-left virtual screen
158 LONG cxVirtScr, cyVirtScr; // Width and Height of the virtual screen
159 LONG cxFrame , cyFrame ; // Thickness of the window frame
160
161 /* Multi-monitor support */
162 xVirtScr = GetSystemMetrics(SM_XVIRTUALSCREEN);
163 yVirtScr = GetSystemMetrics(SM_YVIRTUALSCREEN);
164 cxVirtScr = GetSystemMetrics(SM_CXVIRTUALSCREEN);
165 cyVirtScr = GetSystemMetrics(SM_CYVIRTUALSCREEN);
166 cxFrame = GetSystemMetrics(SM_CXFRAME);
167 cyFrame = GetSystemMetrics(SM_CYFRAME);
168
169 SendDlgItemMessageW(hwndDlg, IDC_UPDOWN_SCREEN_BUFFER_HEIGHT, UDM_SETRANGE, 0, (LPARAM)MAKELONG(9999, 1));
170 SendDlgItemMessageW(hwndDlg, IDC_UPDOWN_SCREEN_BUFFER_WIDTH , UDM_SETRANGE, 0, (LPARAM)MAKELONG(9999, 1));
171 SendDlgItemMessageW(hwndDlg, IDC_UPDOWN_WINDOW_SIZE_HEIGHT, UDM_SETRANGE, 0, (LPARAM)MAKELONG(9999, 1));
172 SendDlgItemMessageW(hwndDlg, IDC_UPDOWN_WINDOW_SIZE_WIDTH , UDM_SETRANGE, 0, (LPARAM)MAKELONG(9999, 1));
173
174 SetDlgItemInt(hwndDlg, IDC_EDIT_SCREEN_BUFFER_HEIGHT, ConInfo->ScreenBufferSize.Y, FALSE);
175 SetDlgItemInt(hwndDlg, IDC_EDIT_SCREEN_BUFFER_WIDTH , ConInfo->ScreenBufferSize.X, FALSE);
176 SetDlgItemInt(hwndDlg, IDC_EDIT_WINDOW_SIZE_HEIGHT, ConInfo->WindowSize.Y, FALSE);
177 SetDlgItemInt(hwndDlg, IDC_EDIT_WINDOW_SIZE_WIDTH , ConInfo->WindowSize.X, FALSE);
178
179 SendDlgItemMessageW(hwndDlg, IDC_UPDOWN_WINDOW_POS_LEFT, UDM_SETRANGE, 0,
180 (LPARAM)MAKELONG(xVirtScr + cxVirtScr - cxFrame, xVirtScr - cxFrame));
181 SendDlgItemMessageW(hwndDlg, IDC_UPDOWN_WINDOW_POS_TOP , UDM_SETRANGE, 0,
182 (LPARAM)MAKELONG(yVirtScr + cyVirtScr - cyFrame, yVirtScr - cyFrame));
183
184 SetDlgItemInt(hwndDlg, IDC_EDIT_WINDOW_POS_LEFT, ConInfo->WindowPosition.x, TRUE);
185 SetDlgItemInt(hwndDlg, IDC_EDIT_WINDOW_POS_TOP , ConInfo->WindowPosition.y, TRUE);
186
187 if (ConInfo->AutoPosition)
188 {
189 EnableDlgItem(hwndDlg, IDC_EDIT_WINDOW_POS_LEFT, FALSE);
190 EnableDlgItem(hwndDlg, IDC_EDIT_WINDOW_POS_TOP , FALSE);
191 EnableDlgItem(hwndDlg, IDC_UPDOWN_WINDOW_POS_LEFT, FALSE);
192 EnableDlgItem(hwndDlg, IDC_UPDOWN_WINDOW_POS_TOP , FALSE);
193 }
194 CheckDlgButton(hwndDlg, IDC_CHECK_SYSTEM_POS_WINDOW,
195 ConInfo->AutoPosition ? BST_CHECKED : BST_UNCHECKED);
196
197 return TRUE;
198 }
199
200 case WM_DRAWITEM:
201 {
202 PaintConsole((LPDRAWITEMSTRUCT)lParam, ConInfo);
203 return TRUE;
204 }
205
206 case WM_NOTIFY:
207 {
208 LPPSHNOTIFY lppsn = (LPPSHNOTIFY)lParam;
209
210 if (lppsn->hdr.code == UDN_DELTAPOS)
211 {
212 LPNMUPDOWN lpnmud = (LPNMUPDOWN)lParam;
213 DWORD wheight, wwidth;
214 DWORD sheight, swidth;
215 DWORD left, top;
216
217 if (lppsn->hdr.idFrom == IDC_UPDOWN_WINDOW_SIZE_WIDTH)
218 {
219 wwidth = lpnmud->iPos + lpnmud->iDelta;
220 }
221 else
222 {
223 wwidth = GetDlgItemInt(hwndDlg, IDC_EDIT_WINDOW_SIZE_WIDTH, NULL, FALSE);
224 }
225
226 if (lppsn->hdr.idFrom == IDC_UPDOWN_WINDOW_SIZE_HEIGHT)
227 {
228 wheight = lpnmud->iPos + lpnmud->iDelta;
229 }
230 else
231 {
232 wheight = GetDlgItemInt(hwndDlg, IDC_EDIT_WINDOW_SIZE_HEIGHT, NULL, FALSE);
233 }
234
235 if (lppsn->hdr.idFrom == IDC_UPDOWN_SCREEN_BUFFER_WIDTH)
236 {
237 swidth = lpnmud->iPos + lpnmud->iDelta;
238 }
239 else
240 {
241 swidth = GetDlgItemInt(hwndDlg, IDC_EDIT_SCREEN_BUFFER_WIDTH, NULL, FALSE);
242 }
243
244 if (lppsn->hdr.idFrom == IDC_UPDOWN_SCREEN_BUFFER_HEIGHT)
245 {
246 sheight = lpnmud->iPos + lpnmud->iDelta;
247 }
248 else
249 {
250 sheight = GetDlgItemInt(hwndDlg, IDC_EDIT_SCREEN_BUFFER_HEIGHT, NULL, FALSE);
251 }
252
253 if (lppsn->hdr.idFrom == IDC_UPDOWN_WINDOW_POS_LEFT)
254 {
255 left = lpnmud->iPos + lpnmud->iDelta;
256 }
257 else
258 {
259 left = GetDlgItemInt(hwndDlg, IDC_EDIT_WINDOW_POS_LEFT, NULL, TRUE);
260 }
261
262 if (lppsn->hdr.idFrom == IDC_UPDOWN_WINDOW_POS_TOP)
263 {
264 top = lpnmud->iPos + lpnmud->iDelta;
265 }
266 else
267 {
268 top = GetDlgItemInt(hwndDlg, IDC_EDIT_WINDOW_POS_TOP, NULL, TRUE);
269 }
270
271 if (lppsn->hdr.idFrom == IDC_UPDOWN_WINDOW_SIZE_WIDTH || lppsn->hdr.idFrom == IDC_UPDOWN_WINDOW_SIZE_HEIGHT)
272 {
273 /* Automatically adjust screen buffer size when window size enlarges */
274 if (wwidth >= swidth)
275 {
276 SetDlgItemInt(hwndDlg, IDC_EDIT_SCREEN_BUFFER_WIDTH, wwidth, TRUE);
277 swidth = wwidth;
278 }
279 if (wheight >= sheight)
280 {
281 SetDlgItemInt(hwndDlg, IDC_EDIT_SCREEN_BUFFER_HEIGHT, wheight, TRUE);
282 sheight = wheight;
283 }
284 }
285
286 /* Be sure that the (new) screen buffer sizes are in the correct range */
287 swidth = min(max(swidth , 1), 0xFFFF);
288 sheight = min(max(sheight, 1), 0xFFFF);
289
290 if (lppsn->hdr.idFrom == IDC_UPDOWN_SCREEN_BUFFER_WIDTH || lppsn->hdr.idFrom == IDC_UPDOWN_SCREEN_BUFFER_HEIGHT)
291 {
292 /* Automatically adjust window size when screen buffer decreases */
293 if (wwidth > swidth)
294 {
295 SetDlgItemInt(hwndDlg, IDC_EDIT_WINDOW_SIZE_WIDTH, swidth, TRUE);
296 wwidth = swidth;
297 }
298 if (wheight > sheight)
299 {
300 SetDlgItemInt(hwndDlg, IDC_EDIT_WINDOW_SIZE_HEIGHT, sheight, TRUE);
301 wheight = sheight;
302 }
303 }
304
305 ConInfo->ScreenBufferSize.X = (SHORT)swidth;
306 ConInfo->ScreenBufferSize.Y = (SHORT)sheight;
307 ConInfo->WindowSize.X = (SHORT)wwidth;
308 ConInfo->WindowSize.Y = (SHORT)wheight;
309 ConInfo->WindowPosition.x = left;
310 ConInfo->WindowPosition.y = top;
311 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
312 }
313 break;
314 }
315
316 case WM_COMMAND:
317 {
318 if (HIWORD(wParam) == EN_KILLFOCUS)
319 {
320 switch (LOWORD(wParam))
321 {
322 case IDC_EDIT_SCREEN_BUFFER_WIDTH:
323 {
324 DWORD swidth, wwidth;
325
326 swidth = GetDlgItemInt(hwndDlg, IDC_EDIT_SCREEN_BUFFER_WIDTH, NULL, FALSE);
327 wwidth = GetDlgItemInt(hwndDlg, IDC_EDIT_WINDOW_SIZE_WIDTH , NULL, FALSE);
328
329 /* Be sure that the (new) screen buffer width is in the correct range */
330 swidth = min(max(swidth, 1), 0xFFFF);
331
332 /* Automatically adjust window size when screen buffer decreases */
333 if (wwidth > swidth)
334 {
335 wwidth = swidth;
336 SetDlgItemInt(hwndDlg, IDC_EDIT_WINDOW_SIZE_WIDTH, wwidth, TRUE);
337 }
338
339 ConInfo->ScreenBufferSize.X = (SHORT)swidth;
340 ConInfo->WindowSize.X = (SHORT)wwidth;
341 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
342 break;
343 }
344
345 case IDC_EDIT_WINDOW_SIZE_WIDTH:
346 {
347 DWORD swidth, wwidth;
348
349 swidth = GetDlgItemInt(hwndDlg, IDC_EDIT_SCREEN_BUFFER_WIDTH, NULL, FALSE);
350 wwidth = GetDlgItemInt(hwndDlg, IDC_EDIT_WINDOW_SIZE_WIDTH , NULL, FALSE);
351
352 /* Automatically adjust screen buffer size when window size enlarges */
353 if (wwidth >= swidth)
354 {
355 swidth = wwidth;
356
357 /* Be sure that the (new) screen buffer width is in the correct range */
358 swidth = min(max(swidth, 1), 0xFFFF);
359
360 SetDlgItemInt(hwndDlg, IDC_EDIT_SCREEN_BUFFER_WIDTH, swidth, TRUE);
361 }
362
363 ConInfo->ScreenBufferSize.X = (SHORT)swidth;
364 ConInfo->WindowSize.X = (SHORT)wwidth;
365 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
366 break;
367 }
368
369 case IDC_EDIT_SCREEN_BUFFER_HEIGHT:
370 {
371 DWORD sheight, wheight;
372
373 sheight = GetDlgItemInt(hwndDlg, IDC_EDIT_SCREEN_BUFFER_HEIGHT, NULL, FALSE);
374 wheight = GetDlgItemInt(hwndDlg, IDC_EDIT_WINDOW_SIZE_HEIGHT , NULL, FALSE);
375
376 /* Be sure that the (new) screen buffer width is in the correct range */
377 sheight = min(max(sheight, 1), 0xFFFF);
378
379 /* Automatically adjust window size when screen buffer decreases */
380 if (wheight > sheight)
381 {
382 wheight = sheight;
383 SetDlgItemInt(hwndDlg, IDC_EDIT_WINDOW_SIZE_HEIGHT, wheight, TRUE);
384 }
385
386 ConInfo->ScreenBufferSize.Y = (SHORT)sheight;
387 ConInfo->WindowSize.Y = (SHORT)wheight;
388 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
389 break;
390 }
391
392 case IDC_EDIT_WINDOW_SIZE_HEIGHT:
393 {
394 DWORD sheight, wheight;
395
396 sheight = GetDlgItemInt(hwndDlg, IDC_EDIT_SCREEN_BUFFER_HEIGHT, NULL, FALSE);
397 wheight = GetDlgItemInt(hwndDlg, IDC_EDIT_WINDOW_SIZE_HEIGHT , NULL, FALSE);
398
399 /* Automatically adjust screen buffer size when window size enlarges */
400 if (wheight >= sheight)
401 {
402 sheight = wheight;
403
404 /* Be sure that the (new) screen buffer width is in the correct range */
405 sheight = min(max(sheight, 1), 0xFFFF);
406
407 SetDlgItemInt(hwndDlg, IDC_EDIT_SCREEN_BUFFER_HEIGHT, sheight, TRUE);
408 }
409
410 ConInfo->ScreenBufferSize.Y = (SHORT)sheight;
411 ConInfo->WindowSize.Y = (SHORT)wheight;
412 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
413 break;
414 }
415
416 case IDC_EDIT_WINDOW_POS_LEFT:
417 case IDC_EDIT_WINDOW_POS_TOP:
418 {
419 ConInfo->WindowPosition.x = GetDlgItemInt(hwndDlg, IDC_EDIT_WINDOW_POS_LEFT, NULL, TRUE);
420 ConInfo->WindowPosition.y = GetDlgItemInt(hwndDlg, IDC_EDIT_WINDOW_POS_TOP , NULL, TRUE);
421 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
422 break;
423 }
424 }
425 }
426 else
427 if (HIWORD(wParam) == BN_CLICKED &&
428 LOWORD(wParam) == IDC_CHECK_SYSTEM_POS_WINDOW)
429 {
430 if (IsDlgButtonChecked(hwndDlg, IDC_CHECK_SYSTEM_POS_WINDOW) == BST_CHECKED)
431 {
432 EnableDlgItem(hwndDlg, IDC_EDIT_WINDOW_POS_LEFT, FALSE);
433 EnableDlgItem(hwndDlg, IDC_EDIT_WINDOW_POS_TOP , FALSE);
434 EnableDlgItem(hwndDlg, IDC_UPDOWN_WINDOW_POS_LEFT, FALSE);
435 EnableDlgItem(hwndDlg, IDC_UPDOWN_WINDOW_POS_TOP , FALSE);
436
437 ConInfo->AutoPosition = TRUE;
438 // Do not touch ConInfo->WindowPosition !!
439 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
440 }
441 else
442 {
443 ULONG left, top;
444
445 left = GetDlgItemInt(hwndDlg, IDC_EDIT_WINDOW_POS_LEFT, NULL, TRUE);
446 top = GetDlgItemInt(hwndDlg, IDC_EDIT_WINDOW_POS_TOP , NULL, TRUE);
447
448 EnableDlgItem(hwndDlg, IDC_EDIT_WINDOW_POS_LEFT, TRUE);
449 EnableDlgItem(hwndDlg, IDC_EDIT_WINDOW_POS_TOP , TRUE);
450 EnableDlgItem(hwndDlg, IDC_UPDOWN_WINDOW_POS_LEFT, TRUE);
451 EnableDlgItem(hwndDlg, IDC_UPDOWN_WINDOW_POS_TOP , TRUE);
452
453 ConInfo->AutoPosition = FALSE;
454 ConInfo->WindowPosition.x = left;
455 ConInfo->WindowPosition.y = top;
456 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
457 }
458 }
459
460 break;
461 }
462
463 default:
464 break;
465 }
466
467 return FALSE;
468 }