cf92b5d6d7ab4985942e6fe8e84e9a7e75b86b3f
[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 Font, OldFont;
109
110 COORD FontSize = pConInfo->FontSize;
111
112 if (TextMode == Screen)
113 CurrentAttrib = pConInfo->ScreenAttributes;
114 else if (TextMode == Popup)
115 CurrentAttrib = pConInfo->PopupAttributes;
116 else
117 return FALSE;
118
119 nbkColor = pConInfo->ColorTable[BkgdAttribFromAttrib(CurrentAttrib)];
120 ntColor = pConInfo->ColorTable[TextAttribFromAttrib(CurrentAttrib)];
121
122 hBrush = CreateSolidBrush(nbkColor);
123 if (!hBrush) return FALSE;
124
125 FontSize.Y = FontSize.Y > 0 ? -MulDiv(FontSize.Y, GetDeviceCaps(drawItem->hDC, LOGPIXELSY), 72)
126 : FontSize.Y;
127
128 Font = CreateFontW(FontSize.Y,
129 FontSize.X,
130 0,
131 TA_BASELINE,
132 pConInfo->FontWeight,
133 FALSE,
134 FALSE,
135 FALSE,
136 CodePageToCharSet(pConInfo->CodePage),
137 OUT_DEFAULT_PRECIS,
138 CLIP_DEFAULT_PRECIS,
139 DEFAULT_QUALITY,
140 FIXED_PITCH | pConInfo->FontFamily,
141 pConInfo->FaceName);
142 if (Font == NULL)
143 {
144 DPRINT1("PaintText: CreateFont failed\n");
145 DeleteObject(hBrush);
146 return FALSE;
147 }
148
149 OldFont = SelectObject(drawItem->hDC, Font);
150 if (OldFont == NULL)
151 {
152 DeleteObject(Font);
153 DeleteObject(hBrush);
154 return FALSE;
155 }
156
157 FillRect(drawItem->hDC, &drawItem->rcItem, hBrush);
158
159 ptColor = SetTextColor(drawItem->hDC, ntColor);
160 pbkColor = SetBkColor(drawItem->hDC, nbkColor);
161 DrawTextW(drawItem->hDC, szPreviewText, wcslen(szPreviewText), &drawItem->rcItem, 0);
162 SetTextColor(drawItem->hDC, ptColor);
163 SetBkColor(drawItem->hDC, pbkColor);
164 DeleteObject(hBrush);
165
166 SelectObject(drawItem->hDC, OldFont);
167 DeleteObject(Font);
168
169 return TRUE;
170 }
171
172 INT_PTR
173 CALLBACK
174 LayoutProc(HWND hwndDlg,
175 UINT uMsg,
176 WPARAM wParam,
177 LPARAM lParam)
178 {
179 switch (uMsg)
180 {
181 case WM_INITDIALOG:
182 {
183 /* Multi-monitor support */
184 LONG xVirtScr, yVirtScr; // Coordinates of the top-left virtual screen
185 LONG cxVirtScr, cyVirtScr; // Width and Height of the virtual screen
186 LONG cxFrame , cyFrame ; // Thickness of the window frame
187
188 /* Multi-monitor support */
189 xVirtScr = GetSystemMetrics(SM_XVIRTUALSCREEN);
190 yVirtScr = GetSystemMetrics(SM_YVIRTUALSCREEN);
191 cxVirtScr = GetSystemMetrics(SM_CXVIRTUALSCREEN);
192 cyVirtScr = GetSystemMetrics(SM_CYVIRTUALSCREEN);
193 cxFrame = GetSystemMetrics(SM_CXFRAME);
194 cyFrame = GetSystemMetrics(SM_CYFRAME);
195
196 SendDlgItemMessageW(hwndDlg, IDC_UPDOWN_SCREEN_BUFFER_HEIGHT, UDM_SETRANGE, 0, (LPARAM)MAKELONG(9999, 1));
197 SendDlgItemMessageW(hwndDlg, IDC_UPDOWN_SCREEN_BUFFER_WIDTH , UDM_SETRANGE, 0, (LPARAM)MAKELONG(9999, 1));
198 SendDlgItemMessageW(hwndDlg, IDC_UPDOWN_WINDOW_SIZE_HEIGHT, UDM_SETRANGE, 0, (LPARAM)MAKELONG(9999, 1));
199 SendDlgItemMessageW(hwndDlg, IDC_UPDOWN_WINDOW_SIZE_WIDTH , UDM_SETRANGE, 0, (LPARAM)MAKELONG(9999, 1));
200
201 SetDlgItemInt(hwndDlg, IDC_EDIT_SCREEN_BUFFER_HEIGHT, ConInfo->ScreenBufferSize.Y, FALSE);
202 SetDlgItemInt(hwndDlg, IDC_EDIT_SCREEN_BUFFER_WIDTH , ConInfo->ScreenBufferSize.X, FALSE);
203 SetDlgItemInt(hwndDlg, IDC_EDIT_WINDOW_SIZE_HEIGHT, ConInfo->WindowSize.Y, FALSE);
204 SetDlgItemInt(hwndDlg, IDC_EDIT_WINDOW_SIZE_WIDTH , ConInfo->WindowSize.X, FALSE);
205
206 SendDlgItemMessageW(hwndDlg, IDC_UPDOWN_WINDOW_POS_LEFT, UDM_SETRANGE, 0,
207 (LPARAM)MAKELONG(xVirtScr + cxVirtScr - cxFrame, xVirtScr - cxFrame));
208 SendDlgItemMessageW(hwndDlg, IDC_UPDOWN_WINDOW_POS_TOP , UDM_SETRANGE, 0,
209 (LPARAM)MAKELONG(yVirtScr + cyVirtScr - cyFrame, yVirtScr - cyFrame));
210
211 SetDlgItemInt(hwndDlg, IDC_EDIT_WINDOW_POS_LEFT, ConInfo->WindowPosition.x, TRUE);
212 SetDlgItemInt(hwndDlg, IDC_EDIT_WINDOW_POS_TOP , ConInfo->WindowPosition.y, TRUE);
213
214 if (ConInfo->AutoPosition)
215 {
216 EnableDlgItem(hwndDlg, IDC_EDIT_WINDOW_POS_LEFT, FALSE);
217 EnableDlgItem(hwndDlg, IDC_EDIT_WINDOW_POS_TOP , FALSE);
218 EnableDlgItem(hwndDlg, IDC_UPDOWN_WINDOW_POS_LEFT, FALSE);
219 EnableDlgItem(hwndDlg, IDC_UPDOWN_WINDOW_POS_TOP , FALSE);
220 }
221 CheckDlgButton(hwndDlg, IDC_CHECK_SYSTEM_POS_WINDOW,
222 ConInfo->AutoPosition ? BST_CHECKED : BST_UNCHECKED);
223
224 return TRUE;
225 }
226
227 case WM_DRAWITEM:
228 {
229 PaintConsole((LPDRAWITEMSTRUCT)lParam, ConInfo);
230 return TRUE;
231 }
232
233 case WM_NOTIFY:
234 {
235 LPPSHNOTIFY lppsn = (LPPSHNOTIFY)lParam;
236
237 if (lppsn->hdr.code == UDN_DELTAPOS)
238 {
239 LPNMUPDOWN lpnmud = (LPNMUPDOWN)lParam;
240 DWORD wheight, wwidth;
241 DWORD sheight, swidth;
242 DWORD left, top;
243
244 if (lppsn->hdr.idFrom == IDC_UPDOWN_WINDOW_SIZE_WIDTH)
245 {
246 wwidth = lpnmud->iPos + lpnmud->iDelta;
247 }
248 else
249 {
250 wwidth = GetDlgItemInt(hwndDlg, IDC_EDIT_WINDOW_SIZE_WIDTH, NULL, FALSE);
251 }
252
253 if (lppsn->hdr.idFrom == IDC_UPDOWN_WINDOW_SIZE_HEIGHT)
254 {
255 wheight = lpnmud->iPos + lpnmud->iDelta;
256 }
257 else
258 {
259 wheight = GetDlgItemInt(hwndDlg, IDC_EDIT_WINDOW_SIZE_HEIGHT, NULL, FALSE);
260 }
261
262 if (lppsn->hdr.idFrom == IDC_UPDOWN_SCREEN_BUFFER_WIDTH)
263 {
264 swidth = lpnmud->iPos + lpnmud->iDelta;
265 }
266 else
267 {
268 swidth = GetDlgItemInt(hwndDlg, IDC_EDIT_SCREEN_BUFFER_WIDTH, NULL, FALSE);
269 }
270
271 if (lppsn->hdr.idFrom == IDC_UPDOWN_SCREEN_BUFFER_HEIGHT)
272 {
273 sheight = lpnmud->iPos + lpnmud->iDelta;
274 }
275 else
276 {
277 sheight = GetDlgItemInt(hwndDlg, IDC_EDIT_SCREEN_BUFFER_HEIGHT, NULL, FALSE);
278 }
279
280 if (lppsn->hdr.idFrom == IDC_UPDOWN_WINDOW_POS_LEFT)
281 {
282 left = lpnmud->iPos + lpnmud->iDelta;
283 }
284 else
285 {
286 left = GetDlgItemInt(hwndDlg, IDC_EDIT_WINDOW_POS_LEFT, NULL, TRUE);
287 }
288
289 if (lppsn->hdr.idFrom == IDC_UPDOWN_WINDOW_POS_TOP)
290 {
291 top = lpnmud->iPos + lpnmud->iDelta;
292 }
293 else
294 {
295 top = GetDlgItemInt(hwndDlg, IDC_EDIT_WINDOW_POS_TOP, NULL, TRUE);
296 }
297
298 if (lppsn->hdr.idFrom == IDC_UPDOWN_WINDOW_SIZE_WIDTH || lppsn->hdr.idFrom == IDC_UPDOWN_WINDOW_SIZE_HEIGHT)
299 {
300 /* Automatically adjust screen buffer size when window size enlarges */
301 if (wwidth >= swidth)
302 {
303 SetDlgItemInt(hwndDlg, IDC_EDIT_SCREEN_BUFFER_WIDTH, wwidth, TRUE);
304 swidth = wwidth;
305 }
306 if (wheight >= sheight)
307 {
308 SetDlgItemInt(hwndDlg, IDC_EDIT_SCREEN_BUFFER_HEIGHT, wheight, TRUE);
309 sheight = wheight;
310 }
311 }
312
313 /* Be sure that the (new) screen buffer sizes are in the correct range */
314 swidth = min(max(swidth , 1), 0xFFFF);
315 sheight = min(max(sheight, 1), 0xFFFF);
316
317 if (lppsn->hdr.idFrom == IDC_UPDOWN_SCREEN_BUFFER_WIDTH || lppsn->hdr.idFrom == IDC_UPDOWN_SCREEN_BUFFER_HEIGHT)
318 {
319 /* Automatically adjust window size when screen buffer decreases */
320 if (wwidth > swidth)
321 {
322 SetDlgItemInt(hwndDlg, IDC_EDIT_WINDOW_SIZE_WIDTH, swidth, TRUE);
323 wwidth = swidth;
324 }
325 if (wheight > sheight)
326 {
327 SetDlgItemInt(hwndDlg, IDC_EDIT_WINDOW_SIZE_HEIGHT, sheight, TRUE);
328 wheight = sheight;
329 }
330 }
331
332 ConInfo->ScreenBufferSize.X = (SHORT)swidth;
333 ConInfo->ScreenBufferSize.Y = (SHORT)sheight;
334 ConInfo->WindowSize.X = (SHORT)wwidth;
335 ConInfo->WindowSize.Y = (SHORT)wheight;
336 ConInfo->WindowPosition.x = left;
337 ConInfo->WindowPosition.y = top;
338 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
339 }
340 break;
341 }
342
343 case WM_COMMAND:
344 {
345 if (HIWORD(wParam) == EN_KILLFOCUS)
346 {
347 switch (LOWORD(wParam))
348 {
349 case IDC_EDIT_SCREEN_BUFFER_WIDTH:
350 {
351 DWORD swidth, wwidth;
352
353 swidth = GetDlgItemInt(hwndDlg, IDC_EDIT_SCREEN_BUFFER_WIDTH, NULL, FALSE);
354 wwidth = GetDlgItemInt(hwndDlg, IDC_EDIT_WINDOW_SIZE_WIDTH , NULL, FALSE);
355
356 /* Be sure that the (new) screen buffer width is in the correct range */
357 swidth = min(max(swidth, 1), 0xFFFF);
358
359 /* Automatically adjust window size when screen buffer decreases */
360 if (wwidth > swidth)
361 {
362 wwidth = swidth;
363 SetDlgItemInt(hwndDlg, IDC_EDIT_WINDOW_SIZE_WIDTH, wwidth, TRUE);
364 }
365
366 ConInfo->ScreenBufferSize.X = (SHORT)swidth;
367 ConInfo->WindowSize.X = (SHORT)wwidth;
368 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
369 break;
370 }
371
372 case IDC_EDIT_WINDOW_SIZE_WIDTH:
373 {
374 DWORD swidth, wwidth;
375
376 swidth = GetDlgItemInt(hwndDlg, IDC_EDIT_SCREEN_BUFFER_WIDTH, NULL, FALSE);
377 wwidth = GetDlgItemInt(hwndDlg, IDC_EDIT_WINDOW_SIZE_WIDTH , NULL, FALSE);
378
379 /* Automatically adjust screen buffer size when window size enlarges */
380 if (wwidth >= swidth)
381 {
382 swidth = wwidth;
383
384 /* Be sure that the (new) screen buffer width is in the correct range */
385 swidth = min(max(swidth, 1), 0xFFFF);
386
387 SetDlgItemInt(hwndDlg, IDC_EDIT_SCREEN_BUFFER_WIDTH, swidth, TRUE);
388 }
389
390 ConInfo->ScreenBufferSize.X = (SHORT)swidth;
391 ConInfo->WindowSize.X = (SHORT)wwidth;
392 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
393 break;
394 }
395
396 case IDC_EDIT_SCREEN_BUFFER_HEIGHT:
397 {
398 DWORD sheight, wheight;
399
400 sheight = GetDlgItemInt(hwndDlg, IDC_EDIT_SCREEN_BUFFER_HEIGHT, NULL, FALSE);
401 wheight = GetDlgItemInt(hwndDlg, IDC_EDIT_WINDOW_SIZE_HEIGHT , NULL, FALSE);
402
403 /* Be sure that the (new) screen buffer width is in the correct range */
404 sheight = min(max(sheight, 1), 0xFFFF);
405
406 /* Automatically adjust window size when screen buffer decreases */
407 if (wheight > sheight)
408 {
409 wheight = sheight;
410 SetDlgItemInt(hwndDlg, IDC_EDIT_WINDOW_SIZE_HEIGHT, wheight, TRUE);
411 }
412
413 ConInfo->ScreenBufferSize.Y = (SHORT)sheight;
414 ConInfo->WindowSize.Y = (SHORT)wheight;
415 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
416 break;
417 }
418
419 case IDC_EDIT_WINDOW_SIZE_HEIGHT:
420 {
421 DWORD sheight, wheight;
422
423 sheight = GetDlgItemInt(hwndDlg, IDC_EDIT_SCREEN_BUFFER_HEIGHT, NULL, FALSE);
424 wheight = GetDlgItemInt(hwndDlg, IDC_EDIT_WINDOW_SIZE_HEIGHT , NULL, FALSE);
425
426 /* Automatically adjust screen buffer size when window size enlarges */
427 if (wheight >= sheight)
428 {
429 sheight = wheight;
430
431 /* Be sure that the (new) screen buffer width is in the correct range */
432 sheight = min(max(sheight, 1), 0xFFFF);
433
434 SetDlgItemInt(hwndDlg, IDC_EDIT_SCREEN_BUFFER_HEIGHT, sheight, TRUE);
435 }
436
437 ConInfo->ScreenBufferSize.Y = (SHORT)sheight;
438 ConInfo->WindowSize.Y = (SHORT)wheight;
439 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
440 break;
441 }
442
443 case IDC_EDIT_WINDOW_POS_LEFT:
444 case IDC_EDIT_WINDOW_POS_TOP:
445 {
446 ConInfo->WindowPosition.x = GetDlgItemInt(hwndDlg, IDC_EDIT_WINDOW_POS_LEFT, NULL, TRUE);
447 ConInfo->WindowPosition.y = GetDlgItemInt(hwndDlg, IDC_EDIT_WINDOW_POS_TOP , NULL, TRUE);
448 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
449 break;
450 }
451 }
452 }
453 else
454 if (HIWORD(wParam) == BN_CLICKED &&
455 LOWORD(wParam) == IDC_CHECK_SYSTEM_POS_WINDOW)
456 {
457 if (IsDlgButtonChecked(hwndDlg, IDC_CHECK_SYSTEM_POS_WINDOW) == BST_CHECKED)
458 {
459 EnableDlgItem(hwndDlg, IDC_EDIT_WINDOW_POS_LEFT, FALSE);
460 EnableDlgItem(hwndDlg, IDC_EDIT_WINDOW_POS_TOP , FALSE);
461 EnableDlgItem(hwndDlg, IDC_UPDOWN_WINDOW_POS_LEFT, FALSE);
462 EnableDlgItem(hwndDlg, IDC_UPDOWN_WINDOW_POS_TOP , FALSE);
463
464 ConInfo->AutoPosition = TRUE;
465 // Do not touch ConInfo->WindowPosition !!
466 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
467 }
468 else
469 {
470 ULONG left, top;
471
472 left = GetDlgItemInt(hwndDlg, IDC_EDIT_WINDOW_POS_LEFT, NULL, TRUE);
473 top = GetDlgItemInt(hwndDlg, IDC_EDIT_WINDOW_POS_TOP , NULL, TRUE);
474
475 EnableDlgItem(hwndDlg, IDC_EDIT_WINDOW_POS_LEFT, TRUE);
476 EnableDlgItem(hwndDlg, IDC_EDIT_WINDOW_POS_TOP , TRUE);
477 EnableDlgItem(hwndDlg, IDC_UPDOWN_WINDOW_POS_LEFT, TRUE);
478 EnableDlgItem(hwndDlg, IDC_UPDOWN_WINDOW_POS_TOP , TRUE);
479
480 ConInfo->AutoPosition = FALSE;
481 ConInfo->WindowPosition.x = left;
482 ConInfo->WindowPosition.y = top;
483 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
484 }
485 }
486
487 break;
488 }
489
490 default:
491 break;
492 }
493
494 return FALSE;
495 }