[KERNEL32_APITEST]: SetConsoleWindowInfo test:
[reactos.git] / rostests / apitests / kernel32 / SetConsoleWindowInfo.c
index 962db7d..763e99a 100644 (file)
@@ -8,6 +8,72 @@
 #include <apitest.h>
 #include <wincon.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)
 {
     /*
@@ -42,7 +108,7 @@ START_TEST(SetConsoleWindowInfo)
     DWORD dwLastError;
     HANDLE hConOut;
     COORD Resolution;
-    CONSOLE_SCREEN_BUFFER_INFO csbi, csbi2;
+    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 */
@@ -51,56 +117,25 @@ START_TEST(SetConsoleWindowInfo)
     if (hConOut == INVALID_HANDLE_VALUE)
         return; // We cannot run this test if we failed...
 
-    /* Retrieve console screen buffer info */
-    Success = GetConsoleScreenBufferInfo(hConOut, &csbi);
+    /*
+     * 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.
+     * 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;
-    if (Resolution.X != csbi.dwSize.X || Resolution.Y != csbi.dwSize.Y)
-    {
-        SHORT oldWidth, oldHeight;
-
-        oldWidth  = csbi.srWindow.Right  - csbi.srWindow.Left + 1;
-        oldHeight = csbi.srWindow.Bottom - csbi.srWindow.Top  + 1;
+    ResizeTextConsole(hConOut, &csbi, Resolution, NULL);
 
-        /*
-         * 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.
-         */
-        GetConsoleScreenBufferInfo(hConOut, &csbi);
-    }
-
-    /* Update console screen buffer info */
-    Success = GetConsoleScreenBufferInfo(hConOut, &csbi);
-    ok(Success, "Getting SB info\n");
-    if (!Success)
-        goto Cleanup; // We cannot as well run this test if we failed...
-
-    /* Test 1: Resize the console window to its possible maximum size (should succeed) */
+    /* 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;
@@ -110,24 +145,11 @@ START_TEST(SetConsoleWindowInfo)
     ok(Success, "Setting console wnd info\n");
     ok(dwLastError != ERROR_INVALID_PARAMETER, "GetLastError: %lu\n", dwLastError);
 
-    /* Test 2: Set Right/Bottom members smaller than Left/Top members
-     * (should fail, 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 3: Set negative Left/Top members, but correct Right/Bottom ones.
+    /* 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.
-     * 1st situation where the Right/Bottom members will be ok after the shift
-     * (should succeed, disagrees with MSDN) */
+     * 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;
@@ -144,19 +166,24 @@ START_TEST(SetConsoleWindowInfo)
     ok(Success, "Getting SB info\n");
     if (Success)
     {
-        ok(csbi2.srWindow.Left == 0, "srWindow.Left = %d, expected 0\n", csbi2.srWindow.Left);
-        ok(csbi2.srWindow.Top == 0, "srWindow.Top = %d, expected 0\n", csbi2.srWindow.Top);
+        ConRect.Right -= ConRect.Left;
+        ConRect.Left = 0;
+        ConRect.Bottom -= ConRect.Top;
+        ConRect.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);
+        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 4: Similar to Test 3, but set the Right/Bottom members too large
+    /* 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
-     * still are too large (should fail, agrees with MSDN) */
+     * 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
@@ -173,20 +200,20 @@ START_TEST(SetConsoleWindowInfo)
     if (Success)
     {
         /* NOTE that here we compare against the old csbi data! */
-        ok(csbi2.srWindow.Left == 0, "srWindow(2).Left = %d, expected equal to %d\n",
+        ok(csbi2.srWindow.Left == 0, "srWindow.Left = %d, expected %d\n",
            csbi2.srWindow.Left, 0);
-        ok(csbi2.srWindow.Top == 0, "srWindow(2).Top = %d, expected equal to %d\n",
+        ok(csbi2.srWindow.Top == 0, "srWindow.Top = %d, expected %d\n",
            csbi2.srWindow.Top, 0);
-        ok(csbi2.srWindow.Right == csbi.dwSize.X - 2, "srWindow(2).Right = %d, expected equal to %d\n",
+        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(2).Bottom = %d, expected equal to %d\n",
+        ok(csbi2.srWindow.Bottom == csbi.dwSize.Y - 2, "srWindow.Bottom = %d, expected %d\n",
            csbi2.srWindow.Bottom, csbi.dwSize.Y - 2);
     }
 
-    /* Test 5: Similar to Tests 3 and 4, but we here just check what happens for
+    /* 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)
-     * (should fail, agrees with MSDN) */
+     * (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
@@ -202,17 +229,128 @@ START_TEST(SetConsoleWindowInfo)
     ok(Success, "Getting SB info\n");
     if (Success)
     {
-        ok(csbi2.srWindow.Left == 0, "srWindow.Left = %d, expected 0\n", csbi2.srWindow.Left);
-        ok(csbi2.srWindow.Top == 0, "srWindow.Top = %d, expected 0\n", csbi2.srWindow.Top);
+        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);
+           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);
+           csbi2.srWindow.Bottom, csbi.dwSize.Y - 2);
     }
 
-    /* Done! */
+    /* 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);
 }