reactos/dll/cpl/console/layout.c

864 lines
30 KiB
C
Raw Normal View History

/*
* PROJECT: ReactOS Console Configuration DLL
* LICENSE: GPL - See COPYING in the top level directory
* FILE: dll/cpl/console/layout.c
* PURPOSE: Layout dialog
* PROGRAMMERS: Johannes Anderwald (johannes.anderwald@reactos.org)
* Hermes Belusca-Maito (hermes.belusca@sfr.fr)
*/
#include "console.h"
#define NDEBUG
#include <debug.h>
/* CONSOLE WINDOW PREVIEW Control *********************************************/
[CONSOLE.DLL-KERNEL32-CONSRV] Fix the console properties dialog, when launching and transmitting console properties. Before, the properties dialog was directly launched by the console server (consrv), running with CSRSS (System) privileges, what constituted a security hole. Now, I create a remote thread in the running process owning the console for launching the properties dialog (thus it has only user privileges, and not System ones anymore). For that purpose, I basically took the technique described in the following paper (Cesar Cerrudo, "Story of a dumb patch", http://www.argeniss.com/research/MSBugPaper.pdf or http://www.scn.rain.com/~neighorn/PDF/MSBugPaper.pdf), where basically the console server shares the console properties via a shared memory section with the console properties dialog dll. The address of the thread which launches the dialog in the context of the console app is given to the console server the same way as we do for the control handler (called e.g. when you press Ctrl-C, etc...) Of course this is quite hackish, because you have the GUI interface split between the console server and the console properties dialog dll. Something far more elegant would be to put all the GUI thingie into a dedicated dll or exe, running with the same privileges as the console program itself (a kind of console -- or terminal -- emulator). [CONSOLE.DLL] Fix retriving / setting colors.c and other things. [CONSRV.DLL] - Fix retrieving / setting console properties from the registry (via the HKCU\Console\* keys), via the shell shortcuts (not totally done at the moment, because somebody has to implement properly that thing : http://msdn.microsoft.com/en-us/library/windows/desktop/bb773359(v=vs.85).aspx (NT_CONSOLE_PROPS structure stored as a shortcut data block) (at application launching time), and via the console properties dialog. - Few DPRINTs removed. svn path=/branches/ros-csrss/; revision=58415
2013-03-03 15:35:12 +00:00
#define WIN_PREVIEW_CLASS L"WinPreview"
[CONSOLE.DLL-KERNEL32-CONSRV] Fix the console properties dialog, when launching and transmitting console properties. Before, the properties dialog was directly launched by the console server (consrv), running with CSRSS (System) privileges, what constituted a security hole. Now, I create a remote thread in the running process owning the console for launching the properties dialog (thus it has only user privileges, and not System ones anymore). For that purpose, I basically took the technique described in the following paper (Cesar Cerrudo, "Story of a dumb patch", http://www.argeniss.com/research/MSBugPaper.pdf or http://www.scn.rain.com/~neighorn/PDF/MSBugPaper.pdf), where basically the console server shares the console properties via a shared memory section with the console properties dialog dll. The address of the thread which launches the dialog in the context of the console app is given to the console server the same way as we do for the control handler (called e.g. when you press Ctrl-C, etc...) Of course this is quite hackish, because you have the GUI interface split between the console server and the console properties dialog dll. Something far more elegant would be to put all the GUI thingie into a dedicated dll or exe, running with the same privileges as the console program itself (a kind of console -- or terminal -- emulator). [CONSOLE.DLL] Fix retriving / setting colors.c and other things. [CONSRV.DLL] - Fix retrieving / setting console properties from the registry (via the HKCU\Console\* keys), via the shell shortcuts (not totally done at the moment, because somebody has to implement properly that thing : http://msdn.microsoft.com/en-us/library/windows/desktop/bb773359(v=vs.85).aspx (NT_CONSOLE_PROPS structure stored as a shortcut data block) (at application launching time), and via the console properties dialog. - Few DPRINTs removed. svn path=/branches/ros-csrss/; revision=58415
2013-03-03 15:35:12 +00:00
typedef struct _WINPREV_DATA
{
HWND hWnd; // The window which this structure refers to
RECT rcMaxArea; // Maximum rectangle in which the preview window can be sized
SIZE siPreview; // Actual size of the preview window
SIZE siVirtScr; // Width and Height of the virtual screen
PVOID pData; // Private data
} WINPREV_DATA, *PWINPREV_DATA;
static LRESULT CALLBACK
WinPrevProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
BOOL
RegisterWinPrevClass(
IN HINSTANCE hInstance)
{
WNDCLASSW WndClass;
WndClass.lpszClassName = WIN_PREVIEW_CLASS;
WndClass.lpfnWndProc = WinPrevProc;
WndClass.style = 0;
WndClass.hInstance = hInstance;
WndClass.hIcon = NULL;
WndClass.hCursor = LoadCursorW(NULL, MAKEINTRESOURCEW(IDC_ARROW));
WndClass.hbrBackground = (HBRUSH)(COLOR_BACKGROUND + 1);
WndClass.lpszMenuName = NULL;
WndClass.cbClsExtra = 0;
WndClass.cbWndExtra = 0; // sizeof(PWINPREV_DATA);
return (RegisterClassW(&WndClass) != 0);
}
BOOL
UnRegisterWinPrevClass(
IN HINSTANCE hInstance)
{
return UnregisterClassW(WIN_PREVIEW_CLASS, hInstance);
}
static VOID
WinPrev_OnDisplayChange(
IN PWINPREV_DATA pData)
{
// RECT rcNew;
pData->siVirtScr.cx = GetSystemMetrics(SM_CXVIRTUALSCREEN);
pData->siVirtScr.cy = GetSystemMetrics(SM_CYVIRTUALSCREEN);
/*
* The rescaling factor "siPreview / siVirtScr" should be the minimum of the ratios
* pData->rcMaxArea.right / pData->siVirtScr.cx , and
* pData->rcMaxArea.bottom / pData->siVirtScr.cy ,
* or equivalently, the maximum of the inverse of these ratios.
* This condition is equivalent to the following inequality being tested.
*/
// if (pData->siVirtScr.cx / pData->rcMaxArea.right >= pData->siVirtScr.cy / pData->rcMaxArea.bottom)
if (pData->siVirtScr.cx * pData->rcMaxArea.bottom >= pData->siVirtScr.cy * pData->rcMaxArea.right)
{
pData->siPreview.cx = MulDiv(pData->siVirtScr.cx, pData->rcMaxArea.right, pData->siVirtScr.cx);
pData->siPreview.cy = MulDiv(pData->siVirtScr.cy, pData->rcMaxArea.right, pData->siVirtScr.cx);
}
else
{
pData->siPreview.cx = MulDiv(pData->siVirtScr.cx, pData->rcMaxArea.bottom, pData->siVirtScr.cy);
pData->siPreview.cy = MulDiv(pData->siVirtScr.cy, pData->rcMaxArea.bottom, pData->siVirtScr.cy);
}
/*
* Now, the lengths in screen-units can be rescaled into preview-units with:
* MulDiv(cx, pData->siPreview.cx, pData->siVirtScr.cx);
* and:
* MulDiv(cy, pData->siPreview.cy, pData->siVirtScr.cy);
*/
#if 0 // TODO: Investigate!
/*
* Since both rcMaxArea and siPreview are client window area sizes,
* transform them into window sizes.
*/
SetRect(&rcNew, 0, 0, pData->siPreview.cx, pData->siPreview.cy);
AdjustWindowRect(&rcNew,
WS_BORDER,
// GetWindowLongPtrW(pData->hWnd, GWL_STYLE) & ~WS_OVERLAPPED,
FALSE);
OffsetRect(&rcNew, -rcNew.left, -rcNew.top);
rcNew.right += 2;
rcNew.bottom += 2;
#endif
SetWindowPos(pData->hWnd,
0 /* HWND_TOP */,
0, 0,
pData->siPreview.cx, pData->siPreview.cy,
// rcNew.right, rcNew.bottom,
SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE);
}
#define RescaleCX(pData, len) \
MulDiv((len), (pData)->siPreview.cx, (pData)->siVirtScr.cx)
#define RescaleCY(pData, len) \
MulDiv((len), (pData)->siPreview.cy, (pData)->siVirtScr.cy)
#define RescaleRect(pData, rect) \
do { \
(rect).left = RescaleCX((pData), (rect).left); \
(rect).right = RescaleCX((pData), (rect).right); \
(rect).top = RescaleCY((pData), (rect).top); \
(rect).bottom = RescaleCY((pData), (rect).bottom); \
} while (0)
#if 0
static VOID
WinPrev_OnSize(VOID)
{
}
#endif
static VOID
WinPrev_OnDraw(
IN HDC hDC,
IN PWINPREV_DATA pData)
{
PCONSOLE_STATE_INFO pConInfo = (PCONSOLE_STATE_INFO)pData->pData;
HBRUSH hBrush;
RECT rcWin, fRect;
SIZE /*siBorder,*/ siFrame, siButton, siScroll;
SIZE resize;
RECT rcItem;
GetClientRect(pData->hWnd, &rcItem);
/*
* Retrieve some system metrics and rescale them.
* They will be added separately, so that to always round the sizes up.
*/
/* Don't care about border as it is almost always 1 and <= frame size */
/* Example: Frame = 4, or 13 ... while Border = 1 */
// siBorder.cx = GetSystemMetrics(SM_CXBORDER);
// siBorder.cy = GetSystemMetrics(SM_CYBORDER);
/* Window frame size */
siFrame.cx = GetSystemMetrics(SM_CXFRAME);
if (siFrame.cx > 0)
{
siFrame.cx = RescaleCX(pData, siFrame.cx);
siFrame.cx = max(1, siFrame.cx);
}
siFrame.cy = GetSystemMetrics(SM_CYFRAME);
if (siFrame.cy > 0)
{
siFrame.cy = RescaleCY(pData, siFrame.cy);
siFrame.cy = max(1, siFrame.cy);
}
/* Window caption buttons */
siButton.cx = GetSystemMetrics(SM_CXSIZE);
siButton.cx = RescaleCX(pData, siButton.cx);
siButton.cx = max(1, siButton.cx);
siButton.cy = GetSystemMetrics(SM_CYSIZE);
siButton.cy = RescaleCY(pData, siButton.cy);
siButton.cy = max(1, siButton.cy);
/* Enlarge them for improving their appearance */
// siButton.cx *= 2;
siButton.cy *= 2;
/* Dimensions of the scrollbars */
siScroll.cx = GetSystemMetrics(SM_CXVSCROLL);
siScroll.cx = RescaleCX(pData, siScroll.cx);
siScroll.cx = max(1, siScroll.cx);
siScroll.cy = GetSystemMetrics(SM_CYHSCROLL);
siScroll.cy = RescaleCY(pData, siScroll.cy);
siScroll.cy = max(1, siScroll.cy);
// FIXME: Use SM_CXMIN, SM_CYMIN ??
/*
* Compute the console window layout
*/
if (FontPreview.hFont == NULL)
RefreshFontPreview(&FontPreview, pConInfo);
/* We start with the console client area, rescaled for the preview */
SetRect(&rcWin, 0, 0,
pConInfo->WindowSize.X * FontPreview.CharWidth,
pConInfo->WindowSize.Y * FontPreview.CharHeight);
RescaleRect(pData, rcWin);
/* Add the scrollbars if needed (does not account for any frame) */
if (pConInfo->WindowSize.X < pConInfo->ScreenBufferSize.X)
{
/* Horizontal scrollbar */
rcWin.bottom += siScroll.cy;
// NOTE: If an additional exterior frame is needed, add +1
}
else
{
/* No scrollbar */
siScroll.cy = 0;
}
if (pConInfo->WindowSize.Y < pConInfo->ScreenBufferSize.Y)
{
/* Vertical scrollbar */
rcWin.right += siScroll.cx;
// NOTE: If an additional exterior frame is needed, add +1
}
else
{
/* No scrollbar */
siScroll.cx = 0;
}
/* Add the title bar, taking into account the frames */
rcWin.top -= siButton.cy - 1;
/* If we have a non-zero window frame size, add an interior border and the frame */
resize.cx = (siFrame.cx > 0 ? 1 + siFrame.cx : 0);
resize.cy = (siFrame.cy > 0 ? 1 + siFrame.cy : 0);
/* Add the outer border */
++resize.cx, ++resize.cy;
InflateRect(&rcWin, resize.cx, resize.cy);
/* Finally, move the window rectangle back to its correct origin */
OffsetRect(&rcWin, -rcWin.left, -rcWin.top);
[CONSRV] - Introduce a "console configuration" library that is used by both CONSRV and the console properties applet so that they can share common code concerning getting/setting console registry properties. - Make use of the Windows-compatible (and undocumented) CONSOLE_STATE_INFO structure for that purpose (as well as the WM_SETCONSOLEINFO): see commits r63819 and r58415 and links within for more details. Note: this structure needs to be 4-byte packed (contrary to what it is said in almost all the links from above. The difference is only visible at the level of the last member that is the ConsoleTitle string array. This was tested on windows). - Simplify some parts of console settings initialization. - Some work is still needed concerning how to correctly retrieve the default console settings (without touching the ConsoleTitle member of CONSOLE_STATE_INFO, contrary to what we do currently). [CONSOLE.DLL] - Make the console properties applet windows-compatible, in the sense that you can now run it on win2k3 and use it instead of the windows one. This implies having the same strange hacks as windows' one, namely, that the window handle parameter of the CPlApplet entry point is either used as the caller (parent) window handle, OR, as a shared section handle to shared data with CONSRV. [KERNEL32] - Rework the console applet initialization accordingly. Also we reload each time the console.dll when opening the console applet, and then unload it: this "allows" to reset all the global variables that console.dll may (and does) have. svn path=/trunk/; revision=66867
2015-03-24 23:58:44 +00:00
if ( pConInfo->WindowPosition.x == MAXDWORD &&
pConInfo->WindowPosition.y == MAXDWORD )
{
// OffsetRect(&rcWin, (rcItem.right - rcItem.left) / 3, (rcItem.bottom - rcItem.top) / 3);
OffsetRect(&rcWin, 0, 0);
}
else
{
OffsetRect(&rcWin,
RescaleCX(pData, pConInfo->WindowPosition.x),
RescaleCY(pData, pConInfo->WindowPosition.y));
}
/*
* Paint the preview window
*/
/* Fill the background with desktop colour */
FillRect(hDC, &rcItem, GetSysColorBrush(COLOR_BACKGROUND));
/*
* Draw the exterior frame. Use 'FillRect' instead of 'FrameRect'
* so that, when we want to draw frames around other elements,
* we can just instead separate them with space instead of redrawing
* a frame with 'FrameRect'.
*/
FillRect(hDC, &rcWin, GetSysColorBrush(COLOR_WINDOWFRAME));
InflateRect(&rcWin, -1, -1);
/* Draw the border */
hBrush = GetSysColorBrush(COLOR_ACTIVEBORDER);
if (siFrame.cx > 0)
{
SetRect(&fRect, rcWin.left, rcWin.top, rcWin.left + siFrame.cx, rcWin.bottom);
FillRect(hDC, &fRect, hBrush);
SetRect(&fRect, rcWin.right - siFrame.cx, rcWin.top, rcWin.right, rcWin.bottom);
FillRect(hDC, &fRect, hBrush);
InflateRect(&rcWin, -siFrame.cx, 0);
}
if (siFrame.cy > 0)
{
SetRect(&fRect, rcWin.left, rcWin.top, rcWin.right, rcWin.top + siFrame.cy);
FillRect(hDC, &fRect, hBrush);
SetRect(&fRect, rcWin.left, rcWin.bottom - siFrame.cy, rcWin.right, rcWin.bottom);
FillRect(hDC, &fRect, hBrush);
InflateRect(&rcWin, 0, -siFrame.cy);
}
/* Draw the interior frame if we had a border */
if (siFrame.cx > 0 || siFrame.cy > 0)
{
#if 0 // See the remark above
SetRect(&fRect, rcWin.left, rcWin.top, rcWin.right, rcWin.bottom);
FrameRect(hDC, &fRect, GetSysColorBrush(COLOR_WINDOWFRAME));
#endif
InflateRect(&rcWin, (siFrame.cx > 0 ? -1 : 0), (siFrame.cy > 0 ? -1 : 0));
}
/* Draw the console window title bar */
hBrush = GetSysColorBrush(COLOR_BTNFACE);
/* Draw the system menu (left button) */
SetRect(&fRect, rcWin.left, rcWin.top, rcWin.left + siButton.cx, rcWin.top + siButton.cy - 2);
// DrawFrameControl(hDC, &fRect, DFC_CAPTION, DFCS_CAPTIONCLOSE);
FillRect(hDC, &fRect, hBrush);
fRect.right++; // Separation
/* Draw the caption bar */
SetRect(&fRect, fRect.right, fRect.top, rcWin.right - 2 * (siButton.cx + 1), fRect.bottom);
FillRect(hDC, &fRect, GetSysColorBrush(COLOR_ACTIVECAPTION));
fRect.right++; // Separation
/* Draw the minimize menu (first right button) */
SetRect(&fRect, fRect.right, fRect.top, fRect.right + siButton.cx, fRect.bottom);
// DrawFrameControl(hDC, &fRect, DFC_CAPTION, DFCS_CAPTIONMIN);
FillRect(hDC, &fRect, hBrush);
fRect.right++; // Separation
/* Draw the maximize menu (second right button) */
SetRect(&fRect, fRect.right, fRect.top, fRect.right + siButton.cx, fRect.bottom);
// DrawFrameControl(hDC, &fRect, DFC_CAPTION, DFCS_CAPTIONMAX);
FillRect(hDC, &fRect, hBrush);
rcWin.top += siButton.cy - 1;
/* Add the scrollbars if needed */
if (siScroll.cy > 0 || siScroll.cx > 0)
{
LONG right, bottom;
right = rcWin.right;
bottom = rcWin.bottom;
/*
* If both the horizontal and vertical scrollbars are present,
* reserve some space for the "dead square" at the bottom right.
*/
if (siScroll.cy > 0 && siScroll.cx > 0)
{
right -= (1 + siScroll.cx);
bottom -= (1 + siScroll.cy);
}
hBrush = GetSysColorBrush(COLOR_SCROLLBAR);
/* Horizontal scrollbar */
if (siScroll.cy > 0)
{
SetRect(&fRect, rcWin.left, rcWin.bottom - siScroll.cy, right, rcWin.bottom);
FillRect(hDC, &fRect, hBrush);
}
/* Vertical scrollbar */
if (siScroll.cx > 0)
{
SetRect(&fRect, rcWin.right - siScroll.cx, rcWin.top, rcWin.right, bottom);
FillRect(hDC, &fRect, hBrush);
}
/*
* If both the horizontal and vertical scrollbars are present,
* draw the "dead square" at the bottom right.
*/
if (siScroll.cy > 0 && siScroll.cx > 0)
{
SetRect(&fRect, rcWin.right - siScroll.cx, rcWin.bottom - siScroll.cy, rcWin.right, rcWin.bottom);
FillRect(hDC, &fRect, hBrush);
}
// NOTE: If an additional exterior frame is needed, remove +1 for each direction
rcWin.right -= siScroll.cx;
rcWin.bottom -= siScroll.cy;
}
/* Draw the console background */
[CONSRV] - Introduce a "console configuration" library that is used by both CONSRV and the console properties applet so that they can share common code concerning getting/setting console registry properties. - Make use of the Windows-compatible (and undocumented) CONSOLE_STATE_INFO structure for that purpose (as well as the WM_SETCONSOLEINFO): see commits r63819 and r58415 and links within for more details. Note: this structure needs to be 4-byte packed (contrary to what it is said in almost all the links from above. The difference is only visible at the level of the last member that is the ConsoleTitle string array. This was tested on windows). - Simplify some parts of console settings initialization. - Some work is still needed concerning how to correctly retrieve the default console settings (without touching the ConsoleTitle member of CONSOLE_STATE_INFO, contrary to what we do currently). [CONSOLE.DLL] - Make the console properties applet windows-compatible, in the sense that you can now run it on win2k3 and use it instead of the windows one. This implies having the same strange hacks as windows' one, namely, that the window handle parameter of the CPlApplet entry point is either used as the caller (parent) window handle, OR, as a shared section handle to shared data with CONSRV. [KERNEL32] - Rework the console applet initialization accordingly. Also we reload each time the console.dll when opening the console applet, and then unload it: this "allows" to reset all the global variables that console.dll may (and does) have. svn path=/trunk/; revision=66867
2015-03-24 23:58:44 +00:00
hBrush = CreateSolidBrush(pConInfo->ColorTable[BkgdAttribFromAttrib(pConInfo->ScreenAttributes)]);
FillRect(hDC, &rcWin, hBrush);
DeleteObject(hBrush);
}
static LRESULT CALLBACK
WinPrevProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
PWINPREV_DATA pData;
pData = (PWINPREV_DATA)GetWindowLongPtrW(hWnd, GWLP_USERDATA);
switch (msg)
{
case WM_CREATE:
{
pData = (PWINPREV_DATA)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*pData));
if (!pData)
{
/* We failed to allocate our private data, halt the window creation */
return (LRESULT)-1;
}
pData->hWnd = hWnd;
pData->pData = ConInfo;
GetClientRect(pData->hWnd, &pData->rcMaxArea);
// LPCREATESTRUCT::cx and cy give window (not client) size
WinPrev_OnDisplayChange(pData);
SetWindowLongPtrW(hWnd, GWLP_USERDATA, (LONG_PTR)pData);
break;
}
case WM_DESTROY:
{
if (pData)
HeapFree(GetProcessHeap(), 0, pData);
break;
}
case WM_DISPLAYCHANGE:
{
WinPrev_OnDisplayChange(pData);
UpdateWindow(hWnd);
// InvalidateRect(hWnd, NULL, FALSE);
break;
}
case WM_SIZE:
break;
case WM_ERASEBKGND:
return 1;
case WM_PAINT:
{
PAINTSTRUCT ps;
BeginPaint(hWnd, &ps);
WinPrev_OnDraw(ps.hdc, pData);
EndPaint(hWnd, &ps);
return 0;
}
}
return DefWindowProcW(hWnd, msg, wParam, lParam);
}
/* CONSOLE TEXT PREVIEW *******************************************************/
const WCHAR szPreviewText[] =
L"C:\\ReactOS> dir \n" \
L"SYSTEM <DIR> 13-04-15 5:00a\n" \
L"SYSTEM32 <DIR> 13-04-15 5:00a\n" \
L"readme txt 1739 13-04-15 5:00a\n" \
L"explorer exe 3329536 13-04-15 5:00a\n" \
L"vgafonts cab 18736 13-04-15 5:00a\n" \
L"setuplog txt 313 13-04-15 5:00a\n" \
L"win ini 7005 13-04-15 5:00a\n" ;
VOID
PaintText(
IN LPDRAWITEMSTRUCT drawItem,
IN PCONSOLE_STATE_INFO pConInfo,
IN TEXT_TYPE TextMode)
{
USHORT CurrentAttrib;
COLORREF pbkColor, ptColor;
COLORREF nbkColor, ntColor;
HBRUSH hBrush;
[CONSOLE.CPL]: Rewrite the way we deal with console font samples in the console properties dialog: - Remove the font helper functions that were already moved into concfg/font.c in r74462, and use the latter instead. - Use a double list for listing the available font sizes for a given face: * a ListBox for raster fonts; * a ComboBox for TrueType fonts, allowing the user to specify a custom size. The raster ListBox is wrapped using the LIST_CTL structure so that we can use the bisection functions on it. - Allow the user to specify TrueType font size either in pixels or in points. Raster font sizes however are always in pixels. - Try to remember the nearest font size across different selected face changes. - Try to support custom-sized TrueType fonts (using the ComboBox's edit field). May need more improvements! - Retrieve the correct character cell height & width size in pixels when selecting a font (especially when it's a TrueType one). - We now support bold console fonts too, see CORE-13122 (thanks Katayama!). - Remove the commented-out "temporary code for future reference". - Use a global cached font "hCurrentFont" that gets initialized when the console properties applet is created, so that we now can have a correct font in the screen samples when one directly views e.g. the "Color" tab, without going first in the "Font" tab. This current font is of course updated whenever one changes the font settings. Tested with success on Windows 2003, Windows 7 and on ReactOS. CORE-13122 CORE-13182 #resolve svn path=/trunk/; revision=74469
2017-05-03 23:56:35 +00:00
HFONT hOldFont;
if (TextMode == Screen)
[CONSRV] - Introduce a "console configuration" library that is used by both CONSRV and the console properties applet so that they can share common code concerning getting/setting console registry properties. - Make use of the Windows-compatible (and undocumented) CONSOLE_STATE_INFO structure for that purpose (as well as the WM_SETCONSOLEINFO): see commits r63819 and r58415 and links within for more details. Note: this structure needs to be 4-byte packed (contrary to what it is said in almost all the links from above. The difference is only visible at the level of the last member that is the ConsoleTitle string array. This was tested on windows). - Simplify some parts of console settings initialization. - Some work is still needed concerning how to correctly retrieve the default console settings (without touching the ConsoleTitle member of CONSOLE_STATE_INFO, contrary to what we do currently). [CONSOLE.DLL] - Make the console properties applet windows-compatible, in the sense that you can now run it on win2k3 and use it instead of the windows one. This implies having the same strange hacks as windows' one, namely, that the window handle parameter of the CPlApplet entry point is either used as the caller (parent) window handle, OR, as a shared section handle to shared data with CONSRV. [KERNEL32] - Rework the console applet initialization accordingly. Also we reload each time the console.dll when opening the console applet, and then unload it: this "allows" to reset all the global variables that console.dll may (and does) have. svn path=/trunk/; revision=66867
2015-03-24 23:58:44 +00:00
CurrentAttrib = pConInfo->ScreenAttributes;
else if (TextMode == Popup)
[CONSRV] - Introduce a "console configuration" library that is used by both CONSRV and the console properties applet so that they can share common code concerning getting/setting console registry properties. - Make use of the Windows-compatible (and undocumented) CONSOLE_STATE_INFO structure for that purpose (as well as the WM_SETCONSOLEINFO): see commits r63819 and r58415 and links within for more details. Note: this structure needs to be 4-byte packed (contrary to what it is said in almost all the links from above. The difference is only visible at the level of the last member that is the ConsoleTitle string array. This was tested on windows). - Simplify some parts of console settings initialization. - Some work is still needed concerning how to correctly retrieve the default console settings (without touching the ConsoleTitle member of CONSOLE_STATE_INFO, contrary to what we do currently). [CONSOLE.DLL] - Make the console properties applet windows-compatible, in the sense that you can now run it on win2k3 and use it instead of the windows one. This implies having the same strange hacks as windows' one, namely, that the window handle parameter of the CPlApplet entry point is either used as the caller (parent) window handle, OR, as a shared section handle to shared data with CONSRV. [KERNEL32] - Rework the console applet initialization accordingly. Also we reload each time the console.dll when opening the console applet, and then unload it: this "allows" to reset all the global variables that console.dll may (and does) have. svn path=/trunk/; revision=66867
2015-03-24 23:58:44 +00:00
CurrentAttrib = pConInfo->PopupAttributes;
else
return;
[CONSRV] - Introduce a "console configuration" library that is used by both CONSRV and the console properties applet so that they can share common code concerning getting/setting console registry properties. - Make use of the Windows-compatible (and undocumented) CONSOLE_STATE_INFO structure for that purpose (as well as the WM_SETCONSOLEINFO): see commits r63819 and r58415 and links within for more details. Note: this structure needs to be 4-byte packed (contrary to what it is said in almost all the links from above. The difference is only visible at the level of the last member that is the ConsoleTitle string array. This was tested on windows). - Simplify some parts of console settings initialization. - Some work is still needed concerning how to correctly retrieve the default console settings (without touching the ConsoleTitle member of CONSOLE_STATE_INFO, contrary to what we do currently). [CONSOLE.DLL] - Make the console properties applet windows-compatible, in the sense that you can now run it on win2k3 and use it instead of the windows one. This implies having the same strange hacks as windows' one, namely, that the window handle parameter of the CPlApplet entry point is either used as the caller (parent) window handle, OR, as a shared section handle to shared data with CONSRV. [KERNEL32] - Rework the console applet initialization accordingly. Also we reload each time the console.dll when opening the console applet, and then unload it: this "allows" to reset all the global variables that console.dll may (and does) have. svn path=/trunk/; revision=66867
2015-03-24 23:58:44 +00:00
nbkColor = pConInfo->ColorTable[BkgdAttribFromAttrib(CurrentAttrib)];
ntColor = pConInfo->ColorTable[TextAttribFromAttrib(CurrentAttrib)];
hBrush = CreateSolidBrush(nbkColor);
if (!hBrush) return;
if (FontPreview.hFont == NULL)
RefreshFontPreview(&FontPreview, pConInfo);
hOldFont = SelectObject(drawItem->hDC, FontPreview.hFont);
[CONSOLE.CPL]: Rewrite the way we deal with console font samples in the console properties dialog: - Remove the font helper functions that were already moved into concfg/font.c in r74462, and use the latter instead. - Use a double list for listing the available font sizes for a given face: * a ListBox for raster fonts; * a ComboBox for TrueType fonts, allowing the user to specify a custom size. The raster ListBox is wrapped using the LIST_CTL structure so that we can use the bisection functions on it. - Allow the user to specify TrueType font size either in pixels or in points. Raster font sizes however are always in pixels. - Try to remember the nearest font size across different selected face changes. - Try to support custom-sized TrueType fonts (using the ComboBox's edit field). May need more improvements! - Retrieve the correct character cell height & width size in pixels when selecting a font (especially when it's a TrueType one). - We now support bold console fonts too, see CORE-13122 (thanks Katayama!). - Remove the commented-out "temporary code for future reference". - Use a global cached font "hCurrentFont" that gets initialized when the console properties applet is created, so that we now can have a correct font in the screen samples when one directly views e.g. the "Color" tab, without going first in the "Font" tab. This current font is of course updated whenever one changes the font settings. Tested with success on Windows 2003, Windows 7 and on ReactOS. CORE-13122 CORE-13182 #resolve svn path=/trunk/; revision=74469
2017-05-03 23:56:35 +00:00
//if (hOldFont == NULL)
//{
// DeleteObject(hBrush);
// return;
[CONSOLE.CPL]: Rewrite the way we deal with console font samples in the console properties dialog: - Remove the font helper functions that were already moved into concfg/font.c in r74462, and use the latter instead. - Use a double list for listing the available font sizes for a given face: * a ListBox for raster fonts; * a ComboBox for TrueType fonts, allowing the user to specify a custom size. The raster ListBox is wrapped using the LIST_CTL structure so that we can use the bisection functions on it. - Allow the user to specify TrueType font size either in pixels or in points. Raster font sizes however are always in pixels. - Try to remember the nearest font size across different selected face changes. - Try to support custom-sized TrueType fonts (using the ComboBox's edit field). May need more improvements! - Retrieve the correct character cell height & width size in pixels when selecting a font (especially when it's a TrueType one). - We now support bold console fonts too, see CORE-13122 (thanks Katayama!). - Remove the commented-out "temporary code for future reference". - Use a global cached font "hCurrentFont" that gets initialized when the console properties applet is created, so that we now can have a correct font in the screen samples when one directly views e.g. the "Color" tab, without going first in the "Font" tab. This current font is of course updated whenever one changes the font settings. Tested with success on Windows 2003, Windows 7 and on ReactOS. CORE-13122 CORE-13182 #resolve svn path=/trunk/; revision=74469
2017-05-03 23:56:35 +00:00
//}
FillRect(drawItem->hDC, &drawItem->rcItem, hBrush);
/* Add a few space between the preview window border and the text sample */
InflateRect(&drawItem->rcItem, -2, -2);
ptColor = SetTextColor(drawItem->hDC, ntColor);
pbkColor = SetBkColor(drawItem->hDC, nbkColor);
DrawTextW(drawItem->hDC, szPreviewText, (INT)wcslen(szPreviewText), &drawItem->rcItem, 0);
SetTextColor(drawItem->hDC, ptColor);
SetBkColor(drawItem->hDC, pbkColor);
[CONSOLE.CPL]: Rewrite the way we deal with console font samples in the console properties dialog: - Remove the font helper functions that were already moved into concfg/font.c in r74462, and use the latter instead. - Use a double list for listing the available font sizes for a given face: * a ListBox for raster fonts; * a ComboBox for TrueType fonts, allowing the user to specify a custom size. The raster ListBox is wrapped using the LIST_CTL structure so that we can use the bisection functions on it. - Allow the user to specify TrueType font size either in pixels or in points. Raster font sizes however are always in pixels. - Try to remember the nearest font size across different selected face changes. - Try to support custom-sized TrueType fonts (using the ComboBox's edit field). May need more improvements! - Retrieve the correct character cell height & width size in pixels when selecting a font (especially when it's a TrueType one). - We now support bold console fonts too, see CORE-13122 (thanks Katayama!). - Remove the commented-out "temporary code for future reference". - Use a global cached font "hCurrentFont" that gets initialized when the console properties applet is created, so that we now can have a correct font in the screen samples when one directly views e.g. the "Color" tab, without going first in the "Font" tab. This current font is of course updated whenever one changes the font settings. Tested with success on Windows 2003, Windows 7 and on ReactOS. CORE-13122 CORE-13182 #resolve svn path=/trunk/; revision=74469
2017-05-03 23:56:35 +00:00
SelectObject(drawItem->hDC, hOldFont);
DeleteObject(hBrush);
}
/* LAYOUT DIALOG **************************************************************/
INT_PTR
CALLBACK
LayoutProc(HWND hDlg,
[CONSOLE.DLL-KERNEL32-CONSRV] Fix the console properties dialog, when launching and transmitting console properties. Before, the properties dialog was directly launched by the console server (consrv), running with CSRSS (System) privileges, what constituted a security hole. Now, I create a remote thread in the running process owning the console for launching the properties dialog (thus it has only user privileges, and not System ones anymore). For that purpose, I basically took the technique described in the following paper (Cesar Cerrudo, "Story of a dumb patch", http://www.argeniss.com/research/MSBugPaper.pdf or http://www.scn.rain.com/~neighorn/PDF/MSBugPaper.pdf), where basically the console server shares the console properties via a shared memory section with the console properties dialog dll. The address of the thread which launches the dialog in the context of the console app is given to the console server the same way as we do for the control handler (called e.g. when you press Ctrl-C, etc...) Of course this is quite hackish, because you have the GUI interface split between the console server and the console properties dialog dll. Something far more elegant would be to put all the GUI thingie into a dedicated dll or exe, running with the same privileges as the console program itself (a kind of console -- or terminal -- emulator). [CONSOLE.DLL] Fix retriving / setting colors.c and other things. [CONSRV.DLL] - Fix retrieving / setting console properties from the registry (via the HKCU\Console\* keys), via the shell shortcuts (not totally done at the moment, because somebody has to implement properly that thing : http://msdn.microsoft.com/en-us/library/windows/desktop/bb773359(v=vs.85).aspx (NT_CONSOLE_PROPS structure stored as a shortcut data block) (at application launching time), and via the console properties dialog. - Few DPRINTs removed. svn path=/branches/ros-csrss/; revision=58415
2013-03-03 15:35:12 +00:00
UINT uMsg,
WPARAM wParam,
LPARAM lParam)
{
switch (uMsg)
{
case WM_INITDIALOG:
{
/* Multi-monitor support */
LONG xVirtScr, yVirtScr; // Coordinates of the top-left virtual screen
LONG cxVirtScr, cyVirtScr; // Width and Height of the virtual screen
LONG cxFrame , cyFrame ; // Thickness of the window frame
xVirtScr = GetSystemMetrics(SM_XVIRTUALSCREEN);
yVirtScr = GetSystemMetrics(SM_YVIRTUALSCREEN);
cxVirtScr = GetSystemMetrics(SM_CXVIRTUALSCREEN);
cyVirtScr = GetSystemMetrics(SM_CYVIRTUALSCREEN);
cxFrame = GetSystemMetrics(SM_CXFRAME);
cyFrame = GetSystemMetrics(SM_CYFRAME);
SendDlgItemMessageW(hDlg, IDC_UPDOWN_SCREEN_BUFFER_HEIGHT, UDM_SETRANGE, 0, (LPARAM)MAKELONG(9999, 1));
SendDlgItemMessageW(hDlg, IDC_UPDOWN_SCREEN_BUFFER_WIDTH , UDM_SETRANGE, 0, (LPARAM)MAKELONG(9999, 1));
SendDlgItemMessageW(hDlg, IDC_UPDOWN_WINDOW_SIZE_HEIGHT, UDM_SETRANGE, 0, (LPARAM)MAKELONG(9999, 1));
SendDlgItemMessageW(hDlg, IDC_UPDOWN_WINDOW_SIZE_WIDTH , UDM_SETRANGE, 0, (LPARAM)MAKELONG(9999, 1));
SetDlgItemInt(hDlg, IDC_EDIT_SCREEN_BUFFER_HEIGHT, ConInfo->ScreenBufferSize.Y, FALSE);
SetDlgItemInt(hDlg, IDC_EDIT_SCREEN_BUFFER_WIDTH , ConInfo->ScreenBufferSize.X, FALSE);
SetDlgItemInt(hDlg, IDC_EDIT_WINDOW_SIZE_HEIGHT, ConInfo->WindowSize.Y, FALSE);
SetDlgItemInt(hDlg, IDC_EDIT_WINDOW_SIZE_WIDTH , ConInfo->WindowSize.X, FALSE);
SendDlgItemMessageW(hDlg, IDC_UPDOWN_WINDOW_POS_LEFT, UDM_SETRANGE, 0,
(LPARAM)MAKELONG(xVirtScr + cxVirtScr - cxFrame, xVirtScr - cxFrame));
SendDlgItemMessageW(hDlg, IDC_UPDOWN_WINDOW_POS_TOP , UDM_SETRANGE, 0,
(LPARAM)MAKELONG(yVirtScr + cyVirtScr - cyFrame, yVirtScr - cyFrame));
SetDlgItemInt(hDlg, IDC_EDIT_WINDOW_POS_LEFT, ConInfo->WindowPosition.x, TRUE);
SetDlgItemInt(hDlg, IDC_EDIT_WINDOW_POS_TOP , ConInfo->WindowPosition.y, TRUE);
[CONSRV] - Introduce a "console configuration" library that is used by both CONSRV and the console properties applet so that they can share common code concerning getting/setting console registry properties. - Make use of the Windows-compatible (and undocumented) CONSOLE_STATE_INFO structure for that purpose (as well as the WM_SETCONSOLEINFO): see commits r63819 and r58415 and links within for more details. Note: this structure needs to be 4-byte packed (contrary to what it is said in almost all the links from above. The difference is only visible at the level of the last member that is the ConsoleTitle string array. This was tested on windows). - Simplify some parts of console settings initialization. - Some work is still needed concerning how to correctly retrieve the default console settings (without touching the ConsoleTitle member of CONSOLE_STATE_INFO, contrary to what we do currently). [CONSOLE.DLL] - Make the console properties applet windows-compatible, in the sense that you can now run it on win2k3 and use it instead of the windows one. This implies having the same strange hacks as windows' one, namely, that the window handle parameter of the CPlApplet entry point is either used as the caller (parent) window handle, OR, as a shared section handle to shared data with CONSRV. [KERNEL32] - Rework the console applet initialization accordingly. Also we reload each time the console.dll when opening the console applet, and then unload it: this "allows" to reset all the global variables that console.dll may (and does) have. svn path=/trunk/; revision=66867
2015-03-24 23:58:44 +00:00
if (ConInfo->AutoPosition)
{
EnableDlgItem(hDlg, IDC_EDIT_WINDOW_POS_LEFT, FALSE);
EnableDlgItem(hDlg, IDC_EDIT_WINDOW_POS_TOP , FALSE);
EnableDlgItem(hDlg, IDC_UPDOWN_WINDOW_POS_LEFT, FALSE);
EnableDlgItem(hDlg, IDC_UPDOWN_WINDOW_POS_TOP , FALSE);
}
CheckDlgButton(hDlg, IDC_CHECK_SYSTEM_POS_WINDOW,
[CONSRV] - Introduce a "console configuration" library that is used by both CONSRV and the console properties applet so that they can share common code concerning getting/setting console registry properties. - Make use of the Windows-compatible (and undocumented) CONSOLE_STATE_INFO structure for that purpose (as well as the WM_SETCONSOLEINFO): see commits r63819 and r58415 and links within for more details. Note: this structure needs to be 4-byte packed (contrary to what it is said in almost all the links from above. The difference is only visible at the level of the last member that is the ConsoleTitle string array. This was tested on windows). - Simplify some parts of console settings initialization. - Some work is still needed concerning how to correctly retrieve the default console settings (without touching the ConsoleTitle member of CONSOLE_STATE_INFO, contrary to what we do currently). [CONSOLE.DLL] - Make the console properties applet windows-compatible, in the sense that you can now run it on win2k3 and use it instead of the windows one. This implies having the same strange hacks as windows' one, namely, that the window handle parameter of the CPlApplet entry point is either used as the caller (parent) window handle, OR, as a shared section handle to shared data with CONSRV. [KERNEL32] - Rework the console applet initialization accordingly. Also we reload each time the console.dll when opening the console applet, and then unload it: this "allows" to reset all the global variables that console.dll may (and does) have. svn path=/trunk/; revision=66867
2015-03-24 23:58:44 +00:00
ConInfo->AutoPosition ? BST_CHECKED : BST_UNCHECKED);
return TRUE;
}
case WM_DISPLAYCHANGE:
{
/* Retransmit to the preview window */
SendDlgItemMessageW(hDlg, IDC_STATIC_LAYOUT_WINDOW_PREVIEW,
WM_DISPLAYCHANGE, wParam, lParam);
break;
}
case WM_NOTIFY:
{
LPPSHNOTIFY lppsn = (LPPSHNOTIFY)lParam;
if (lppsn->hdr.code == UDN_DELTAPOS)
{
LPNMUPDOWN lpnmud = (LPNMUPDOWN)lParam;
DWORD wheight, wwidth;
DWORD sheight, swidth;
DWORD left, top;
if (lppsn->hdr.idFrom == IDC_UPDOWN_WINDOW_SIZE_WIDTH)
{
wwidth = lpnmud->iPos + lpnmud->iDelta;
}
else
{
wwidth = GetDlgItemInt(hDlg, IDC_EDIT_WINDOW_SIZE_WIDTH, NULL, FALSE);
}
if (lppsn->hdr.idFrom == IDC_UPDOWN_WINDOW_SIZE_HEIGHT)
{
wheight = lpnmud->iPos + lpnmud->iDelta;
}
else
{
wheight = GetDlgItemInt(hDlg, IDC_EDIT_WINDOW_SIZE_HEIGHT, NULL, FALSE);
}
if (lppsn->hdr.idFrom == IDC_UPDOWN_SCREEN_BUFFER_WIDTH)
{
swidth = lpnmud->iPos + lpnmud->iDelta;
}
else
{
swidth = GetDlgItemInt(hDlg, IDC_EDIT_SCREEN_BUFFER_WIDTH, NULL, FALSE);
}
if (lppsn->hdr.idFrom == IDC_UPDOWN_SCREEN_BUFFER_HEIGHT)
{
sheight = lpnmud->iPos + lpnmud->iDelta;
}
else
{
sheight = GetDlgItemInt(hDlg, IDC_EDIT_SCREEN_BUFFER_HEIGHT, NULL, FALSE);
}
if (lppsn->hdr.idFrom == IDC_UPDOWN_WINDOW_POS_LEFT)
{
left = lpnmud->iPos + lpnmud->iDelta;
}
else
{
left = GetDlgItemInt(hDlg, IDC_EDIT_WINDOW_POS_LEFT, NULL, TRUE);
}
if (lppsn->hdr.idFrom == IDC_UPDOWN_WINDOW_POS_TOP)
{
top = lpnmud->iPos + lpnmud->iDelta;
}
else
{
top = GetDlgItemInt(hDlg, IDC_EDIT_WINDOW_POS_TOP, NULL, TRUE);
}
if (lppsn->hdr.idFrom == IDC_UPDOWN_WINDOW_SIZE_WIDTH || lppsn->hdr.idFrom == IDC_UPDOWN_WINDOW_SIZE_HEIGHT)
{
/* Automatically adjust screen buffer size when window size enlarges */
if (wwidth >= swidth)
{
SetDlgItemInt(hDlg, IDC_EDIT_SCREEN_BUFFER_WIDTH, wwidth, TRUE);
swidth = wwidth;
}
if (wheight >= sheight)
{
SetDlgItemInt(hDlg, IDC_EDIT_SCREEN_BUFFER_HEIGHT, wheight, TRUE);
sheight = wheight;
}
}
/* Be sure that the (new) screen buffer sizes are in the correct range */
[CONSOLE.CPL-KERNEL32] Fix some compilation warnings with MSVC. [KERNEL32-CONSRV] - Implement console graphics screen buffers, as described in http://blog.airesoft.co.uk/2012/10/things-ms-can-do-that-they-dont-tell-you-about-console-graphics/ . The idea is that the console server creates a memory shared section to be shared with the client console application (it increases performance). A mutex is used to "say" to the console server that he can repaint the screen. The function InvalidateConsoleDIBits is implemented too. The definition of the structure CONSOLE_GRAPHICS_BUFFER_INFO comes directly from the site. - CreateConsoleScreenBuffer was modified to be able to create such buffers. This is needed for a working NTVDM-like application. [CONSRV] - Rework the console buffer structures so that text-mode buffers and graphics-mode buffers can "inherit" from an "abstract" structure, CONSOLE_SCREEN_BUFFER. Add few helper functions for manipulating them. - Reorganize the output code in "graphics.c" and "text.c" files to separate text-mode only code from graphics-mode only code, both in the console server and in the GUI front-end. Other fixes: - Fix mouse handling (left and right clicks when one goes away from the "Selection" mode); do not handle mouse signal when we reactivate the GUI front-end window by a click. - Fix GetLargestConsoleWindowSize API in console server side. Now pressing Alt+F9 in Far Manager to "change" the "video" mode works correctly. Finally: - Start to implement a (fake, i.e. not using directly a VGA driver) console fullscreen mode. Currently Alt-Enter key presses call a stub which just alternates DPRINTing between "switch to fullscreen mode" and "switch to windowed mode". Images here: - Example of an application (a 16-bit emulator by Mysoft) which uses the console graphics screen-buffer functionality: http://img577.imageshack.us/img577/1693/mysoftemulatorargon.png - A potpourri of console applications which use graphics screen-buffers: http://img571.imageshack.us/img571/6526/consoledelirium.png Enjoy :) svn path=/trunk/; revision=59099
2013-05-29 00:29:07 +00:00
swidth = min(max(swidth , 1), 0xFFFF);
sheight = min(max(sheight, 1), 0xFFFF);
if (lppsn->hdr.idFrom == IDC_UPDOWN_SCREEN_BUFFER_WIDTH || lppsn->hdr.idFrom == IDC_UPDOWN_SCREEN_BUFFER_HEIGHT)
{
/* Automatically adjust window size when screen buffer decreases */
if (wwidth > swidth)
{
SetDlgItemInt(hDlg, IDC_EDIT_WINDOW_SIZE_WIDTH, swidth, TRUE);
wwidth = swidth;
}
if (wheight > sheight)
{
SetDlgItemInt(hDlg, IDC_EDIT_WINDOW_SIZE_HEIGHT, sheight, TRUE);
wheight = sheight;
}
}
[CONSRV] - Introduce a "console configuration" library that is used by both CONSRV and the console properties applet so that they can share common code concerning getting/setting console registry properties. - Make use of the Windows-compatible (and undocumented) CONSOLE_STATE_INFO structure for that purpose (as well as the WM_SETCONSOLEINFO): see commits r63819 and r58415 and links within for more details. Note: this structure needs to be 4-byte packed (contrary to what it is said in almost all the links from above. The difference is only visible at the level of the last member that is the ConsoleTitle string array. This was tested on windows). - Simplify some parts of console settings initialization. - Some work is still needed concerning how to correctly retrieve the default console settings (without touching the ConsoleTitle member of CONSOLE_STATE_INFO, contrary to what we do currently). [CONSOLE.DLL] - Make the console properties applet windows-compatible, in the sense that you can now run it on win2k3 and use it instead of the windows one. This implies having the same strange hacks as windows' one, namely, that the window handle parameter of the CPlApplet entry point is either used as the caller (parent) window handle, OR, as a shared section handle to shared data with CONSRV. [KERNEL32] - Rework the console applet initialization accordingly. Also we reload each time the console.dll when opening the console applet, and then unload it: this "allows" to reset all the global variables that console.dll may (and does) have. svn path=/trunk/; revision=66867
2015-03-24 23:58:44 +00:00
ConInfo->ScreenBufferSize.X = (SHORT)swidth;
ConInfo->ScreenBufferSize.Y = (SHORT)sheight;
ConInfo->WindowSize.X = (SHORT)wwidth;
ConInfo->WindowSize.Y = (SHORT)wheight;
ConInfo->WindowPosition.x = left;
ConInfo->WindowPosition.y = top;
InvalidateRect(GetDlgItem(hDlg, IDC_STATIC_LAYOUT_WINDOW_PREVIEW), NULL, TRUE);
PropSheet_Changed(GetParent(hDlg), hDlg);
}
break;
}
case WM_COMMAND:
{
if (HIWORD(wParam) == EN_KILLFOCUS)
{
switch (LOWORD(wParam))
{
case IDC_EDIT_SCREEN_BUFFER_WIDTH:
{
DWORD swidth, wwidth;
swidth = GetDlgItemInt(hDlg, IDC_EDIT_SCREEN_BUFFER_WIDTH, NULL, FALSE);
wwidth = GetDlgItemInt(hDlg, IDC_EDIT_WINDOW_SIZE_WIDTH , NULL, FALSE);
/* Be sure that the (new) screen buffer width is in the correct range */
swidth = min(max(swidth, 1), 0xFFFF);
/* Automatically adjust window size when screen buffer decreases */
if (wwidth > swidth)
{
wwidth = swidth;
SetDlgItemInt(hDlg, IDC_EDIT_WINDOW_SIZE_WIDTH, wwidth, TRUE);
}
ConInfo->ScreenBufferSize.X = (SHORT)swidth;
ConInfo->WindowSize.X = (SHORT)wwidth;
InvalidateRect(GetDlgItem(hDlg, IDC_STATIC_LAYOUT_WINDOW_PREVIEW), NULL, TRUE);
PropSheet_Changed(GetParent(hDlg), hDlg);
break;
}
case IDC_EDIT_WINDOW_SIZE_WIDTH:
{
DWORD swidth, wwidth;
swidth = GetDlgItemInt(hDlg, IDC_EDIT_SCREEN_BUFFER_WIDTH, NULL, FALSE);
wwidth = GetDlgItemInt(hDlg, IDC_EDIT_WINDOW_SIZE_WIDTH , NULL, FALSE);
/* Automatically adjust screen buffer size when window size enlarges */
if (wwidth >= swidth)
{
swidth = wwidth;
/* Be sure that the (new) screen buffer width is in the correct range */
swidth = min(max(swidth, 1), 0xFFFF);
SetDlgItemInt(hDlg, IDC_EDIT_SCREEN_BUFFER_WIDTH, swidth, TRUE);
}
ConInfo->ScreenBufferSize.X = (SHORT)swidth;
ConInfo->WindowSize.X = (SHORT)wwidth;
InvalidateRect(GetDlgItem(hDlg, IDC_STATIC_LAYOUT_WINDOW_PREVIEW), NULL, TRUE);
PropSheet_Changed(GetParent(hDlg), hDlg);
break;
}
case IDC_EDIT_SCREEN_BUFFER_HEIGHT:
{
DWORD sheight, wheight;
sheight = GetDlgItemInt(hDlg, IDC_EDIT_SCREEN_BUFFER_HEIGHT, NULL, FALSE);
wheight = GetDlgItemInt(hDlg, IDC_EDIT_WINDOW_SIZE_HEIGHT , NULL, FALSE);
/* Be sure that the (new) screen buffer width is in the correct range */
sheight = min(max(sheight, 1), 0xFFFF);
/* Automatically adjust window size when screen buffer decreases */
if (wheight > sheight)
{
wheight = sheight;
SetDlgItemInt(hDlg, IDC_EDIT_WINDOW_SIZE_HEIGHT, wheight, TRUE);
}
ConInfo->ScreenBufferSize.Y = (SHORT)sheight;
ConInfo->WindowSize.Y = (SHORT)wheight;
InvalidateRect(GetDlgItem(hDlg, IDC_STATIC_LAYOUT_WINDOW_PREVIEW), NULL, TRUE);
PropSheet_Changed(GetParent(hDlg), hDlg);
break;
}
case IDC_EDIT_WINDOW_SIZE_HEIGHT:
{
DWORD sheight, wheight;
sheight = GetDlgItemInt(hDlg, IDC_EDIT_SCREEN_BUFFER_HEIGHT, NULL, FALSE);
wheight = GetDlgItemInt(hDlg, IDC_EDIT_WINDOW_SIZE_HEIGHT , NULL, FALSE);
/* Automatically adjust screen buffer size when window size enlarges */
if (wheight >= sheight)
{
sheight = wheight;
/* Be sure that the (new) screen buffer width is in the correct range */
sheight = min(max(sheight, 1), 0xFFFF);
SetDlgItemInt(hDlg, IDC_EDIT_SCREEN_BUFFER_HEIGHT, sheight, TRUE);
}
ConInfo->ScreenBufferSize.Y = (SHORT)sheight;
ConInfo->WindowSize.Y = (SHORT)wheight;
InvalidateRect(GetDlgItem(hDlg, IDC_STATIC_LAYOUT_WINDOW_PREVIEW), NULL, TRUE);
PropSheet_Changed(GetParent(hDlg), hDlg);
break;
}
case IDC_EDIT_WINDOW_POS_LEFT:
case IDC_EDIT_WINDOW_POS_TOP:
{
ConInfo->WindowPosition.x = GetDlgItemInt(hDlg, IDC_EDIT_WINDOW_POS_LEFT, NULL, TRUE);
ConInfo->WindowPosition.y = GetDlgItemInt(hDlg, IDC_EDIT_WINDOW_POS_TOP , NULL, TRUE);
InvalidateRect(GetDlgItem(hDlg, IDC_STATIC_LAYOUT_WINDOW_PREVIEW), NULL, TRUE);
PropSheet_Changed(GetParent(hDlg), hDlg);
break;
}
}
}
else
if (HIWORD(wParam) == BN_CLICKED &&
LOWORD(wParam) == IDC_CHECK_SYSTEM_POS_WINDOW)
{
if (IsDlgButtonChecked(hDlg, IDC_CHECK_SYSTEM_POS_WINDOW) == BST_CHECKED)
{
EnableDlgItem(hDlg, IDC_EDIT_WINDOW_POS_LEFT, FALSE);
EnableDlgItem(hDlg, IDC_EDIT_WINDOW_POS_TOP , FALSE);
EnableDlgItem(hDlg, IDC_UPDOWN_WINDOW_POS_LEFT, FALSE);
EnableDlgItem(hDlg, IDC_UPDOWN_WINDOW_POS_TOP , FALSE);
ConInfo->AutoPosition = TRUE;
// Do not touch ConInfo->WindowPosition !!
InvalidateRect(GetDlgItem(hDlg, IDC_STATIC_LAYOUT_WINDOW_PREVIEW), NULL, TRUE);
PropSheet_Changed(GetParent(hDlg), hDlg);
}
else
{
ULONG left, top;
left = GetDlgItemInt(hDlg, IDC_EDIT_WINDOW_POS_LEFT, NULL, TRUE);
top = GetDlgItemInt(hDlg, IDC_EDIT_WINDOW_POS_TOP , NULL, TRUE);
EnableDlgItem(hDlg, IDC_EDIT_WINDOW_POS_LEFT, TRUE);
EnableDlgItem(hDlg, IDC_EDIT_WINDOW_POS_TOP , TRUE);
EnableDlgItem(hDlg, IDC_UPDOWN_WINDOW_POS_LEFT, TRUE);
EnableDlgItem(hDlg, IDC_UPDOWN_WINDOW_POS_TOP , TRUE);
ConInfo->AutoPosition = FALSE;
ConInfo->WindowPosition.x = left;
ConInfo->WindowPosition.y = top;
InvalidateRect(GetDlgItem(hDlg, IDC_STATIC_LAYOUT_WINDOW_PREVIEW), NULL, TRUE);
PropSheet_Changed(GetParent(hDlg), hDlg);
}
}
break;
}
default:
break;
}
return FALSE;
}