ReactOS  0.4.14-dev-384-g5b37caa
SetConsoleWindowInfo.c File Reference
#include "precomp.h"
Include dependency graph for SetConsoleWindowInfo.c:

Go to the source code of this file.

Functions

static VOID ResizeTextConsole (IN HANDLE hConOut, IN OUT PCONSOLE_SCREEN_BUFFER_INFO pcsbi, IN COORD Resolution, IN PSMALL_RECT WindowSize OPTIONAL)
 
 START_TEST (SetConsoleWindowInfo)
 

Function Documentation

◆ ResizeTextConsole()

static VOID ResizeTextConsole ( IN HANDLE  hConOut,
IN OUT PCONSOLE_SCREEN_BUFFER_INFO  pcsbi,
IN COORD  Resolution,
IN PSMALL_RECT WindowSize  OPTIONAL 
)
static

Definition at line 11 of file SetConsoleWindowInfo.c.

16 {
17  BOOL Success;
18  SMALL_RECT ConRect;
19 
20  if (Resolution.X != pcsbi->dwSize.X || Resolution.Y != pcsbi->dwSize.Y)
21  {
22  SHORT oldWidth, oldHeight;
23 
24  oldWidth = pcsbi->srWindow.Right - pcsbi->srWindow.Left + 1;
25  oldHeight = pcsbi->srWindow.Bottom - pcsbi->srWindow.Top + 1;
26 
27  /*
28  * If the current console window is too large for
29  * the new screen buffer, resize it first.
30  */
31  if (oldWidth > Resolution.X || oldHeight > Resolution.Y)
32  {
33  ConRect.Left = ConRect.Top = 0;
34  ConRect.Right = ConRect.Left + min(oldWidth , Resolution.X) - 1;
35  ConRect.Bottom = ConRect.Top + min(oldHeight, Resolution.Y) - 1;
36  Success = SetConsoleWindowInfo(hConOut, TRUE, &ConRect);
37  ok(Success, "Setting console wnd info failed with last error error %lu\n", GetLastError());
38  }
39 
40  /* Now resize the screen buffer */
42  ok(Success, "Setting console SB size failed with last error error %lu\n", GetLastError());
43 
44  /*
45  * Setting a new screen buffer size can change other information,
46  * so update the saved console information.
47  */
48  Success = GetConsoleScreenBufferInfo(hConOut, pcsbi);
49  ok(Success, "Getting SB info\n");
50  }
51 
52  if (!WindowSize)
53  {
54  /* Always resize the console window within the permitted maximum size */
55  ConRect.Left = 0;
56  ConRect.Right = ConRect.Left + min(Resolution.X, pcsbi->dwMaximumWindowSize.X) - 1;
57  ConRect.Bottom = min(pcsbi->dwCursorPosition.Y, Resolution.Y - 1);
58  ConRect.Top = ConRect.Bottom - min(Resolution.Y, pcsbi->dwMaximumWindowSize.Y) + 1;
59  }
60  else
61  {
62  /* Resize the console window according to user's wishes */
63  ConRect.Left = ConRect.Top = 0;
64  ConRect.Right = ConRect.Left + WindowSize->Right - WindowSize->Left;
65  ConRect.Bottom = ConRect.Top + WindowSize->Bottom - WindowSize->Top ;
66  }
67 
68  Success = SetConsoleWindowInfo(hConOut, TRUE, &ConRect);
69  ok(Success, "Setting console wnd info failed with last error error %lu\n", GetLastError());
70 
71  /* Update console screen buffer info */
72  Success = GetConsoleScreenBufferInfo(hConOut, pcsbi);
73  ok(Success, "Getting SB info\n");
74 }
#define TRUE
Definition: types.h:120
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
BOOL WINAPI DECLSPEC_HOTPATCH SetConsoleScreenBufferSize(HANDLE hConsoleOutput, COORD dwSize)
Definition: console.c:1857
unsigned int BOOL
Definition: ntddk_ex.h:94
short SHORT
Definition: pedump.c:59
BOOL WINAPI GetConsoleScreenBufferInfo(IN HANDLE hConsoleOutput, OUT PCONSOLE_SCREEN_BUFFER_INFO lpConsoleScreenBufferInfo)
Definition: console.c:544
SHORT Left
Definition: blue.h:25
SHORT Bottom
Definition: blue.h:28
SHORT Top
Definition: blue.h:26
_In_ ULONGLONG _In_ ULONGLONG _In_ BOOLEAN _In_opt_ ULONG WindowSize
Definition: ntddpcm.h:140
#define ok(value,...)
Definition: atltest.h:57
#define min(a, b)
Definition: monoChain.cc:55
static BYTE Resolution
Definition: mouse.c:35
SHORT Right
Definition: blue.h:27
BOOL WINAPI SetConsoleWindowInfo(HANDLE hConsoleOutput, BOOL bAbsolute, CONST SMALL_RECT *lpConsoleWindow)
Definition: console.c:1972

Referenced by START_TEST().

◆ START_TEST()

START_TEST ( SetConsoleWindowInfo  )

Definition at line 76 of file SetConsoleWindowInfo.c.

77 {
78  /*
79  * The aim of this test is to show that what MSDN says about the validity
80  * checks performed on the window size rect given to SetConsoleWindowInfo
81  * is partially wrong.
82  *
83  * Indeed, while it is claimed that:
84  * "The function fails if the specified window rectangle extends beyond
85  * the boundaries of the console screen buffer. This means that the Top
86  * and Left members of the lpConsoleWindow rectangle (or the calculated
87  * top and left coordinates, if bAbsolute is FALSE) cannot be less than
88  * zero. Similarly, the Bottom and Right members (or the calculated
89  * bottom and right coordinates) cannot be greater than (screen buffer
90  * height – 1) and (screen buffer width – 1), respectively. The function
91  * also fails if the Right member (or calculated right coordinate) is
92  * less than or equal to the Left member (or calculated left coordinate)
93  * or if the Bottom member (or calculated bottom coordinate) is less than
94  * or equal to the Top member (or calculated top coordinate)."
95  *
96  * the really performed tests are fewer, and it appears that the console
97  * subsystem knows how to take proper actions when the window size rect
98  * has e.g. negative left/top coordinates...
99  *
100  * NOTE that we all perform those tests in "absolute mode" (second parameter
101  * of SetConsoleWindowInfo being TRUE), so that the specified window size rect
102  * is in absolute coordinates (i.e. relative to the console screen buffer),
103  * and not in coordinates relative to the current window-corner coordinates.
104  */
105 
106  BOOL Success;
107  DWORD dwLastError;
108  HANDLE hConOut;
110  CONSOLE_SCREEN_BUFFER_INFO org_csbi, csbi, csbi2;
111  SMALL_RECT ConRect;
112 
113  /* First, retrieve a handle to the real console output, even if we are redirected */
114  hConOut = CreateFileW(L"CONOUT$", GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0);
115  ok(hConOut != INVALID_HANDLE_VALUE, "Opening ConOut\n");
116  if (hConOut == INVALID_HANDLE_VALUE)
117  return; // We cannot run this test if we failed...
118 
119  /*
120  * Retrieve the original console screen buffer info and save it
121  * for restoration at the end of the test. Use a copy after then.
122  */
123  Success = GetConsoleScreenBufferInfo(hConOut, &org_csbi);
124  ok(Success, "Getting SB info\n");
125  if (!Success)
126  goto Cleanup; // We cannot as well run this test if we failed...
127  csbi = org_csbi;
128 
129  /*
130  * Set the console screen buffer to a correct size that should not
131  * completely fill the computer screen. 'csbi' is correctly updated.
132  */
133  Resolution.X = 80;
134  Resolution.Y = 25;
135  ResizeTextConsole(hConOut, &csbi, Resolution, NULL);
136 
137  /* Test 1: Resize the console window to its possible maximum size (succeeds) */
138  ConRect.Left = ConRect.Top = 0;
139  ConRect.Right = ConRect.Left + min(csbi.dwSize.X, csbi.dwMaximumWindowSize.X) - 1;
140  ConRect.Bottom = ConRect.Top + min(csbi.dwSize.Y, csbi.dwMaximumWindowSize.Y) - 1;
141  SetLastError(0xdeadbeef);
142  Success = SetConsoleWindowInfo(hConOut, TRUE, &ConRect);
143  dwLastError = GetLastError();
144  ok(Success, "Setting console wnd info\n");
145  ok(dwLastError != ERROR_INVALID_PARAMETER, "GetLastError: %lu\n", dwLastError);
146 
147  /* Test 2: Set negative Left/Top members, but correct Right/Bottom ones.
148  * The Left/Top members are shifted to zero while the Right/Bottom ones
149  * are shifted too in accordance.
150  * Situation where the Right/Bottom members will be ok after the shift
151  * (succeeds, disagrees with MSDN) */
152  ConRect.Left = ConRect.Top = -5;
153  ConRect.Right = csbi.dwSize.X - 7;
154  ConRect.Bottom = csbi.dwSize.Y - 7;
155  // Expected result: ConRect.Left == ConRect.Top == 0 and
156  // ConRect.Right == csbi.dwSize.X - 2, ConRect.Bottom == csbi.dwSize.Y - 2;
157  SetLastError(0xdeadbeef);
158  Success = SetConsoleWindowInfo(hConOut, TRUE, &ConRect);
159  dwLastError = GetLastError();
160  ok(Success, "Setting console wnd info should have succeeded!\n");
161  ok(dwLastError != ERROR_INVALID_PARAMETER, "GetLastError: %lu\n", dwLastError);
162 
163  /* Check the new reported window size rect */
164  Success = GetConsoleScreenBufferInfo(hConOut, &csbi2);
165  ok(Success, "Getting SB info\n");
166  if (Success)
167  {
168  ConRect.Right -= ConRect.Left;
169  ConRect.Left = 0;
170  ConRect.Bottom -= ConRect.Top;
171  ConRect.Top = 0;
172 
173  ok(csbi2.srWindow.Left == ConRect.Left, "srWindow.Left = %d, expected %d\n",
174  csbi2.srWindow.Left, ConRect.Left);
175  ok(csbi2.srWindow.Top == ConRect.Top, "srWindow.Top = %d, expected %d\n",
176  csbi2.srWindow.Top, ConRect.Top);
177  ok(csbi2.srWindow.Right == ConRect.Right, "srWindow.Right = %d, expected %d\n",
178  csbi2.srWindow.Right, ConRect.Right);
179  ok(csbi2.srWindow.Bottom == ConRect.Bottom, "srWindow.Bottom = %d, expected %d\n",
180  csbi2.srWindow.Bottom, ConRect.Bottom);
181  }
182 
183  /* Test 3: Similar to Test 2, but set the Right/Bottom members too large
184  * with respect to the screen buffer size, so that after their shift, they
185  * are still too large (fails, agrees with MSDN) */
186  ConRect.Left = ConRect.Top = -5;
187  ConRect.Right = csbi.dwSize.X + 2; // Bigger than SB size
188  ConRect.Bottom = csbi.dwSize.Y + 2; // Bigger than SB size
189  SetLastError(0xdeadbeef);
190  Success = SetConsoleWindowInfo(hConOut, TRUE, &ConRect);
191  dwLastError = GetLastError();
192  ok(!Success, "Setting console wnd info should have failed!\n");
193  ok(dwLastError == ERROR_INVALID_PARAMETER, "GetLastError: expecting %u got %lu\n",
194  ERROR_INVALID_PARAMETER, dwLastError);
195 
196  /* Check the new reported window size rect */
197  Success = GetConsoleScreenBufferInfo(hConOut, &csbi2);
198  ok(Success, "Getting SB info\n");
199  if (Success)
200  {
201  /* NOTE that here we compare against the old csbi data! */
202  ok(csbi2.srWindow.Left == 0, "srWindow.Left = %d, expected %d\n",
203  csbi2.srWindow.Left, 0);
204  ok(csbi2.srWindow.Top == 0, "srWindow.Top = %d, expected %d\n",
205  csbi2.srWindow.Top, 0);
206  ok(csbi2.srWindow.Right == csbi.dwSize.X - 2, "srWindow.Right = %d, expected %d\n",
207  csbi2.srWindow.Right, csbi.dwSize.X - 2);
208  ok(csbi2.srWindow.Bottom == csbi.dwSize.Y - 2, "srWindow.Bottom = %d, expected %d\n",
209  csbi2.srWindow.Bottom, csbi.dwSize.Y - 2);
210  }
211 
212  /* Test 4: Similar to Tests 2 and 3, but we here just check what happens for
213  * the Right/Bottom members when they are too large, without caring about the
214  * Left/Top members (the latter being set to valid values this time)
215  * (fails, agrees with MSDN) */
216  ConRect.Left = ConRect.Top = 2; // OK
217  ConRect.Right = csbi.dwSize.X + 7; // Bigger than SB size
218  ConRect.Bottom = csbi.dwSize.Y + 7; // Bigger than SB size
219  SetLastError(0xdeadbeef);
220  Success = SetConsoleWindowInfo(hConOut, TRUE, &ConRect);
221  dwLastError = GetLastError();
222  ok(!Success, "Setting console wnd info should have failed!\n");
223  ok(dwLastError == ERROR_INVALID_PARAMETER, "GetLastError: expecting %u got %lu\n",
224  ERROR_INVALID_PARAMETER, dwLastError);
225 
226  /* Check the new reported window size rect */
227  Success = GetConsoleScreenBufferInfo(hConOut, &csbi2);
228  ok(Success, "Getting SB info\n");
229  if (Success)
230  {
231  ok(csbi2.srWindow.Left == 0, "srWindow.Left = %d, expected %d\n",
232  csbi2.srWindow.Left, 0);
233  ok(csbi2.srWindow.Top == 0, "srWindow.Top = %d, expected %d\n",
234  csbi2.srWindow.Top, 0);
235 
236  /* NOTE that here we compare against the old csbi data! */
237  ok(csbi2.srWindow.Right == csbi.dwSize.X - 2, "srWindow.Right = %d, expected %d\n",
238  csbi2.srWindow.Right, csbi.dwSize.X - 2);
239  ok(csbi2.srWindow.Bottom == csbi.dwSize.Y - 2, "srWindow.Bottom = %d, expected %d\n",
240  csbi2.srWindow.Bottom, csbi.dwSize.Y - 2);
241  }
242 
243  /* Test 5: Set Right/Bottom members strictly smaller than Left/Top members
244  * (fails, agrees with MSDN) */
245  ConRect.Left = csbi.dwSize.X - 5;
246  ConRect.Right = 0;
247  ConRect.Top = csbi.dwSize.Y - 5;
248  ConRect.Bottom = 0;
249  SetLastError(0xdeadbeef);
250  Success = SetConsoleWindowInfo(hConOut, TRUE, &ConRect);
251  dwLastError = GetLastError();
252  ok(!Success, "Setting console wnd info should have failed!\n");
253  ok(dwLastError == ERROR_INVALID_PARAMETER, "GetLastError: expecting %u got %lu\n",
254  ERROR_INVALID_PARAMETER, dwLastError);
255 
256  /* Test 6: Set Left/Top members equal to the Right/Bottom members respectively
257  * (succeeds, disagrees with MSDN) */
258  ConRect.Left = ConRect.Right = 2;
259  ConRect.Top = ConRect.Bottom = 5;
260  SetLastError(0xdeadbeef);
261  Success = SetConsoleWindowInfo(hConOut, TRUE, &ConRect);
262  dwLastError = GetLastError();
263  ok(Success, "Setting console wnd info should have succeeded!\n");
264  ok(dwLastError != ERROR_INVALID_PARAMETER, "GetLastError: %lu\n", dwLastError);
265 
266  /* Check the new reported window size rect */
267  Success = GetConsoleScreenBufferInfo(hConOut, &csbi2);
268  ok(Success, "Getting SB info\n");
269  if (Success)
270  {
271  ok(csbi2.srWindow.Left == ConRect.Left, "srWindow.Left = %d, expected %d\n",
272  csbi2.srWindow.Left, ConRect.Left);
273  ok(csbi2.srWindow.Top == ConRect.Top, "srWindow.Top = %d, expected %d\n",
274  csbi2.srWindow.Top, ConRect.Top);
275  ok(csbi2.srWindow.Right == ConRect.Right, "srWindow.Right = %d, expected %d\n",
276  csbi2.srWindow.Right, ConRect.Right);
277  ok(csbi2.srWindow.Bottom == ConRect.Bottom, "srWindow.Bottom = %d, expected %d\n",
278  csbi2.srWindow.Bottom, ConRect.Bottom);
279  }
280 
281  /*
282  * Test 7: Test how large can the console window be, for a given
283  * screen buffer size. For that we set the console screen buffer
284  * to a really large size, hoping that its corresponding window size
285  * is larger than the computer screen. The permitted maximum window
286  * size specified in csbi.dwMaximumWindowSize should be a boundary.
287  */
288  Resolution.X = 500;
289  Resolution.Y = 500;
290  ResizeTextConsole(hConOut, &csbi, Resolution, NULL);
291  /* Be sure that csbi.dwMaximumWindowSize is strictly smaller
292  * than the console screen buffer size, for our matters... */
294  "dwMaximumWindowSize = {%d, %d} was expected to be smaller than Resolution = {%d, %d}\n",
296 
297  /* Now try to set first the console window to a size smaller than the maximum size */
298  ConRect.Left = ConRect.Top = 0;
299  ConRect.Right = csbi.dwMaximumWindowSize.X - 1;
300  ConRect.Bottom = csbi.dwMaximumWindowSize.Y - 1;
301  SetLastError(0xdeadbeef);
302  Success = SetConsoleWindowInfo(hConOut, TRUE, &ConRect);
303  dwLastError = GetLastError();
304  ok(Success, "Setting console wnd info should have succeeded!\n");
305  ok(dwLastError != ERROR_INVALID_PARAMETER, "GetLastError: %lu\n", dwLastError);
306 
307  /* Check the new reported window size rect */
308  Success = GetConsoleScreenBufferInfo(hConOut, &csbi2);
309  ok(Success, "Getting SB info\n");
310  if (Success)
311  {
312  ok(csbi2.srWindow.Left == ConRect.Left, "srWindow.Left = %d, expected %d\n",
313  csbi2.srWindow.Left, ConRect.Left);
314  ok(csbi2.srWindow.Top == ConRect.Top, "srWindow.Top = %d, expected %d\n",
315  csbi2.srWindow.Top, ConRect.Top);
316  ok(csbi2.srWindow.Right == ConRect.Right, "srWindow.Right = %d, expected %d\n",
317  csbi2.srWindow.Right, ConRect.Right);
318  ok(csbi2.srWindow.Bottom == ConRect.Bottom, "srWindow.Bottom = %d, expected %d\n",
319  csbi2.srWindow.Bottom, ConRect.Bottom);
320  }
321 
322  /* And now try to set the console window to a size larger than the maximum size.
323  * The SetConsoleWindowInfo call should fail */
324  ConRect.Left = ConRect.Top = 0;
325  ConRect.Right = csbi.dwMaximumWindowSize.X + 1;
326  ConRect.Bottom = csbi.dwMaximumWindowSize.Y + 1;
327  SetLastError(0xdeadbeef);
328  Success = SetConsoleWindowInfo(hConOut, TRUE, &ConRect);
329  dwLastError = GetLastError();
330  ok(!Success, "Setting console wnd info should have failed!\n");
331  ok(dwLastError == ERROR_INVALID_PARAMETER, "GetLastError: expecting %u got %lu\n",
332  ERROR_INVALID_PARAMETER, dwLastError);
333 
334  /* Check the new reported window size rect */
335  Success = GetConsoleScreenBufferInfo(hConOut, &csbi2);
336  ok(Success, "Getting SB info\n");
337  if (Success)
338  {
339  ok(csbi2.srWindow.Left == 0, "srWindow.Left = %d, expected %d\n",
340  csbi2.srWindow.Left, 0);
341  ok(csbi2.srWindow.Top == 0, "srWindow.Top = %d, expected %d\n",
342  csbi2.srWindow.Top, 0);
343  ok(csbi2.srWindow.Right == csbi.dwMaximumWindowSize.X - 1, "srWindow.Right = %d, expected %d\n",
344  csbi2.srWindow.Right, csbi.dwMaximumWindowSize.X - 1);
345  ok(csbi2.srWindow.Bottom == csbi.dwMaximumWindowSize.Y - 1, "srWindow.Bottom = %d, expected %d\n",
346  csbi2.srWindow.Bottom, csbi.dwMaximumWindowSize.Y - 1);
347  }
348 
349 
350  /* Done! Restore the original console screen buffer size and perform cleanup */
351  ResizeTextConsole(hConOut, &csbi, org_csbi.dwSize, &org_csbi.srWindow);
352 
353 Cleanup:
354  CloseHandle(hConOut);
355 }
#define ERROR_INVALID_PARAMETER
Definition: compat.h:91
#define TRUE
Definition: types.h:120
#define CloseHandle
Definition: compat.h:406
#define INVALID_HANDLE_VALUE
Definition: compat.h:399
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
unsigned int BOOL
Definition: ntddk_ex.h:94
#define GENERIC_WRITE
Definition: nt_native.h:90
smooth NULL
Definition: ftsmooth.c:416
#define OPEN_EXISTING
Definition: compat.h:434
BOOL WINAPI GetConsoleScreenBufferInfo(IN HANDLE hConsoleOutput, OUT PCONSOLE_SCREEN_BUFFER_INFO lpConsoleScreenBufferInfo)
Definition: console.c:544
SHORT Left
Definition: blue.h:25
ULONG X
Definition: bl.h:1340
SHORT Bottom
Definition: blue.h:28
unsigned long DWORD
Definition: ntddk_ex.h:95
#define SetLastError(x)
Definition: compat.h:417
SHORT Top
Definition: blue.h:26
static const WCHAR L[]
Definition: oid.c:1250
#define GENERIC_READ
Definition: compat.h:124
static const WCHAR Cleanup[]
Definition: register.c:80
Definition: bl.h:1338
#define ok(value,...)
Definition: atltest.h:57
#define min(a, b)
Definition: monoChain.cc:55
#define CreateFileW
Definition: compat.h:408
static BYTE Resolution
Definition: mouse.c:35
static VOID ResizeTextConsole(IN HANDLE hConOut, IN OUT PCONSOLE_SCREEN_BUFFER_INFO pcsbi, IN COORD Resolution, IN PSMALL_RECT WindowSize OPTIONAL)
SHORT Right
Definition: blue.h:27
BOOL WINAPI SetConsoleWindowInfo(HANDLE hConsoleOutput, BOOL bAbsolute, CONST SMALL_RECT *lpConsoleWindow)
Definition: console.c:1972
ULONG Y
Definition: bl.h:1341