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 /* CONSOLE WINDOW PREVIEW Control *********************************************/ 16 17 #define WIN_PREVIEW_CLASS L"WinPreview" 18 19 typedef struct _WINPREV_DATA 20 { 21 HWND hWnd; // The window which this structure refers to 22 RECT rcMaxArea; // Maximum rectangle in which the preview window can be sized 23 SIZE siPreview; // Actual size of the preview window 24 SIZE siVirtScr; // Width and Height of the virtual screen 25 PVOID pData; // Private data 26 } WINPREV_DATA, *PWINPREV_DATA; 27 28 static LRESULT CALLBACK 29 WinPrevProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); 30 31 BOOL 32 RegisterWinPrevClass( 33 IN HINSTANCE hInstance) 34 { 35 WNDCLASSW WndClass; 36 37 WndClass.lpszClassName = WIN_PREVIEW_CLASS; 38 WndClass.lpfnWndProc = WinPrevProc; 39 WndClass.style = 0; 40 WndClass.hInstance = hInstance; 41 WndClass.hIcon = NULL; 42 WndClass.hCursor = LoadCursorW(NULL, MAKEINTRESOURCEW(IDC_ARROW)); 43 WndClass.hbrBackground = (HBRUSH)(COLOR_BACKGROUND + 1); 44 WndClass.lpszMenuName = NULL; 45 WndClass.cbClsExtra = 0; 46 WndClass.cbWndExtra = 0; // sizeof(PWINPREV_DATA); 47 48 return (RegisterClassW(&WndClass) != 0); 49 } 50 51 BOOL 52 UnRegisterWinPrevClass( 53 IN HINSTANCE hInstance) 54 { 55 return UnregisterClassW(WIN_PREVIEW_CLASS, hInstance); 56 } 57 58 static VOID 59 WinPrev_OnDisplayChange( 60 IN PWINPREV_DATA pData) 61 { 62 // RECT rcNew; 63 64 pData->siVirtScr.cx = GetSystemMetrics(SM_CXVIRTUALSCREEN); 65 pData->siVirtScr.cy = GetSystemMetrics(SM_CYVIRTUALSCREEN); 66 67 /* 68 * The rescaling factor "siPreview / siVirtScr" should be the minimum of the ratios 69 * pData->rcMaxArea.right / pData->siVirtScr.cx , and 70 * pData->rcMaxArea.bottom / pData->siVirtScr.cy , 71 * or equivalently, the maximum of the inverse of these ratios. 72 * This condition is equivalent to the following inequality being tested. 73 */ 74 // if (pData->siVirtScr.cx / pData->rcMaxArea.right >= pData->siVirtScr.cy / pData->rcMaxArea.bottom) 75 if (pData->siVirtScr.cx * pData->rcMaxArea.bottom >= pData->siVirtScr.cy * pData->rcMaxArea.right) 76 { 77 pData->siPreview.cx = MulDiv(pData->siVirtScr.cx, pData->rcMaxArea.right, pData->siVirtScr.cx); 78 pData->siPreview.cy = MulDiv(pData->siVirtScr.cy, pData->rcMaxArea.right, pData->siVirtScr.cx); 79 } 80 else 81 { 82 pData->siPreview.cx = MulDiv(pData->siVirtScr.cx, pData->rcMaxArea.bottom, pData->siVirtScr.cy); 83 pData->siPreview.cy = MulDiv(pData->siVirtScr.cy, pData->rcMaxArea.bottom, pData->siVirtScr.cy); 84 } 85 86 /* 87 * Now, the lengths in screen-units can be rescaled into preview-units with: 88 * MulDiv(cx, pData->siPreview.cx, pData->siVirtScr.cx); 89 * and: 90 * MulDiv(cy, pData->siPreview.cy, pData->siVirtScr.cy); 91 */ 92 93 #if 0 // TODO: Investigate! 94 /* 95 * Since both rcMaxArea and siPreview are client window area sizes, 96 * transform them into window sizes. 97 */ 98 SetRect(&rcNew, 0, 0, pData->siPreview.cx, pData->siPreview.cy); 99 AdjustWindowRect(&rcNew, 100 WS_BORDER, 101 // GetWindowLongPtrW(pData->hWnd, GWL_STYLE) & ~WS_OVERLAPPED, 102 FALSE); 103 OffsetRect(&rcNew, -rcNew.left, -rcNew.top); 104 rcNew.right += 2; 105 rcNew.bottom += 2; 106 #endif 107 108 SetWindowPos(pData->hWnd, 109 0 /* HWND_TOP */, 110 0, 0, 111 pData->siPreview.cx, pData->siPreview.cy, 112 // rcNew.right, rcNew.bottom, 113 SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE); 114 } 115 116 #define RescaleCX(pData, len) \ 117 MulDiv((len), (pData)->siPreview.cx, (pData)->siVirtScr.cx) 118 119 #define RescaleCY(pData, len) \ 120 MulDiv((len), (pData)->siPreview.cy, (pData)->siVirtScr.cy) 121 122 #define RescaleRect(pData, rect) \ 123 do { \ 124 (rect).left = RescaleCX((pData), (rect).left); \ 125 (rect).right = RescaleCX((pData), (rect).right); \ 126 (rect).top = RescaleCY((pData), (rect).top); \ 127 (rect).bottom = RescaleCY((pData), (rect).bottom); \ 128 } while (0) 129 130 #if 0 131 static VOID 132 WinPrev_OnSize(VOID) 133 { 134 } 135 #endif 136 137 static VOID 138 WinPrev_OnDraw( 139 IN HDC hDC, 140 IN PWINPREV_DATA pData) 141 { 142 PCONSOLE_STATE_INFO pConInfo = (PCONSOLE_STATE_INFO)pData->pData; 143 HBRUSH hBrush; 144 RECT rcWin, fRect; 145 SIZE /*siBorder,*/ siFrame, siButton, siScroll; 146 SIZE resize; 147 148 RECT rcItem; 149 150 GetClientRect(pData->hWnd, &rcItem); 151 152 /* 153 * Retrieve some system metrics and rescale them. 154 * They will be added separately, so that to always round the sizes up. 155 */ 156 157 /* Don't care about border as it is almost always 1 and <= frame size */ 158 /* Example: Frame = 4, or 13 ... while Border = 1 */ 159 // siBorder.cx = GetSystemMetrics(SM_CXBORDER); 160 // siBorder.cy = GetSystemMetrics(SM_CYBORDER); 161 162 /* Window frame size */ 163 siFrame.cx = GetSystemMetrics(SM_CXFRAME); 164 if (siFrame.cx > 0) 165 { 166 siFrame.cx = RescaleCX(pData, siFrame.cx); 167 siFrame.cx = max(1, siFrame.cx); 168 } 169 siFrame.cy = GetSystemMetrics(SM_CYFRAME); 170 if (siFrame.cy > 0) 171 { 172 siFrame.cy = RescaleCY(pData, siFrame.cy); 173 siFrame.cy = max(1, siFrame.cy); 174 } 175 176 /* Window caption buttons */ 177 siButton.cx = GetSystemMetrics(SM_CXSIZE); 178 siButton.cx = RescaleCX(pData, siButton.cx); 179 siButton.cx = max(1, siButton.cx); 180 181 siButton.cy = GetSystemMetrics(SM_CYSIZE); 182 siButton.cy = RescaleCY(pData, siButton.cy); 183 siButton.cy = max(1, siButton.cy); 184 185 /* Enlarge them for improving their appearance */ 186 // siButton.cx *= 2; 187 siButton.cy *= 2; 188 189 /* Dimensions of the scrollbars */ 190 siScroll.cx = GetSystemMetrics(SM_CXVSCROLL); 191 siScroll.cx = RescaleCX(pData, siScroll.cx); 192 siScroll.cx = max(1, siScroll.cx); 193 194 siScroll.cy = GetSystemMetrics(SM_CYHSCROLL); 195 siScroll.cy = RescaleCY(pData, siScroll.cy); 196 siScroll.cy = max(1, siScroll.cy); 197 198 199 // FIXME: Use SM_CXMIN, SM_CYMIN ?? 200 201 202 /* 203 * Compute the console window layout 204 */ 205 206 if (FontPreview.hFont == NULL) 207 RefreshFontPreview(&FontPreview, pConInfo); 208 209 /* We start with the console client area, rescaled for the preview */ 210 SetRect(&rcWin, 0, 0, 211 pConInfo->WindowSize.X * FontPreview.CharWidth, 212 pConInfo->WindowSize.Y * FontPreview.CharHeight); 213 RescaleRect(pData, rcWin); 214 215 /* Add the scrollbars if needed (does not account for any frame) */ 216 if (pConInfo->WindowSize.X < pConInfo->ScreenBufferSize.X) 217 { 218 /* Horizontal scrollbar */ 219 rcWin.bottom += siScroll.cy; 220 // NOTE: If an additional exterior frame is needed, add +1 221 } 222 else 223 { 224 /* No scrollbar */ 225 siScroll.cy = 0; 226 } 227 if (pConInfo->WindowSize.Y < pConInfo->ScreenBufferSize.Y) 228 { 229 /* Vertical scrollbar */ 230 rcWin.right += siScroll.cx; 231 // NOTE: If an additional exterior frame is needed, add +1 232 } 233 else 234 { 235 /* No scrollbar */ 236 siScroll.cx = 0; 237 } 238 239 /* Add the title bar, taking into account the frames */ 240 rcWin.top -= siButton.cy - 1; 241 242 /* If we have a non-zero window frame size, add an interior border and the frame */ 243 resize.cx = (siFrame.cx > 0 ? 1 + siFrame.cx : 0); 244 resize.cy = (siFrame.cy > 0 ? 1 + siFrame.cy : 0); 245 246 /* Add the outer border */ 247 ++resize.cx, ++resize.cy; 248 249 InflateRect(&rcWin, resize.cx, resize.cy); 250 251 /* Finally, move the window rectangle back to its correct origin */ 252 OffsetRect(&rcWin, -rcWin.left, -rcWin.top); 253 254 if ( pConInfo->WindowPosition.x == MAXDWORD && 255 pConInfo->WindowPosition.y == MAXDWORD ) 256 { 257 // OffsetRect(&rcWin, (rcItem.right - rcItem.left) / 3, (rcItem.bottom - rcItem.top) / 3); 258 OffsetRect(&rcWin, 0, 0); 259 } 260 else 261 { 262 OffsetRect(&rcWin, 263 RescaleCX(pData, pConInfo->WindowPosition.x), 264 RescaleCY(pData, pConInfo->WindowPosition.y)); 265 } 266 267 268 /* 269 * Paint the preview window 270 */ 271 272 /* Fill the background with desktop colour */ 273 FillRect(hDC, &rcItem, GetSysColorBrush(COLOR_BACKGROUND)); 274 275 /* 276 * Draw the exterior frame. Use 'FillRect' instead of 'FrameRect' 277 * so that, when we want to draw frames around other elements, 278 * we can just instead separate them with space instead of redrawing 279 * a frame with 'FrameRect'. 280 */ 281 FillRect(hDC, &rcWin, GetSysColorBrush(COLOR_WINDOWFRAME)); 282 InflateRect(&rcWin, -1, -1); 283 284 /* Draw the border */ 285 hBrush = GetSysColorBrush(COLOR_ACTIVEBORDER); 286 if (siFrame.cx > 0) 287 { 288 SetRect(&fRect, rcWin.left, rcWin.top, rcWin.left + siFrame.cx, rcWin.bottom); 289 FillRect(hDC, &fRect, hBrush); 290 SetRect(&fRect, rcWin.right - siFrame.cx, rcWin.top, rcWin.right, rcWin.bottom); 291 FillRect(hDC, &fRect, hBrush); 292 293 InflateRect(&rcWin, -siFrame.cx, 0); 294 } 295 if (siFrame.cy > 0) 296 { 297 SetRect(&fRect, rcWin.left, rcWin.top, rcWin.right, rcWin.top + siFrame.cy); 298 FillRect(hDC, &fRect, hBrush); 299 SetRect(&fRect, rcWin.left, rcWin.bottom - siFrame.cy, rcWin.right, rcWin.bottom); 300 FillRect(hDC, &fRect, hBrush); 301 302 InflateRect(&rcWin, 0, -siFrame.cy); 303 } 304 305 /* Draw the interior frame if we had a border */ 306 if (siFrame.cx > 0 || siFrame.cy > 0) 307 { 308 #if 0 // See the remark above 309 SetRect(&fRect, rcWin.left, rcWin.top, rcWin.right, rcWin.bottom); 310 FrameRect(hDC, &fRect, GetSysColorBrush(COLOR_WINDOWFRAME)); 311 #endif 312 InflateRect(&rcWin, (siFrame.cx > 0 ? -1 : 0), (siFrame.cy > 0 ? -1 : 0)); 313 } 314 315 /* Draw the console window title bar */ 316 hBrush = GetSysColorBrush(COLOR_BTNFACE); 317 318 /* Draw the system menu (left button) */ 319 SetRect(&fRect, rcWin.left, rcWin.top, rcWin.left + siButton.cx, rcWin.top + siButton.cy - 2); 320 // DrawFrameControl(hDC, &fRect, DFC_CAPTION, DFCS_CAPTIONCLOSE); 321 FillRect(hDC, &fRect, hBrush); 322 fRect.right++; // Separation 323 324 /* Draw the caption bar */ 325 SetRect(&fRect, fRect.right, fRect.top, rcWin.right - 2 * (siButton.cx + 1), fRect.bottom); 326 FillRect(hDC, &fRect, GetSysColorBrush(COLOR_ACTIVECAPTION)); 327 fRect.right++; // Separation 328 329 /* Draw the minimize menu (first right button) */ 330 SetRect(&fRect, fRect.right, fRect.top, fRect.right + siButton.cx, fRect.bottom); 331 // DrawFrameControl(hDC, &fRect, DFC_CAPTION, DFCS_CAPTIONMIN); 332 FillRect(hDC, &fRect, hBrush); 333 fRect.right++; // Separation 334 335 /* Draw the maximize menu (second right button) */ 336 SetRect(&fRect, fRect.right, fRect.top, fRect.right + siButton.cx, fRect.bottom); 337 // DrawFrameControl(hDC, &fRect, DFC_CAPTION, DFCS_CAPTIONMAX); 338 FillRect(hDC, &fRect, hBrush); 339 340 rcWin.top += siButton.cy - 1; 341 342 /* Add the scrollbars if needed */ 343 if (siScroll.cy > 0 || siScroll.cx > 0) 344 { 345 LONG right, bottom; 346 347 right = rcWin.right; 348 bottom = rcWin.bottom; 349 350 /* 351 * If both the horizontal and vertical scrollbars are present, 352 * reserve some space for the "dead square" at the bottom right. 353 */ 354 if (siScroll.cy > 0 && siScroll.cx > 0) 355 { 356 right -= (1 + siScroll.cx); 357 bottom -= (1 + siScroll.cy); 358 } 359 360 hBrush = GetSysColorBrush(COLOR_SCROLLBAR); 361 362 /* Horizontal scrollbar */ 363 if (siScroll.cy > 0) 364 { 365 SetRect(&fRect, rcWin.left, rcWin.bottom - siScroll.cy, right, rcWin.bottom); 366 FillRect(hDC, &fRect, hBrush); 367 } 368 369 /* Vertical scrollbar */ 370 if (siScroll.cx > 0) 371 { 372 SetRect(&fRect, rcWin.right - siScroll.cx, rcWin.top, rcWin.right, bottom); 373 FillRect(hDC, &fRect, hBrush); 374 } 375 376 /* 377 * If both the horizontal and vertical scrollbars are present, 378 * draw the "dead square" at the bottom right. 379 */ 380 if (siScroll.cy > 0 && siScroll.cx > 0) 381 { 382 SetRect(&fRect, rcWin.right - siScroll.cx, rcWin.bottom - siScroll.cy, rcWin.right, rcWin.bottom); 383 FillRect(hDC, &fRect, hBrush); 384 } 385 386 // NOTE: If an additional exterior frame is needed, remove +1 for each direction 387 rcWin.right -= siScroll.cx; 388 rcWin.bottom -= siScroll.cy; 389 } 390 391 /* Draw the console background */ 392 hBrush = CreateSolidBrush(pConInfo->ColorTable[BkgdAttribFromAttrib(pConInfo->ScreenAttributes)]); 393 FillRect(hDC, &rcWin, hBrush ? hBrush : GetStockObject(BLACK_BRUSH)); 394 if (hBrush) DeleteObject(hBrush); 395 } 396 397 static LRESULT CALLBACK 398 WinPrevProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) 399 { 400 PWINPREV_DATA pData; 401 402 pData = (PWINPREV_DATA)GetWindowLongPtrW(hWnd, GWLP_USERDATA); 403 404 switch (msg) 405 { 406 case WM_CREATE: 407 { 408 pData = (PWINPREV_DATA)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*pData)); 409 if (!pData) 410 { 411 /* We failed to allocate our private data, halt the window creation */ 412 return (LRESULT)-1; 413 } 414 pData->hWnd = hWnd; 415 pData->pData = ConInfo; 416 GetClientRect(pData->hWnd, &pData->rcMaxArea); 417 // LPCREATESTRUCT::cx and cy give window (not client) size 418 WinPrev_OnDisplayChange(pData); 419 SetWindowLongPtrW(hWnd, GWLP_USERDATA, (LONG_PTR)pData); 420 break; 421 } 422 423 case WM_DESTROY: 424 { 425 if (pData) 426 HeapFree(GetProcessHeap(), 0, pData); 427 break; 428 } 429 430 case WM_DISPLAYCHANGE: 431 { 432 WinPrev_OnDisplayChange(pData); 433 UpdateWindow(hWnd); 434 // InvalidateRect(hWnd, NULL, FALSE); 435 break; 436 } 437 438 case WM_SIZE: 439 break; 440 441 case WM_ERASEBKGND: 442 return 1; 443 444 case WM_PAINT: 445 { 446 PAINTSTRUCT ps; 447 BeginPaint(hWnd, &ps); 448 WinPrev_OnDraw(ps.hdc, pData); 449 EndPaint(hWnd, &ps); 450 return 0; 451 } 452 } 453 454 return DefWindowProcW(hWnd, msg, wParam, lParam); 455 } 456 457 458 /* CONSOLE TEXT PREVIEW *******************************************************/ 459 460 const WCHAR szPreviewText[] = 461 L"C:\\ReactOS>dir\n" \ 462 L"SYSTEM <DIR> 13-04-15 5:00a\n" \ 463 L"SYSTEM32 <DIR> 13-04-15 5:00a\n" \ 464 L"readme txt 1739 13-04-15 5:00a\n" \ 465 L"explorer exe 3329536 13-04-15 5:00a\n" \ 466 L"vgafonts cab 18736 13-04-15 5:00a\n" \ 467 L"setuplog txt 313 13-04-15 5:00a\n" \ 468 L"win ini 7005 13-04-15 5:00a\n" ; 469 470 VOID 471 PaintText( 472 IN LPDRAWITEMSTRUCT drawItem, 473 IN PCONSOLE_STATE_INFO pConInfo, 474 IN TEXT_TYPE TextMode) 475 { 476 USHORT CurrentAttrib; 477 COLORREF pbkColor, ptColor; 478 COLORREF nbkColor, ntColor; 479 HBRUSH hBrush; 480 HFONT hOldFont; 481 482 if (TextMode == Screen) 483 CurrentAttrib = pConInfo->ScreenAttributes; 484 else if (TextMode == Popup) 485 CurrentAttrib = pConInfo->PopupAttributes; 486 else 487 return; 488 489 nbkColor = pConInfo->ColorTable[BkgdAttribFromAttrib(CurrentAttrib)]; 490 ntColor = pConInfo->ColorTable[TextAttribFromAttrib(CurrentAttrib)]; 491 492 /* Draw the console background */ 493 hBrush = CreateSolidBrush(nbkColor); 494 FillRect(drawItem->hDC, &drawItem->rcItem, hBrush ? hBrush : GetStockObject(BLACK_BRUSH)); 495 if (hBrush) DeleteObject(hBrush); 496 497 /* Refresh the font preview, getting a new font if necessary */ 498 if (FontPreview.hFont == NULL) 499 RefreshFontPreview(&FontPreview, pConInfo); 500 /* Recheck hFont since RefreshFontPreview() may not have updated it */ 501 if (FontPreview.hFont == NULL) 502 return; 503 504 /* Draw the preview text using the current font */ 505 hOldFont = SelectObject(drawItem->hDC, FontPreview.hFont); 506 // if (!hOldFont) return; 507 508 /* Add a few space between the preview window border and the text sample */ 509 InflateRect(&drawItem->rcItem, -2, -2); 510 511 ptColor = SetTextColor(drawItem->hDC, ntColor); 512 pbkColor = SetBkColor(drawItem->hDC, nbkColor); 513 DrawTextW(drawItem->hDC, szPreviewText, (INT)wcslen(szPreviewText), &drawItem->rcItem, 0); 514 SetTextColor(drawItem->hDC, ptColor); 515 SetBkColor(drawItem->hDC, pbkColor); 516 517 SelectObject(drawItem->hDC, hOldFont); 518 } 519 520 521 /* LAYOUT DIALOG **************************************************************/ 522 523 INT_PTR 524 CALLBACK 525 LayoutProc(HWND hDlg, 526 UINT uMsg, 527 WPARAM wParam, 528 LPARAM lParam) 529 { 530 switch (uMsg) 531 { 532 case WM_INITDIALOG: 533 { 534 /* Multi-monitor support */ 535 LONG xVirtScr, yVirtScr; // Coordinates of the top-left virtual screen 536 LONG cxVirtScr, cyVirtScr; // Width and Height of the virtual screen 537 LONG cxFrame , cyFrame ; // Thickness of the window frame 538 539 xVirtScr = GetSystemMetrics(SM_XVIRTUALSCREEN); 540 yVirtScr = GetSystemMetrics(SM_YVIRTUALSCREEN); 541 cxVirtScr = GetSystemMetrics(SM_CXVIRTUALSCREEN); 542 cyVirtScr = GetSystemMetrics(SM_CYVIRTUALSCREEN); 543 cxFrame = GetSystemMetrics(SM_CXFRAME); 544 cyFrame = GetSystemMetrics(SM_CYFRAME); 545 546 SendDlgItemMessageW(hDlg, IDC_UPDOWN_SCREEN_BUFFER_HEIGHT, UDM_SETRANGE, 0, (LPARAM)MAKELONG(9999, 1)); 547 SendDlgItemMessageW(hDlg, IDC_UPDOWN_SCREEN_BUFFER_WIDTH , UDM_SETRANGE, 0, (LPARAM)MAKELONG(9999, 1)); 548 SendDlgItemMessageW(hDlg, IDC_UPDOWN_WINDOW_SIZE_HEIGHT, UDM_SETRANGE, 0, (LPARAM)MAKELONG(9999, 1)); 549 SendDlgItemMessageW(hDlg, IDC_UPDOWN_WINDOW_SIZE_WIDTH , UDM_SETRANGE, 0, (LPARAM)MAKELONG(9999, 1)); 550 551 SetDlgItemInt(hDlg, IDC_EDIT_SCREEN_BUFFER_HEIGHT, ConInfo->ScreenBufferSize.Y, FALSE); 552 SetDlgItemInt(hDlg, IDC_EDIT_SCREEN_BUFFER_WIDTH , ConInfo->ScreenBufferSize.X, FALSE); 553 SetDlgItemInt(hDlg, IDC_EDIT_WINDOW_SIZE_HEIGHT, ConInfo->WindowSize.Y, FALSE); 554 SetDlgItemInt(hDlg, IDC_EDIT_WINDOW_SIZE_WIDTH , ConInfo->WindowSize.X, FALSE); 555 556 SendDlgItemMessageW(hDlg, IDC_UPDOWN_WINDOW_POS_LEFT, UDM_SETRANGE, 0, 557 (LPARAM)MAKELONG(xVirtScr + cxVirtScr - cxFrame, xVirtScr - cxFrame)); 558 SendDlgItemMessageW(hDlg, IDC_UPDOWN_WINDOW_POS_TOP , UDM_SETRANGE, 0, 559 (LPARAM)MAKELONG(yVirtScr + cyVirtScr - cyFrame, yVirtScr - cyFrame)); 560 561 SetDlgItemInt(hDlg, IDC_EDIT_WINDOW_POS_LEFT, ConInfo->WindowPosition.x, TRUE); 562 SetDlgItemInt(hDlg, IDC_EDIT_WINDOW_POS_TOP , ConInfo->WindowPosition.y, TRUE); 563 564 if (ConInfo->AutoPosition) 565 { 566 EnableDlgItem(hDlg, IDC_EDIT_WINDOW_POS_LEFT, FALSE); 567 EnableDlgItem(hDlg, IDC_EDIT_WINDOW_POS_TOP , FALSE); 568 EnableDlgItem(hDlg, IDC_UPDOWN_WINDOW_POS_LEFT, FALSE); 569 EnableDlgItem(hDlg, IDC_UPDOWN_WINDOW_POS_TOP , FALSE); 570 } 571 CheckDlgButton(hDlg, IDC_CHECK_SYSTEM_POS_WINDOW, 572 ConInfo->AutoPosition ? BST_CHECKED : BST_UNCHECKED); 573 574 return TRUE; 575 } 576 577 case WM_DISPLAYCHANGE: 578 { 579 /* Retransmit to the preview window */ 580 SendDlgItemMessageW(hDlg, IDC_STATIC_LAYOUT_WINDOW_PREVIEW, 581 WM_DISPLAYCHANGE, wParam, lParam); 582 break; 583 } 584 585 case WM_NOTIFY: 586 { 587 LPPSHNOTIFY lppsn = (LPPSHNOTIFY)lParam; 588 589 if (lppsn->hdr.code == UDN_DELTAPOS) 590 { 591 LPNMUPDOWN lpnmud = (LPNMUPDOWN)lParam; 592 DWORD wheight, wwidth; 593 DWORD sheight, swidth; 594 DWORD left, top; 595 596 if (lppsn->hdr.idFrom == IDC_UPDOWN_WINDOW_SIZE_WIDTH) 597 { 598 wwidth = lpnmud->iPos + lpnmud->iDelta; 599 } 600 else 601 { 602 wwidth = GetDlgItemInt(hDlg, IDC_EDIT_WINDOW_SIZE_WIDTH, NULL, FALSE); 603 } 604 605 if (lppsn->hdr.idFrom == IDC_UPDOWN_WINDOW_SIZE_HEIGHT) 606 { 607 wheight = lpnmud->iPos + lpnmud->iDelta; 608 } 609 else 610 { 611 wheight = GetDlgItemInt(hDlg, IDC_EDIT_WINDOW_SIZE_HEIGHT, NULL, FALSE); 612 } 613 614 if (lppsn->hdr.idFrom == IDC_UPDOWN_SCREEN_BUFFER_WIDTH) 615 { 616 swidth = lpnmud->iPos + lpnmud->iDelta; 617 } 618 else 619 { 620 swidth = GetDlgItemInt(hDlg, IDC_EDIT_SCREEN_BUFFER_WIDTH, NULL, FALSE); 621 } 622 623 if (lppsn->hdr.idFrom == IDC_UPDOWN_SCREEN_BUFFER_HEIGHT) 624 { 625 sheight = lpnmud->iPos + lpnmud->iDelta; 626 } 627 else 628 { 629 sheight = GetDlgItemInt(hDlg, IDC_EDIT_SCREEN_BUFFER_HEIGHT, NULL, FALSE); 630 } 631 632 if (lppsn->hdr.idFrom == IDC_UPDOWN_WINDOW_POS_LEFT) 633 { 634 left = lpnmud->iPos + lpnmud->iDelta; 635 } 636 else 637 { 638 left = GetDlgItemInt(hDlg, IDC_EDIT_WINDOW_POS_LEFT, NULL, TRUE); 639 } 640 641 if (lppsn->hdr.idFrom == IDC_UPDOWN_WINDOW_POS_TOP) 642 { 643 top = lpnmud->iPos + lpnmud->iDelta; 644 } 645 else 646 { 647 top = GetDlgItemInt(hDlg, IDC_EDIT_WINDOW_POS_TOP, NULL, TRUE); 648 } 649 650 if (lppsn->hdr.idFrom == IDC_UPDOWN_WINDOW_SIZE_WIDTH || lppsn->hdr.idFrom == IDC_UPDOWN_WINDOW_SIZE_HEIGHT) 651 { 652 /* Automatically adjust screen buffer size when window size enlarges */ 653 if (wwidth >= swidth) 654 { 655 SetDlgItemInt(hDlg, IDC_EDIT_SCREEN_BUFFER_WIDTH, wwidth, TRUE); 656 swidth = wwidth; 657 } 658 if (wheight >= sheight) 659 { 660 SetDlgItemInt(hDlg, IDC_EDIT_SCREEN_BUFFER_HEIGHT, wheight, TRUE); 661 sheight = wheight; 662 } 663 } 664 665 /* Be sure that the (new) screen buffer sizes are in the correct range */ 666 swidth = min(max(swidth , 1), 0xFFFF); 667 sheight = min(max(sheight, 1), 0xFFFF); 668 669 if (lppsn->hdr.idFrom == IDC_UPDOWN_SCREEN_BUFFER_WIDTH || lppsn->hdr.idFrom == IDC_UPDOWN_SCREEN_BUFFER_HEIGHT) 670 { 671 /* Automatically adjust window size when screen buffer decreases */ 672 if (wwidth > swidth) 673 { 674 SetDlgItemInt(hDlg, IDC_EDIT_WINDOW_SIZE_WIDTH, swidth, TRUE); 675 wwidth = swidth; 676 } 677 if (wheight > sheight) 678 { 679 SetDlgItemInt(hDlg, IDC_EDIT_WINDOW_SIZE_HEIGHT, sheight, TRUE); 680 wheight = sheight; 681 } 682 } 683 684 ConInfo->ScreenBufferSize.X = (SHORT)swidth; 685 ConInfo->ScreenBufferSize.Y = (SHORT)sheight; 686 ConInfo->WindowSize.X = (SHORT)wwidth; 687 ConInfo->WindowSize.Y = (SHORT)wheight; 688 ConInfo->WindowPosition.x = left; 689 ConInfo->WindowPosition.y = top; 690 691 InvalidateRect(GetDlgItem(hDlg, IDC_STATIC_LAYOUT_WINDOW_PREVIEW), NULL, TRUE); 692 PropSheet_Changed(GetParent(hDlg), hDlg); 693 } 694 break; 695 } 696 697 case WM_COMMAND: 698 { 699 if (HIWORD(wParam) == EN_KILLFOCUS) 700 { 701 switch (LOWORD(wParam)) 702 { 703 case IDC_EDIT_SCREEN_BUFFER_WIDTH: 704 { 705 DWORD swidth, wwidth; 706 707 swidth = GetDlgItemInt(hDlg, IDC_EDIT_SCREEN_BUFFER_WIDTH, NULL, FALSE); 708 wwidth = GetDlgItemInt(hDlg, IDC_EDIT_WINDOW_SIZE_WIDTH , NULL, FALSE); 709 710 /* Be sure that the (new) screen buffer width is in the correct range */ 711 swidth = min(max(swidth, 1), 0xFFFF); 712 713 /* Automatically adjust window size when screen buffer decreases */ 714 if (wwidth > swidth) 715 { 716 wwidth = swidth; 717 SetDlgItemInt(hDlg, IDC_EDIT_WINDOW_SIZE_WIDTH, wwidth, TRUE); 718 } 719 720 ConInfo->ScreenBufferSize.X = (SHORT)swidth; 721 ConInfo->WindowSize.X = (SHORT)wwidth; 722 723 InvalidateRect(GetDlgItem(hDlg, IDC_STATIC_LAYOUT_WINDOW_PREVIEW), NULL, TRUE); 724 PropSheet_Changed(GetParent(hDlg), hDlg); 725 break; 726 } 727 728 case IDC_EDIT_WINDOW_SIZE_WIDTH: 729 { 730 DWORD swidth, wwidth; 731 732 swidth = GetDlgItemInt(hDlg, IDC_EDIT_SCREEN_BUFFER_WIDTH, NULL, FALSE); 733 wwidth = GetDlgItemInt(hDlg, IDC_EDIT_WINDOW_SIZE_WIDTH , NULL, FALSE); 734 735 /* Automatically adjust screen buffer size when window size enlarges */ 736 if (wwidth >= swidth) 737 { 738 swidth = wwidth; 739 740 /* Be sure that the (new) screen buffer width is in the correct range */ 741 swidth = min(max(swidth, 1), 0xFFFF); 742 743 SetDlgItemInt(hDlg, IDC_EDIT_SCREEN_BUFFER_WIDTH, swidth, TRUE); 744 } 745 746 ConInfo->ScreenBufferSize.X = (SHORT)swidth; 747 ConInfo->WindowSize.X = (SHORT)wwidth; 748 749 InvalidateRect(GetDlgItem(hDlg, IDC_STATIC_LAYOUT_WINDOW_PREVIEW), NULL, TRUE); 750 PropSheet_Changed(GetParent(hDlg), hDlg); 751 break; 752 } 753 754 case IDC_EDIT_SCREEN_BUFFER_HEIGHT: 755 { 756 DWORD sheight, wheight; 757 758 sheight = GetDlgItemInt(hDlg, IDC_EDIT_SCREEN_BUFFER_HEIGHT, NULL, FALSE); 759 wheight = GetDlgItemInt(hDlg, IDC_EDIT_WINDOW_SIZE_HEIGHT , NULL, FALSE); 760 761 /* Be sure that the (new) screen buffer width is in the correct range */ 762 sheight = min(max(sheight, 1), 0xFFFF); 763 764 /* Automatically adjust window size when screen buffer decreases */ 765 if (wheight > sheight) 766 { 767 wheight = sheight; 768 SetDlgItemInt(hDlg, IDC_EDIT_WINDOW_SIZE_HEIGHT, wheight, TRUE); 769 } 770 771 ConInfo->ScreenBufferSize.Y = (SHORT)sheight; 772 ConInfo->WindowSize.Y = (SHORT)wheight; 773 774 InvalidateRect(GetDlgItem(hDlg, IDC_STATIC_LAYOUT_WINDOW_PREVIEW), NULL, TRUE); 775 PropSheet_Changed(GetParent(hDlg), hDlg); 776 break; 777 } 778 779 case IDC_EDIT_WINDOW_SIZE_HEIGHT: 780 { 781 DWORD sheight, wheight; 782 783 sheight = GetDlgItemInt(hDlg, IDC_EDIT_SCREEN_BUFFER_HEIGHT, NULL, FALSE); 784 wheight = GetDlgItemInt(hDlg, IDC_EDIT_WINDOW_SIZE_HEIGHT , NULL, FALSE); 785 786 /* Automatically adjust screen buffer size when window size enlarges */ 787 if (wheight >= sheight) 788 { 789 sheight = wheight; 790 791 /* Be sure that the (new) screen buffer width is in the correct range */ 792 sheight = min(max(sheight, 1), 0xFFFF); 793 794 SetDlgItemInt(hDlg, IDC_EDIT_SCREEN_BUFFER_HEIGHT, sheight, TRUE); 795 } 796 797 ConInfo->ScreenBufferSize.Y = (SHORT)sheight; 798 ConInfo->WindowSize.Y = (SHORT)wheight; 799 800 InvalidateRect(GetDlgItem(hDlg, IDC_STATIC_LAYOUT_WINDOW_PREVIEW), NULL, TRUE); 801 PropSheet_Changed(GetParent(hDlg), hDlg); 802 break; 803 } 804 805 case IDC_EDIT_WINDOW_POS_LEFT: 806 case IDC_EDIT_WINDOW_POS_TOP: 807 { 808 ConInfo->WindowPosition.x = GetDlgItemInt(hDlg, IDC_EDIT_WINDOW_POS_LEFT, NULL, TRUE); 809 ConInfo->WindowPosition.y = GetDlgItemInt(hDlg, IDC_EDIT_WINDOW_POS_TOP , NULL, TRUE); 810 811 InvalidateRect(GetDlgItem(hDlg, IDC_STATIC_LAYOUT_WINDOW_PREVIEW), NULL, TRUE); 812 PropSheet_Changed(GetParent(hDlg), hDlg); 813 break; 814 } 815 } 816 } 817 else 818 if (HIWORD(wParam) == BN_CLICKED && 819 LOWORD(wParam) == IDC_CHECK_SYSTEM_POS_WINDOW) 820 { 821 if (IsDlgButtonChecked(hDlg, IDC_CHECK_SYSTEM_POS_WINDOW) == BST_CHECKED) 822 { 823 EnableDlgItem(hDlg, IDC_EDIT_WINDOW_POS_LEFT, FALSE); 824 EnableDlgItem(hDlg, IDC_EDIT_WINDOW_POS_TOP , FALSE); 825 EnableDlgItem(hDlg, IDC_UPDOWN_WINDOW_POS_LEFT, FALSE); 826 EnableDlgItem(hDlg, IDC_UPDOWN_WINDOW_POS_TOP , FALSE); 827 828 ConInfo->AutoPosition = TRUE; 829 // Do not touch ConInfo->WindowPosition !! 830 831 InvalidateRect(GetDlgItem(hDlg, IDC_STATIC_LAYOUT_WINDOW_PREVIEW), NULL, TRUE); 832 PropSheet_Changed(GetParent(hDlg), hDlg); 833 } 834 else 835 { 836 ULONG left, top; 837 838 left = GetDlgItemInt(hDlg, IDC_EDIT_WINDOW_POS_LEFT, NULL, TRUE); 839 top = GetDlgItemInt(hDlg, IDC_EDIT_WINDOW_POS_TOP , NULL, TRUE); 840 841 EnableDlgItem(hDlg, IDC_EDIT_WINDOW_POS_LEFT, TRUE); 842 EnableDlgItem(hDlg, IDC_EDIT_WINDOW_POS_TOP , TRUE); 843 EnableDlgItem(hDlg, IDC_UPDOWN_WINDOW_POS_LEFT, TRUE); 844 EnableDlgItem(hDlg, IDC_UPDOWN_WINDOW_POS_TOP , TRUE); 845 846 ConInfo->AutoPosition = FALSE; 847 ConInfo->WindowPosition.x = left; 848 ConInfo->WindowPosition.y = top; 849 850 InvalidateRect(GetDlgItem(hDlg, IDC_STATIC_LAYOUT_WINDOW_PREVIEW), NULL, TRUE); 851 PropSheet_Changed(GetParent(hDlg), hDlg); 852 } 853 } 854 855 break; 856 } 857 858 default: 859 break; 860 } 861 862 return FALSE; 863 } 864