mirror of
https://github.com/reactos/reactos.git
synced 2024-11-07 15:10:53 +00:00
355 lines
16 KiB
C
355 lines
16 KiB
C
/*
|
||
* 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);
|
||
}
|