reactos/modules/rostests/apitests/kernel32/SetConsoleWindowInfo.c
2017-12-13 13:48:26 +01:00

356 lines
16 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* PROJECT: ReactOS api tests
* LICENSE: GPLv2+ - See COPYING in the top level directory
* PURPOSE: Test for SetConsoleWindowInfo
* PROGRAMMER: Hermes Belusca-Maito
*/
#include "precomp.h"
static VOID
ResizeTextConsole(
IN HANDLE hConOut,
IN OUT PCONSOLE_SCREEN_BUFFER_INFO pcsbi,
IN COORD Resolution,
IN PSMALL_RECT WindowSize OPTIONAL)
{
BOOL Success;
SMALL_RECT ConRect;
if (Resolution.X != pcsbi->dwSize.X || Resolution.Y != pcsbi->dwSize.Y)
{
SHORT oldWidth, oldHeight;
oldWidth = pcsbi->srWindow.Right - pcsbi->srWindow.Left + 1;
oldHeight = pcsbi->srWindow.Bottom - pcsbi->srWindow.Top + 1;
/*
* If the current console window is too large for
* the new screen buffer, resize it first.
*/
if (oldWidth > Resolution.X || oldHeight > Resolution.Y)
{
ConRect.Left = ConRect.Top = 0;
ConRect.Right = ConRect.Left + min(oldWidth , Resolution.X) - 1;
ConRect.Bottom = ConRect.Top + min(oldHeight, Resolution.Y) - 1;
Success = SetConsoleWindowInfo(hConOut, TRUE, &ConRect);
ok(Success, "Setting console wnd info failed with last error error %lu\n", GetLastError());
}
/* Now resize the screen buffer */
Success = SetConsoleScreenBufferSize(hConOut, Resolution);
ok(Success, "Setting console SB size failed with last error error %lu\n", GetLastError());
/*
* Setting a new screen buffer size can change other information,
* so update the saved console information.
*/
Success = GetConsoleScreenBufferInfo(hConOut, pcsbi);
ok(Success, "Getting SB info\n");
}
if (!WindowSize)
{
/* Always resize the console window within the permitted maximum size */
ConRect.Left = 0;
ConRect.Right = ConRect.Left + min(Resolution.X, pcsbi->dwMaximumWindowSize.X) - 1;
ConRect.Bottom = min(pcsbi->dwCursorPosition.Y, Resolution.Y - 1);
ConRect.Top = ConRect.Bottom - min(Resolution.Y, pcsbi->dwMaximumWindowSize.Y) + 1;
}
else
{
/* Resize the console window according to user's wishes */
ConRect.Left = ConRect.Top = 0;
ConRect.Right = ConRect.Left + WindowSize->Right - WindowSize->Left;
ConRect.Bottom = ConRect.Top + WindowSize->Bottom - WindowSize->Top ;
}
Success = SetConsoleWindowInfo(hConOut, TRUE, &ConRect);
ok(Success, "Setting console wnd info failed with last error error %lu\n", GetLastError());
/* Update console screen buffer info */
Success = GetConsoleScreenBufferInfo(hConOut, pcsbi);
ok(Success, "Getting SB info\n");
}
START_TEST(SetConsoleWindowInfo)
{
/*
* The aim of this test is to show that what MSDN says about the validity
* checks performed on the window size rect given to SetConsoleWindowInfo
* is partially wrong.
*
* Indeed, while it is claimed that:
* "The function fails if the specified window rectangle extends beyond
* the boundaries of the console screen buffer. This means that the Top
* and Left members of the lpConsoleWindow rectangle (or the calculated
* top and left coordinates, if bAbsolute is FALSE) cannot be less than
* zero. Similarly, the Bottom and Right members (or the calculated
* bottom and right coordinates) cannot be greater than (screen buffer
* height 1) and (screen buffer width 1), respectively. The function
* also fails if the Right member (or calculated right coordinate) is
* less than or equal to the Left member (or calculated left coordinate)
* or if the Bottom member (or calculated bottom coordinate) is less than
* or equal to the Top member (or calculated top coordinate)."
*
* the really performed tests are fewer, and it appears that the console
* subsystem knows how to take proper actions when the window size rect
* has e.g. negative left/top coordinates...
*
* NOTE that we all perform those tests in "absolute mode" (second parameter
* of SetConsoleWindowInfo being TRUE), so that the specified window size rect
* is in absolute coordinates (i.e. relative to the console screen buffer),
* and not in coordinates relative to the current window-corner coordinates.
*/
BOOL Success;
DWORD dwLastError;
HANDLE hConOut;
COORD Resolution;
CONSOLE_SCREEN_BUFFER_INFO org_csbi, csbi, csbi2;
SMALL_RECT ConRect;
/* First, retrieve a handle to the real console output, even if we are redirected */
hConOut = CreateFileW(L"CONOUT$", GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0);
ok(hConOut != INVALID_HANDLE_VALUE, "Opening ConOut\n");
if (hConOut == INVALID_HANDLE_VALUE)
return; // We cannot run this test if we failed...
/*
* Retrieve the original console screen buffer info and save it
* for restoration at the end of the test. Use a copy after then.
*/
Success = GetConsoleScreenBufferInfo(hConOut, &org_csbi);
ok(Success, "Getting SB info\n");
if (!Success)
goto Cleanup; // We cannot as well run this test if we failed...
csbi = org_csbi;
/*
* Set the console screen buffer to a correct size that should not
* completely fill the computer screen. 'csbi' is correctly updated.
*/
Resolution.X = 80;
Resolution.Y = 25;
ResizeTextConsole(hConOut, &csbi, Resolution, NULL);
/* Test 1: Resize the console window to its possible maximum size (succeeds) */
ConRect.Left = ConRect.Top = 0;
ConRect.Right = ConRect.Left + min(csbi.dwSize.X, csbi.dwMaximumWindowSize.X) - 1;
ConRect.Bottom = ConRect.Top + min(csbi.dwSize.Y, csbi.dwMaximumWindowSize.Y) - 1;
SetLastError(0xdeadbeef);
Success = SetConsoleWindowInfo(hConOut, TRUE, &ConRect);
dwLastError = GetLastError();
ok(Success, "Setting console wnd info\n");
ok(dwLastError != ERROR_INVALID_PARAMETER, "GetLastError: %lu\n", dwLastError);
/* Test 2: Set negative Left/Top members, but correct Right/Bottom ones.
* The Left/Top members are shifted to zero while the Right/Bottom ones
* are shifted too in accordance.
* Situation where the Right/Bottom members will be ok after the shift
* (succeeds, disagrees with MSDN) */
ConRect.Left = ConRect.Top = -5;
ConRect.Right = csbi.dwSize.X - 7;
ConRect.Bottom = csbi.dwSize.Y - 7;
// Expected result: ConRect.Left == ConRect.Top == 0 and
// ConRect.Right == csbi.dwSize.X - 2, ConRect.Bottom == csbi.dwSize.Y - 2;
SetLastError(0xdeadbeef);
Success = SetConsoleWindowInfo(hConOut, TRUE, &ConRect);
dwLastError = GetLastError();
ok(Success, "Setting console wnd info should have succeeded!\n");
ok(dwLastError != ERROR_INVALID_PARAMETER, "GetLastError: %lu\n", dwLastError);
/* Check the new reported window size rect */
Success = GetConsoleScreenBufferInfo(hConOut, &csbi2);
ok(Success, "Getting SB info\n");
if (Success)
{
ConRect.Right -= ConRect.Left;
ConRect.Left = 0;
ConRect.Bottom -= ConRect.Top;
ConRect.Top = 0;
ok(csbi2.srWindow.Left == ConRect.Left, "srWindow.Left = %d, expected %d\n",
csbi2.srWindow.Left, ConRect.Left);
ok(csbi2.srWindow.Top == ConRect.Top, "srWindow.Top = %d, expected %d\n",
csbi2.srWindow.Top, ConRect.Top);
ok(csbi2.srWindow.Right == ConRect.Right, "srWindow.Right = %d, expected %d\n",
csbi2.srWindow.Right, ConRect.Right);
ok(csbi2.srWindow.Bottom == ConRect.Bottom, "srWindow.Bottom = %d, expected %d\n",
csbi2.srWindow.Bottom, ConRect.Bottom);
}
/* Test 3: Similar to Test 2, but set the Right/Bottom members too large
* with respect to the screen buffer size, so that after their shift, they
* are still too large (fails, agrees with MSDN) */
ConRect.Left = ConRect.Top = -5;
ConRect.Right = csbi.dwSize.X + 2; // Bigger than SB size
ConRect.Bottom = csbi.dwSize.Y + 2; // Bigger than SB size
SetLastError(0xdeadbeef);
Success = SetConsoleWindowInfo(hConOut, TRUE, &ConRect);
dwLastError = GetLastError();
ok(!Success, "Setting console wnd info should have failed!\n");
ok(dwLastError == ERROR_INVALID_PARAMETER, "GetLastError: expecting %u got %lu\n",
ERROR_INVALID_PARAMETER, dwLastError);
/* Check the new reported window size rect */
Success = GetConsoleScreenBufferInfo(hConOut, &csbi2);
ok(Success, "Getting SB info\n");
if (Success)
{
/* NOTE that here we compare against the old csbi data! */
ok(csbi2.srWindow.Left == 0, "srWindow.Left = %d, expected %d\n",
csbi2.srWindow.Left, 0);
ok(csbi2.srWindow.Top == 0, "srWindow.Top = %d, expected %d\n",
csbi2.srWindow.Top, 0);
ok(csbi2.srWindow.Right == csbi.dwSize.X - 2, "srWindow.Right = %d, expected %d\n",
csbi2.srWindow.Right, csbi.dwSize.X - 2);
ok(csbi2.srWindow.Bottom == csbi.dwSize.Y - 2, "srWindow.Bottom = %d, expected %d\n",
csbi2.srWindow.Bottom, csbi.dwSize.Y - 2);
}
/* Test 4: Similar to Tests 2 and 3, but we here just check what happens for
* the Right/Bottom members when they are too large, without caring about the
* Left/Top members (the latter being set to valid values this time)
* (fails, agrees with MSDN) */
ConRect.Left = ConRect.Top = 2; // OK
ConRect.Right = csbi.dwSize.X + 7; // Bigger than SB size
ConRect.Bottom = csbi.dwSize.Y + 7; // Bigger than SB size
SetLastError(0xdeadbeef);
Success = SetConsoleWindowInfo(hConOut, TRUE, &ConRect);
dwLastError = GetLastError();
ok(!Success, "Setting console wnd info should have failed!\n");
ok(dwLastError == ERROR_INVALID_PARAMETER, "GetLastError: expecting %u got %lu\n",
ERROR_INVALID_PARAMETER, dwLastError);
/* Check the new reported window size rect */
Success = GetConsoleScreenBufferInfo(hConOut, &csbi2);
ok(Success, "Getting SB info\n");
if (Success)
{
ok(csbi2.srWindow.Left == 0, "srWindow.Left = %d, expected %d\n",
csbi2.srWindow.Left, 0);
ok(csbi2.srWindow.Top == 0, "srWindow.Top = %d, expected %d\n",
csbi2.srWindow.Top, 0);
/* NOTE that here we compare against the old csbi data! */
ok(csbi2.srWindow.Right == csbi.dwSize.X - 2, "srWindow.Right = %d, expected %d\n",
csbi2.srWindow.Right, csbi.dwSize.X - 2);
ok(csbi2.srWindow.Bottom == csbi.dwSize.Y - 2, "srWindow.Bottom = %d, expected %d\n",
csbi2.srWindow.Bottom, csbi.dwSize.Y - 2);
}
/* Test 5: Set Right/Bottom members strictly smaller than Left/Top members
* (fails, agrees with MSDN) */
ConRect.Left = csbi.dwSize.X - 5;
ConRect.Right = 0;
ConRect.Top = csbi.dwSize.Y - 5;
ConRect.Bottom = 0;
SetLastError(0xdeadbeef);
Success = SetConsoleWindowInfo(hConOut, TRUE, &ConRect);
dwLastError = GetLastError();
ok(!Success, "Setting console wnd info should have failed!\n");
ok(dwLastError == ERROR_INVALID_PARAMETER, "GetLastError: expecting %u got %lu\n",
ERROR_INVALID_PARAMETER, dwLastError);
/* Test 6: Set Left/Top members equal to the Right/Bottom members respectively
* (succeeds, disagrees with MSDN) */
ConRect.Left = ConRect.Right = 2;
ConRect.Top = ConRect.Bottom = 5;
SetLastError(0xdeadbeef);
Success = SetConsoleWindowInfo(hConOut, TRUE, &ConRect);
dwLastError = GetLastError();
ok(Success, "Setting console wnd info should have succeeded!\n");
ok(dwLastError != ERROR_INVALID_PARAMETER, "GetLastError: %lu\n", dwLastError);
/* Check the new reported window size rect */
Success = GetConsoleScreenBufferInfo(hConOut, &csbi2);
ok(Success, "Getting SB info\n");
if (Success)
{
ok(csbi2.srWindow.Left == ConRect.Left, "srWindow.Left = %d, expected %d\n",
csbi2.srWindow.Left, ConRect.Left);
ok(csbi2.srWindow.Top == ConRect.Top, "srWindow.Top = %d, expected %d\n",
csbi2.srWindow.Top, ConRect.Top);
ok(csbi2.srWindow.Right == ConRect.Right, "srWindow.Right = %d, expected %d\n",
csbi2.srWindow.Right, ConRect.Right);
ok(csbi2.srWindow.Bottom == ConRect.Bottom, "srWindow.Bottom = %d, expected %d\n",
csbi2.srWindow.Bottom, ConRect.Bottom);
}
/*
* Test 7: Test how large can the console window be, for a given
* screen buffer size. For that we set the console screen buffer
* to a really large size, hoping that its corresponding window size
* is larger than the computer screen. The permitted maximum window
* size specified in csbi.dwMaximumWindowSize should be a boundary.
*/
Resolution.X = 500;
Resolution.Y = 500;
ResizeTextConsole(hConOut, &csbi, Resolution, NULL);
/* Be sure that csbi.dwMaximumWindowSize is strictly smaller
* than the console screen buffer size, for our matters... */
ok((csbi.dwMaximumWindowSize.X < Resolution.X) && (csbi.dwMaximumWindowSize.Y < Resolution.Y),
"dwMaximumWindowSize = {%d, %d} was expected to be smaller than Resolution = {%d, %d}\n",
csbi.dwMaximumWindowSize.X, csbi.dwMaximumWindowSize.Y, Resolution.X, Resolution.Y);
/* Now try to set first the console window to a size smaller than the maximum size */
ConRect.Left = ConRect.Top = 0;
ConRect.Right = csbi.dwMaximumWindowSize.X - 1;
ConRect.Bottom = csbi.dwMaximumWindowSize.Y - 1;
SetLastError(0xdeadbeef);
Success = SetConsoleWindowInfo(hConOut, TRUE, &ConRect);
dwLastError = GetLastError();
ok(Success, "Setting console wnd info should have succeeded!\n");
ok(dwLastError != ERROR_INVALID_PARAMETER, "GetLastError: %lu\n", dwLastError);
/* Check the new reported window size rect */
Success = GetConsoleScreenBufferInfo(hConOut, &csbi2);
ok(Success, "Getting SB info\n");
if (Success)
{
ok(csbi2.srWindow.Left == ConRect.Left, "srWindow.Left = %d, expected %d\n",
csbi2.srWindow.Left, ConRect.Left);
ok(csbi2.srWindow.Top == ConRect.Top, "srWindow.Top = %d, expected %d\n",
csbi2.srWindow.Top, ConRect.Top);
ok(csbi2.srWindow.Right == ConRect.Right, "srWindow.Right = %d, expected %d\n",
csbi2.srWindow.Right, ConRect.Right);
ok(csbi2.srWindow.Bottom == ConRect.Bottom, "srWindow.Bottom = %d, expected %d\n",
csbi2.srWindow.Bottom, ConRect.Bottom);
}
/* And now try to set the console window to a size larger than the maximum size.
* The SetConsoleWindowInfo call should fail */
ConRect.Left = ConRect.Top = 0;
ConRect.Right = csbi.dwMaximumWindowSize.X + 1;
ConRect.Bottom = csbi.dwMaximumWindowSize.Y + 1;
SetLastError(0xdeadbeef);
Success = SetConsoleWindowInfo(hConOut, TRUE, &ConRect);
dwLastError = GetLastError();
ok(!Success, "Setting console wnd info should have failed!\n");
ok(dwLastError == ERROR_INVALID_PARAMETER, "GetLastError: expecting %u got %lu\n",
ERROR_INVALID_PARAMETER, dwLastError);
/* Check the new reported window size rect */
Success = GetConsoleScreenBufferInfo(hConOut, &csbi2);
ok(Success, "Getting SB info\n");
if (Success)
{
ok(csbi2.srWindow.Left == 0, "srWindow.Left = %d, expected %d\n",
csbi2.srWindow.Left, 0);
ok(csbi2.srWindow.Top == 0, "srWindow.Top = %d, expected %d\n",
csbi2.srWindow.Top, 0);
ok(csbi2.srWindow.Right == csbi.dwMaximumWindowSize.X - 1, "srWindow.Right = %d, expected %d\n",
csbi2.srWindow.Right, csbi.dwMaximumWindowSize.X - 1);
ok(csbi2.srWindow.Bottom == csbi.dwMaximumWindowSize.Y - 1, "srWindow.Bottom = %d, expected %d\n",
csbi2.srWindow.Bottom, csbi.dwMaximumWindowSize.Y - 1);
}
/* Done! Restore the original console screen buffer size and perform cleanup */
ResizeTextConsole(hConOut, &csbi, org_csbi.dwSize, &org_csbi.srWindow);
Cleanup:
CloseHandle(hConOut);
}