[KERNEL32_APITEST]: Commit a test for SetConsoleWindowInfo.
[reactos.git] / rostests / apitests / kernel32 / SetConsoleWindowInfo.c
1 /*
2 * PROJECT: ReactOS api tests
3 * LICENSE: GPLv2+ - See COPYING in the top level directory
4 * PURPOSE: Test for SetConsoleWindowInfo
5 * PROGRAMMER: Hermes Belusca-Maito
6 */
7
8 #include <apitest.h>
9 #include <wincon.h>
10
11 START_TEST(SetConsoleWindowInfo)
12 {
13 /*
14 * The aim of this test is to show that what MSDN says about the validity
15 * checks performed on the window size rect given to SetConsoleWindowInfo
16 * is partially wrong.
17 *
18 * Indeed, while it is claimed that:
19 * "The function fails if the specified window rectangle extends beyond
20 * the boundaries of the console screen buffer. This means that the Top
21 * and Left members of the lpConsoleWindow rectangle (or the calculated
22 * top and left coordinates, if bAbsolute is FALSE) cannot be less than
23 * zero. Similarly, the Bottom and Right members (or the calculated
24 * bottom and right coordinates) cannot be greater than (screen buffer
25 * height – 1) and (screen buffer width – 1), respectively. The function
26 * also fails if the Right member (or calculated right coordinate) is
27 * less than or equal to the Left member (or calculated left coordinate)
28 * or if the Bottom member (or calculated bottom coordinate) is less than
29 * or equal to the Top member (or calculated top coordinate)."
30 *
31 * the really performed tests are fewer, and it appears that the console
32 * subsystem knows how to take proper actions when the window size rect
33 * has e.g. negative left/top coordinates...
34 *
35 * NOTE that we all perform those tests in "absolute mode" (second parameter
36 * of SetConsoleWindowInfo being TRUE), so that the specified window size rect
37 * is in absolute coordinates (i.e. relative to the console screen buffer),
38 * and not in coordinates relative to the current window-corner coordinates.
39 */
40
41 BOOL Success;
42 DWORD dwLastError;
43 HANDLE hConOut;
44 COORD Resolution;
45 CONSOLE_SCREEN_BUFFER_INFO csbi, csbi2;
46 SMALL_RECT ConRect;
47
48 /* First, retrieve a handle to the real console output, even if we are redirected */
49 hConOut = CreateFileW(L"CONOUT$", GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0);
50 ok(hConOut != INVALID_HANDLE_VALUE, "Opening ConOut\n");
51 if (hConOut == INVALID_HANDLE_VALUE)
52 return; // We cannot run this test if we failed...
53
54 /* Retrieve console screen buffer info */
55 Success = GetConsoleScreenBufferInfo(hConOut, &csbi);
56 ok(Success, "Getting SB info\n");
57 if (!Success)
58 goto Cleanup; // We cannot as well run this test if we failed...
59
60 /*
61 * Set the console screen buffer to a correct size
62 * that should not completely fill the computer screen.
63 */
64 Resolution.X = 80;
65 Resolution.Y = 25;
66 if (Resolution.X != csbi.dwSize.X || Resolution.Y != csbi.dwSize.Y)
67 {
68 SHORT oldWidth, oldHeight;
69
70 oldWidth = csbi.srWindow.Right - csbi.srWindow.Left + 1;
71 oldHeight = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
72
73 /*
74 * If the current console window is too large for
75 * the new screen buffer, resize it first.
76 */
77 if (oldWidth > Resolution.X || oldHeight > Resolution.Y)
78 {
79 ConRect.Left = ConRect.Top = 0;
80 ConRect.Right = ConRect.Left + min(oldWidth , Resolution.X) - 1;
81 ConRect.Bottom = ConRect.Top + min(oldHeight, Resolution.Y) - 1;
82 Success = SetConsoleWindowInfo(hConOut, TRUE, &ConRect);
83 ok(Success, "Setting console wnd info failed with last error error %lu\n", GetLastError());
84 }
85
86 /* Now resize the screen buffer */
87 Success = SetConsoleScreenBufferSize(hConOut, Resolution);
88 ok(Success, "Setting console SB size failed with last error error %lu\n", GetLastError());
89
90 /*
91 * Setting a new screen buffer size can change other information,
92 * so update the saved console information.
93 */
94 GetConsoleScreenBufferInfo(hConOut, &csbi);
95 }
96
97 /* Update console screen buffer info */
98 Success = GetConsoleScreenBufferInfo(hConOut, &csbi);
99 ok(Success, "Getting SB info\n");
100 if (!Success)
101 goto Cleanup; // We cannot as well run this test if we failed...
102
103 /* Test 1: Resize the console window to its possible maximum size (should succeed) */
104 ConRect.Left = ConRect.Top = 0;
105 ConRect.Right = ConRect.Left + min(csbi.dwSize.X, csbi.dwMaximumWindowSize.X) - 1;
106 ConRect.Bottom = ConRect.Top + min(csbi.dwSize.Y, csbi.dwMaximumWindowSize.Y) - 1;
107 SetLastError(0xdeadbeef);
108 Success = SetConsoleWindowInfo(hConOut, TRUE, &ConRect);
109 dwLastError = GetLastError();
110 ok(Success, "Setting console wnd info\n");
111 ok(dwLastError != ERROR_INVALID_PARAMETER, "GetLastError: %lu\n", dwLastError);
112
113 /* Test 2: Set Right/Bottom members smaller than Left/Top members
114 * (should fail, agrees with MSDN) */
115 ConRect.Left = csbi.dwSize.X - 5;
116 ConRect.Right = 0;
117 ConRect.Top = csbi.dwSize.Y - 5;
118 ConRect.Bottom = 0;
119 SetLastError(0xdeadbeef);
120 Success = SetConsoleWindowInfo(hConOut, TRUE, &ConRect);
121 dwLastError = GetLastError();
122 ok(!Success, "Setting console wnd info should have failed!\n");
123 ok(dwLastError == ERROR_INVALID_PARAMETER, "GetLastError: expecting %u got %lu\n",
124 ERROR_INVALID_PARAMETER, dwLastError);
125
126 /* Test 3: Set negative Left/Top members, but correct Right/Bottom ones.
127 * The Left/Top members are shifted to zero while the Right/Bottom ones
128 * are shifted too in accordance.
129 * 1st situation where the Right/Bottom members will be ok after the shift
130 * (should succeed, disagrees with MSDN) */
131 ConRect.Left = ConRect.Top = -5;
132 ConRect.Right = csbi.dwSize.X - 7;
133 ConRect.Bottom = csbi.dwSize.Y - 7;
134 // Expected result: ConRect.Left == ConRect.Top == 0 and
135 // ConRect.Right == csbi.dwSize.X - 2, ConRect.Bottom == csbi.dwSize.Y - 2;
136 SetLastError(0xdeadbeef);
137 Success = SetConsoleWindowInfo(hConOut, TRUE, &ConRect);
138 dwLastError = GetLastError();
139 ok(Success, "Setting console wnd info should have succeeded!\n");
140 ok(dwLastError != ERROR_INVALID_PARAMETER, "GetLastError: %lu\n", dwLastError);
141
142 /* Check the new reported window size rect */
143 Success = GetConsoleScreenBufferInfo(hConOut, &csbi2);
144 ok(Success, "Getting SB info\n");
145 if (Success)
146 {
147 ok(csbi2.srWindow.Left == 0, "srWindow.Left = %d, expected 0\n", csbi2.srWindow.Left);
148 ok(csbi2.srWindow.Top == 0, "srWindow.Top = %d, expected 0\n", csbi2.srWindow.Top);
149
150 /* NOTE that here we compare against the old csbi data! */
151 ok(csbi2.srWindow.Right == csbi.dwSize.X - 2, "srWindow.Right = %d, expected %d\n",
152 csbi2.srWindow.Right, csbi.dwSize.X - 2);
153 ok(csbi2.srWindow.Bottom == csbi.dwSize.Y - 2, "srWindow.Bottom = %d, expected %d\n",
154 csbi2.srWindow.Bottom, csbi.dwSize.Y - 2);
155 }
156
157 /* Test 4: Similar to Test 3, but set the Right/Bottom members too large
158 * with respect to the screen buffer size, so that after their shift, they
159 * still are too large (should fail, agrees with MSDN) */
160 ConRect.Left = ConRect.Top = -5;
161 ConRect.Right = csbi.dwSize.X + 2; // Bigger than SB size
162 ConRect.Bottom = csbi.dwSize.Y + 2; // Bigger than SB size
163 SetLastError(0xdeadbeef);
164 Success = SetConsoleWindowInfo(hConOut, TRUE, &ConRect);
165 dwLastError = GetLastError();
166 ok(!Success, "Setting console wnd info should have failed!\n");
167 ok(dwLastError == ERROR_INVALID_PARAMETER, "GetLastError: expecting %u got %lu\n",
168 ERROR_INVALID_PARAMETER, dwLastError);
169
170 /* Check the new reported window size rect */
171 Success = GetConsoleScreenBufferInfo(hConOut, &csbi2);
172 ok(Success, "Getting SB info\n");
173 if (Success)
174 {
175 /* NOTE that here we compare against the old csbi data! */
176 ok(csbi2.srWindow.Left == 0, "srWindow(2).Left = %d, expected equal to %d\n",
177 csbi2.srWindow.Left, 0);
178 ok(csbi2.srWindow.Top == 0, "srWindow(2).Top = %d, expected equal to %d\n",
179 csbi2.srWindow.Top, 0);
180 ok(csbi2.srWindow.Right == csbi.dwSize.X - 2, "srWindow(2).Right = %d, expected equal to %d\n",
181 csbi2.srWindow.Right, csbi.dwSize.X - 2);
182 ok(csbi2.srWindow.Bottom == csbi.dwSize.Y - 2, "srWindow(2).Bottom = %d, expected equal to %d\n",
183 csbi2.srWindow.Bottom, csbi.dwSize.Y - 2);
184 }
185
186 /* Test 5: Similar to Tests 3 and 4, but we here just check what happens for
187 * the Right/Bottom members when they are too large, without caring about the
188 * Left/Top members (the latter being set to valid values this time)
189 * (should fail, agrees with MSDN) */
190 ConRect.Left = ConRect.Top = 2; // OK
191 ConRect.Right = csbi.dwSize.X + 7; // Bigger than SB size
192 ConRect.Bottom = csbi.dwSize.Y + 7; // Bigger than SB size
193 SetLastError(0xdeadbeef);
194 Success = SetConsoleWindowInfo(hConOut, TRUE, &ConRect);
195 dwLastError = GetLastError();
196 ok(!Success, "Setting console wnd info should have failed!\n");
197 ok(dwLastError == ERROR_INVALID_PARAMETER, "GetLastError: expecting %u got %lu\n",
198 ERROR_INVALID_PARAMETER, dwLastError);
199
200 /* Check the new reported window size rect */
201 Success = GetConsoleScreenBufferInfo(hConOut, &csbi2);
202 ok(Success, "Getting SB info\n");
203 if (Success)
204 {
205 ok(csbi2.srWindow.Left == 0, "srWindow.Left = %d, expected 0\n", csbi2.srWindow.Left);
206 ok(csbi2.srWindow.Top == 0, "srWindow.Top = %d, expected 0\n", csbi2.srWindow.Top);
207
208 /* NOTE that here we compare against the old csbi data! */
209 ok(csbi2.srWindow.Right == csbi.dwSize.X - 2, "srWindow.Right = %d, expected %d\n",
210 csbi2.srWindow.Right, csbi.dwSize.X - 2);
211 ok(csbi2.srWindow.Bottom == csbi.dwSize.Y - 2, "srWindow.Bottom = %d, expected %d\n",
212 csbi2.srWindow.Bottom, csbi.dwSize.Y - 2);
213 }
214
215 /* Done! */
216 Cleanup:
217 CloseHandle(hConOut);
218 }