public void RunVtAppTester() { using (RegistryHelper reg = new RegistryHelper()) { reg.BackupRegistry(); // we're going to modify the virtual terminal state for this, so back it up first. VersionSelector.SetConsoleVersion(reg, ConsoleVersion.V2); reg.SetDefaultValue(VIRTUAL_TERMINAL_KEY_NAME, VIRTUAL_TERMINAL_ON_VALUE); bool haveVtAppPath = !string.IsNullOrEmpty(vtAppLocation); Verify.IsTrue(haveVtAppPath, "Ensure that we passed in the location to VtApp.exe"); if (haveVtAppPath) { using (CmdApp app = new CmdApp(CreateType.ProcessOnly, TestContext, vtAppLocation)) { using (ViewportArea area = new ViewportArea(app)) { // Get console handle. IntPtr hConsole = app.GetStdOutHandle(); Verify.IsNotNull(hConsole, "Ensure the STDOUT handle is valid."); Log.Comment("Check that the VT test app loaded up properly with its output line and the cursor down one line."); Rectangle selectRect = new Rectangle(0, 0, 9, 1); IEnumerable <string> scrapedText = area.GetLinesInRectangle(hConsole, selectRect); Verify.AreEqual(scrapedText.Count(), 1, "We should have retrieved one line."); string testerWelcome = scrapedText.Single(); Verify.AreEqual(testerWelcome, "VT Tester"); WinCon.COORD cursorPos = app.GetCursorPosition(hConsole); WinCon.COORD cursorExpected = new WinCon.COORD(); cursorExpected.X = 0; cursorExpected.Y = 1; Verify.AreEqual(cursorExpected, cursorPos, "Check cursor has moved to expected starting position."); TestCursorPositioningCommands(app, hConsole, cursorExpected); TestCursorVisibilityCommands(app, hConsole); TestAreaEraseCommands(app, area, hConsole); TestGraphicsCommands(app, area, hConsole); TestQueryResponses(app, hConsole); TestVtToggle(app, hConsole); TestInsertDelete(app, area, hConsole); } } } } }
private void _ClearScreenBuffer(CmdApp app) { IntPtr outHandle = app.GetStdOutHandle(); WinCon.CONSOLE_SCREEN_BUFFER_INFO_EX screenInfo = new WinCon.CONSOLE_SCREEN_BUFFER_INFO_EX(); screenInfo.cbSize = (uint)Marshal.SizeOf(screenInfo); WinCon.GetConsoleScreenBufferInfoEx(outHandle, ref screenInfo); int charCount = screenInfo.dwSize.X * screenInfo.dwSize.Y; string writeString = new string(' ', charCount); WinCon.COORD coord = new WinCon.COORD(); coord.X = 0; coord.Y = 0; UInt32 charsWritten = 0; WinCon.WriteConsoleOutputCharacter(outHandle, writeString, (uint)charCount, coord, ref charsWritten); Verify.AreEqual((UInt32)charCount, charsWritten); }
public WinCon.CHAR_INFO[,] GetCharInfoInRectangle(IntPtr handle, Rectangle rect) { WinCon.SMALL_RECT readRectangle = new WinCon.SMALL_RECT(); readRectangle.Top = (short)rect.Top; readRectangle.Bottom = (short)(rect.Bottom - 1); readRectangle.Left = (short)rect.Left; readRectangle.Right = (short)(rect.Right - 1); WinCon.COORD dataBufferSize = new WinCon.COORD(); dataBufferSize.X = (short)rect.Width; dataBufferSize.Y = (short)rect.Height; WinCon.COORD dataBufferPos = new WinCon.COORD(); dataBufferPos.X = 0; dataBufferPos.Y = 0; WinCon.CHAR_INFO[,] data = new WinCon.CHAR_INFO[dataBufferSize.Y, dataBufferSize.X]; NativeMethods.Win32BoolHelper(WinCon.ReadConsoleOutput(handle, data, dataBufferSize, dataBufferPos, ref readRectangle), string.Format("Attempting to read rectangle (L: {0}, T: {1}, R: {2}, B: {3}) from output buffer.", readRectangle.Left, readRectangle.Top, readRectangle.Right, readRectangle.Bottom)); return(data); }
private void _WriteCharTestText(CmdApp app) { IntPtr outHandle = app.GetStdOutHandle(); WinCon.COORD coord = new WinCon.COORD(); coord.X = 0; coord.Y = 0; string row1 = "1234567890"; string row2 = " abcdefghijk"; UInt32 charsWritten = 0; WinCon.WriteConsoleOutputCharacter(outHandle, row1, (uint)row1.Length, coord, ref charsWritten); coord.Y = 1; WinCon.WriteConsoleOutputCharacter(outHandle, row2, (uint)row2.Length, coord, ref charsWritten); }
private static void TestCursorPositioningCommands(CmdApp app, IntPtr hConsole, WinCon.COORD cursorExpected) { WinCon.COORD cursorPos; Log.Comment("---Cursor Positioning Commands---"); // Try cursor commands Log.Comment("Press B key (cursor down)"); app.UIRoot.SendKeys("B"); cursorExpected.Y++; cursorPos = app.GetCursorPosition(hConsole); Verify.AreEqual(cursorExpected, cursorPos, "Check cursor has moved down by 1."); Log.Comment("Press A key (cursor up)"); app.UIRoot.SendKeys("A"); cursorExpected.Y--; cursorPos = app.GetCursorPosition(hConsole); Verify.AreEqual(cursorExpected, cursorPos, "Check cursor has moved up by 1."); Log.Comment("Press C key (cursor right)"); app.UIRoot.SendKeys("C"); cursorExpected.X++; cursorPos = app.GetCursorPosition(hConsole); Verify.AreEqual(cursorExpected, cursorPos, "Check cursor has moved right by 1."); Log.Comment("Press D key (cursor left)"); app.UIRoot.SendKeys("D"); cursorExpected.X--; cursorPos = app.GetCursorPosition(hConsole); Verify.AreEqual(cursorExpected, cursorPos, "Check cursor has moved left by 1."); Log.Comment("Move to the right (C) then move down a line (E)"); app.UIRoot.SendKeys("CCC"); cursorExpected.X += 3; cursorPos = app.GetCursorPosition(hConsole); Verify.AreEqual(cursorExpected, cursorPos, "Check cursor has right by 3."); app.UIRoot.SendKeys("E"); cursorExpected.Y++; cursorExpected.X = 0; cursorPos = app.GetCursorPosition(hConsole); Verify.AreEqual(cursorExpected, cursorPos, "Check cursor has moved down by 1 line and reset X position to 0."); Log.Comment("Move to the right (C) then move up a line (F)"); app.UIRoot.SendKeys("CCC"); cursorExpected.X += 3; cursorPos = app.GetCursorPosition(hConsole); Verify.AreEqual(cursorExpected, cursorPos, "Check curs has right by 3."); app.UIRoot.SendKeys("F"); cursorExpected.Y--; cursorExpected.X = 0; cursorPos = app.GetCursorPosition(hConsole); Verify.AreEqual(cursorExpected, cursorPos, "Check cursor has moved up by 1 line."); Log.Comment("Check move directly to position 14 horizontally (G)"); app.UIRoot.SendKeys("G"); cursorExpected.X = 14 - 1; // 14 is the VT position which starts at array offset 1. 13 is the buffer position starting at array offset 0. cursorPos = app.GetCursorPosition(hConsole); Verify.AreEqual(cursorExpected, cursorPos, "Check cursor has moved to horizontal position 14."); Log.Comment("Check move directly to position 14 vertically (v key mapped to d)"); app.UIRoot.SendKeys("v"); cursorExpected.Y = 14 - 1; // 14 is the VT position which starts at array offset 1. 13 is the buffer position starting at array offset 0. cursorPos = app.GetCursorPosition(hConsole); Verify.AreEqual(cursorExpected, cursorPos, "Check cursor has moved to vertical position 14."); Log.Comment("Check move directly to row 5, column 1 (H)"); app.UIRoot.SendKeys("H"); // Again -1s are to convert index base 1 VT to console base 0 arrays cursorExpected.Y = 5 - 1; cursorExpected.X = 1 - 1; cursorPos = app.GetCursorPosition(hConsole); Verify.AreEqual(cursorExpected, cursorPos, "Check cursor has moved to row 5, column 1."); }
public void TestMouseSelection() { using (CmdApp app = new CmdApp(CreateType.ProcessOnly, TestContext)) { using (ViewportArea area = new ViewportArea(app)) { // Set up the area we're going to attempt to select Point startPoint = new Point(); Point endPoint = new Point(); startPoint.X = 1; startPoint.Y = 2; endPoint.X = 10; endPoint.Y = 10; // Save expected anchor WinCon.COORD expectedAnchor = new WinCon.COORD(); expectedAnchor.X = (short)startPoint.X; expectedAnchor.Y = (short)startPoint.Y; // Also save bottom right corner for the end of the selection WinCon.COORD expectedBottomRight = new WinCon.COORD(); expectedBottomRight.X = (short)endPoint.X; expectedBottomRight.Y = (short)endPoint.Y; // Prepare the mouse by moving it into the start position. Prepare the structure WinCon.CONSOLE_SELECTION_INFO csi; WinCon.SMALL_RECT expectedRect = new WinCon.SMALL_RECT(); WinCon.CONSOLE_SELECTION_INFO_FLAGS flagsExpected = WinCon.CONSOLE_SELECTION_INFO_FLAGS.CONSOLE_NO_SELECTION; // 1. Place mouse button down to start selection and check state area.MouseMove(startPoint); area.MouseDown(); Globals.WaitForTimeout(); // must wait after mouse operation. No good waiters since we have no UI objects flagsExpected |= WinCon.CONSOLE_SELECTION_INFO_FLAGS.CONSOLE_SELECTION_IN_PROGRESS; // a selection is occurring flagsExpected |= WinCon.CONSOLE_SELECTION_INFO_FLAGS.CONSOLE_MOUSE_SELECTION; // it's a "Select" mode not "Mark" mode selection flagsExpected |= WinCon.CONSOLE_SELECTION_INFO_FLAGS.CONSOLE_MOUSE_DOWN; // the mouse is still down flagsExpected |= WinCon.CONSOLE_SELECTION_INFO_FLAGS.CONSOLE_SELECTION_NOT_EMPTY; // mouse selections are never empty. minimum 1x1 expectedRect.Top = expectedAnchor.Y; // rectangle is just at the point itself 1x1 size expectedRect.Left = expectedAnchor.X; expectedRect.Bottom = expectedRect.Top; expectedRect.Right = expectedRect.Left; NativeMethods.Win32BoolHelper(WinCon.GetConsoleSelectionInfo(out csi), "Check state on mouse button down to start selection."); Log.Comment("Selection Info: {0}", csi); Verify.AreEqual(csi.Flags, flagsExpected, "Check initial mouse selection with button still down."); Verify.AreEqual(csi.SelectionAnchor, expectedAnchor, "Check that the anchor is equal to the start point."); Verify.AreEqual(csi.Selection, expectedRect, "Check that entire rectangle is the size of 1x1 and is just at the anchor point."); // 2. Move to end point and release cursor area.MouseMove(endPoint); area.MouseUp(); Globals.WaitForTimeout(); // must wait after mouse operation. No good waiters since we have no UI objects // on button up, remove mouse down flag flagsExpected &= ~WinCon.CONSOLE_SELECTION_INFO_FLAGS.CONSOLE_MOUSE_DOWN; // anchor remains the same // bottom right of rectangle now changes to the end point expectedRect.Bottom = expectedBottomRight.Y; expectedRect.Right = expectedBottomRight.X; NativeMethods.Win32BoolHelper(WinCon.GetConsoleSelectionInfo(out csi), "Check state after drag and release mouse."); Log.Comment("Selection Info: {0}", csi); Verify.AreEqual(csi.Flags, flagsExpected, "Check selection is still on and valid, but button is up."); Verify.AreEqual(csi.SelectionAnchor, expectedAnchor, "Check that the anchor is still equal to the start point."); Verify.AreEqual(csi.Selection, expectedRect, "Check that entire rectangle reaches from start to end point."); // 3. Leave mouse selection area.ExitModes(); flagsExpected = WinCon.CONSOLE_SELECTION_INFO_FLAGS.CONSOLE_NO_SELECTION; NativeMethods.Win32BoolHelper(WinCon.GetConsoleSelectionInfo(out csi), "Check state after exiting mouse selection."); Log.Comment("Selection Info: {0}", csi); Verify.AreEqual(csi.Flags, flagsExpected, "Check that selection state is reset."); } } }
public void TestKeyboardSelection() { using (RegistryHelper reg = new RegistryHelper()) { reg.BackupRegistry(); VersionSelector.SetConsoleVersion(reg, ConsoleVersion.V2); using (CmdApp app = new CmdApp(CreateType.ProcessOnly, TestContext)) { using (ViewportArea area = new ViewportArea(app)) { WinCon.CONSOLE_SELECTION_INFO csi; NativeMethods.Win32BoolHelper(WinCon.GetConsoleSelectionInfo(out csi), "Get initial selection state."); Log.Comment("Selection Info: {0}", csi); Verify.AreEqual(csi.Flags, WinCon.CONSOLE_SELECTION_INFO_FLAGS.CONSOLE_NO_SELECTION, "Confirm no selection in progress."); // ignore rectangle and coords. They're undefined when there is no selection. // Get cursor position at the beginning of this operation. The anchor will start at the cursor position for v2 console. // NOTE: It moved to 0,0 for the v1 console. IntPtr hConsole = WinCon.GetStdHandle(WinCon.CONSOLE_STD_HANDLE.STD_OUTPUT_HANDLE); Verify.IsNotNull(hConsole, "Ensure the STDOUT handle is valid."); WinCon.CONSOLE_SCREEN_BUFFER_INFO_EX cbiex = new WinCon.CONSOLE_SCREEN_BUFFER_INFO_EX(); cbiex.cbSize = (uint)Marshal.SizeOf(cbiex); NativeMethods.Win32BoolHelper(WinCon.GetConsoleScreenBufferInfoEx(hConsole, ref cbiex), "Get initial cursor position (from screen buffer info)"); // The expected anchor when we're done is this initial cursor position WinCon.COORD expectedAnchor = new WinCon.COORD(); expectedAnchor.X = cbiex.dwCursorPosition.X; expectedAnchor.Y = cbiex.dwCursorPosition.Y; // The expected rect is going to start from this cursor position. We'll modify it after we perform some operations. WinCon.SMALL_RECT expectedRect = new WinCon.SMALL_RECT(); expectedRect.Top = expectedAnchor.Y; expectedRect.Left = expectedAnchor.X; expectedRect.Right = expectedAnchor.X; expectedRect.Bottom = expectedAnchor.Y; // Now set up the keyboard and enter mark mode. // NOTE: We must wait after every keyboard sequence to give the console time to process before asking it for changes. area.EnterMode(ViewportArea.ViewportStates.Mark); NativeMethods.Win32BoolHelper(WinCon.GetConsoleSelectionInfo(out csi), "Get state on entering mark mode."); Log.Comment("Selection Info: {0}", csi); Verify.AreEqual(csi.Flags, WinCon.CONSOLE_SELECTION_INFO_FLAGS.CONSOLE_SELECTION_IN_PROGRESS, "Selection should now be in progress since mark mode is started."); // Select a small region Log.Comment("1. Select a small region"); app.UIRoot.SendKeys(Keys.Shift + Keys.Right + Keys.Right + Keys.Right + Keys.Down + Keys.Shift); Globals.WaitForTimeout(); // Adjust the expected rectangle for the commands we just entered. expectedRect.Right += 3; // same as the number of Rights we put in expectedRect.Bottom += 1; // same as the number of Downs we put in NativeMethods.Win32BoolHelper(WinCon.GetConsoleSelectionInfo(out csi), "Get state of selected region."); Log.Comment("Selection Info: {0}", csi); Verify.AreEqual(csi.Flags, WinCon.CONSOLE_SELECTION_INFO_FLAGS.CONSOLE_SELECTION_IN_PROGRESS | WinCon.CONSOLE_SELECTION_INFO_FLAGS.CONSOLE_SELECTION_NOT_EMPTY, "Selection in progress and is no longer empty now that we've selected a region."); Verify.AreEqual(csi.Selection, expectedRect, "Verify that the selected rectangle matches the keystrokes we entered."); Verify.AreEqual(csi.SelectionAnchor, expectedAnchor, "Verify anchor didn't go anywhere since we started in the top left."); // End selection by moving Log.Comment("2. End the selection by moving."); app.UIRoot.SendKeys(Keys.Down); Globals.WaitForTimeout(); NativeMethods.Win32BoolHelper(WinCon.GetConsoleSelectionInfo(out csi), "Move cursor to attempt to clear selection."); Log.Comment("Selection Info: {0}", csi); Verify.AreEqual(csi.Flags, WinCon.CONSOLE_SELECTION_INFO_FLAGS.CONSOLE_SELECTION_IN_PROGRESS, "Selection should be still running, but empty."); // Select another region to ensure anchor moved. Log.Comment("3. Select one more region from new position to verify anchor"); app.UIRoot.SendKeys(Keys.Shift + Keys.Right + Keys.Shift); Globals.WaitForTimeout(); expectedAnchor.X = expectedRect.Right; expectedAnchor.Y = expectedRect.Bottom; expectedAnchor.Y++; // +1 for the Down in step 2. Not incremented in the line above because C# is unhappy with adding +1 to a short while assigning. Verify.AreEqual(csi.SelectionAnchor, expectedAnchor, "Verify anchor moved to the new start position."); // Exit mark mode area.EnterMode(ViewportArea.ViewportStates.Normal); NativeMethods.Win32BoolHelper(WinCon.GetConsoleSelectionInfo(out csi), "Move cursor to attempt to clear selection."); Log.Comment("Selection Info: {0}", csi); Verify.AreEqual(csi.Flags, WinCon.CONSOLE_SELECTION_INFO_FLAGS.CONSOLE_NO_SELECTION, "Selection should be empty when mode is exited."); } } } }
public void FillCursorPosition(IntPtr hConsole, ref Point pt) { WinCon.COORD coord = GetCursorPosition(hConsole); pt.X = coord.X; pt.Y = coord.Y; }