private void TestScrollByWheelImpl(CmdApp app, ViewportArea area, IntPtr hConsole, WinCon.CONSOLE_SCREEN_BUFFER_INFO_EX sbiex, Queue <EventData> expected, WinCon.CONSOLE_SCREEN_BUFFER_INFO_EX sbiexOriginal)
        {
            int rowsPerScroll = app.GetRowsPerScroll();
            int scrollDelta;

            // A. Scroll down.
            {
                scrollDelta = -1;
                expected.Enqueue(new EventData(EventType.UpdateScroll, 0, scrollDelta * rowsPerScroll));
                expected.Enqueue(new EventData(EventType.Layout));

                app.ScrollWindow(scrollDelta);

                Globals.WaitForTimeout();
                VerifyQueue(expected);
            }

            // B. Scroll up.
            {
                scrollDelta = 1;
                expected.Enqueue(new EventData(EventType.UpdateScroll, 0, scrollDelta * rowsPerScroll));
                expected.Enqueue(new EventData(EventType.Layout));

                app.ScrollWindow(scrollDelta);

                Globals.WaitForTimeout();
                VerifyQueue(expected);
            }
        }
        void VerifyScroll(CmdApp app, ScrollDir dir, int clicks)
        {
            WinCon.CONSOLE_SCREEN_BUFFER_INFO_EX beforeScroll;
            WinCon.CONSOLE_SCREEN_BUFFER_INFO_EX afterScroll;
            int deltaActual;
            int deltaExpected;

            beforeScroll = app.GetScreenBufferInfo();

            switch (dir)
            {
            case ScrollDir.Vertical:
                app.ScrollWindow(clicks);
                break;

            case ScrollDir.Horizontal:
                app.HScrollWindow(clicks);
                break;

            default:
                throw new NotSupportedException();
            }

            // Give the window message a moment to take effect.
            Globals.WaitForTimeout();

            switch (dir)
            {
            case ScrollDir.Vertical:
                deltaExpected = clicks * app.GetRowsPerScroll();
                break;

            case ScrollDir.Horizontal:
                deltaExpected = clicks * app.GetColsPerScroll();
                break;

            default:
                throw new NotSupportedException();
            }

            afterScroll = app.GetScreenBufferInfo();

            switch (dir)
            {
            case ScrollDir.Vertical:
                // Scrolling "negative" vertically is pulling the wheel downward which makes the lines move down.
                // This means that if you scroll down from the top, before = 0 and after = 3. 0 - 3 = -3.
                // The - sign of the delta here then aligns with the down = negative rule.
                deltaActual = beforeScroll.srWindow.Top - afterScroll.srWindow.Top;
                break;

            case ScrollDir.Horizontal:
                // Scrolling "negative" horizontally is pushing the wheel left which makes lines move left.
                // This means that if you scroll left, before = 3 and after = 0. 0 - 3 = -3.
                // The - sign of the delta here then aligns with the left = negative rule.
                deltaActual = afterScroll.srWindow.Left - beforeScroll.srWindow.Left;
                break;

            default:
                throw new NotSupportedException();
            }

            Verify.AreEqual(deltaExpected, deltaActual);
        }