I meant: how do I limit scrolling down to just where the counting takes place? Because your script makes it possible to scroll down through excess of empty lines
I reworked both test into this script
Code: Select all
# Win32 API wrapper class
Add-Type Console -NS Win32 -MemberDefinition @'
[DllImport("kernel32.dll")]
private static extern IntPtr GetStdHandle(int id);
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
private static extern int WriteConsoleOutputCharacter(IntPtr hConOut, string str, int strLen, uint coord, out int written);
//# The below function:
//# ● writes through to the console screen buffer at the specified coordinates
//# ● it does not update the current position of the console cursor
//# ● invokes a low-level console API
//# ● mist not be used in a terminal application other than the classic Windows Console [conhost]
//# ● if it succeeds it return True
//# ● if it fails it returns False
//# ● parameters for it are:
//# x ▶ zero-based column index of the writing position
//# y ▶ zero-based line index of the writing position
//# text ▶ output to be written
public static bool WriteAtPosition(uint x, uint y, string text)
{
int written;
return 0 != WriteConsoleOutputCharacter(GetStdHandle(-11), text, text.Length, (y << 16) | x, out written);
}
'@
Write-Host "Line of text - at the very top"
Write-Host
Write-Host "Line of text"
Write-Host "Line of text"
Write-Host "Line of text"
Write-Host "Line of text"
Write-Host "Line of text"
Write-Host "Line of text"
Write-Host "Line of text"
Write-Host "Line of text"
Write-Host "Line of text"
Write-Host "Line of text"
Write-Host "Line of text"
Write-Host "Line of text"
Write-Host "Line of text"
Write-Host "Line of text"
Write-Host "Line of text"
Write-Host "Line of text"
Write-Host "Line of text"
Write-Host "Line of text"
Write-Host "Line of text"
Write-Host "Line of text"
Write-Host "Line of text"
Write-Host "Line of text"
Write-Host "Line of text"
Write-Host "Line of text"
Write-Host "Line of text"
Write-Host "Line of text"
Write-Host "Line of text"
Write-Host "Line of text"
Write-Host "Line of text"
Write-Host "Line of text"
Write-Host "Line of text"
Write-Host
Write-Host "Line of text - in the middle"
Write-Host
Write-Host
Write-Host "Line of text"
Write-Host "Line of text"
Write-Host "Line of text"
Write-Host "Line of text"
Write-Host "Line of text"
Write-Host "Line of text"
Write-Host "Line of text"
Write-Host "Line of text"
Write-Host "Line of text"
Write-Host "Line of text"
Write-Host "Line of text"
Write-Host "Line of text"
Write-Host "Line of text"
Write-Host "Line of text"
Write-Host "Line of text"
Write-Host "Line of text"
Write-Host "Line of text"
Write-Host "Line of text"
Write-Host "Line of text"
Write-Host "Line of text"
Write-Host "Line of text"
Write-Host "Line of text"
Write-Host "Line of text"
Write-Host "Line of text"
Write-Host "Line of text"
Write-Host "Line of text"
Write-Host "Line of text"
Write-Host "Line of text"
Write-Host "Line of text"
Write-Host "Line of text"
Write-Host "Line of text"
Write-Host
Write-Host "Line of text - the last one"
# The countdown - duration and lines below it
$Countdown_Values = 3
# Function to set the buffer height
function SetBufferHeight($height)
{
[System.Console]::BufferHeight = $height
}
# Function to display the countdown without scrolling
function DisplayCountdown($count)
{
$topRow = [System.Console]::CursorTop
$leftColumn = 0
# Set the buffer height to prevent scrolling below the countdown
SetBufferHeight($topRow + $count + 1)
for ($i = $count; $i -ge 0; $i--)
{
if ($i -eq $count)
{
[Win32.Console]::WriteAtPosition($leftColumn, $topRow, "$i") | Out-Null
}
else
{
[Win32.Console]::WriteAtPosition($leftColumn, $topRow, " $i") | Out-Null
}
Start-Sleep -Seconds 1
}
# Restore the original buffer height
SetBufferHeight($Countdown_Values + [System.Console]::WindowHeight + 1)
}
# Display the countdown
Write-Host "Executing in:"
DisplayCountdown $Countdown_Values
Write-Host "Script has been executed"
# Wait for specific user input (ESC, ENTER, or SPACE) before closing the window:
Write-Host "To close this window press either:"
Write-Host "Enter"
Write-Host "Space"
Write-Host "Esc"
Write-Host
do
{
$key = $Host.UI.RawUI.ReadKey('NoEcho, IncludeKeyDown').Character
}
while ($key -notin @(' ', [char]13, [char]27))
which does not work correctly - because its issues are:
A] the "Line of text - at the very top" is missing
B] the number that governs the amount of empty lines below the countdown is also the number od seconds for that counter
C] in the end it produces
Line of text
Line of text
Line of text
Line of text
Line of text
Line of text
Line of text
Line of text
Line of text
Line of text
Line of text
Line of text
Line of text
Line of text
Line of text
Line of text
Line of text
Line of text
Line of text
Line of text
Line of text - in the middle
Line of text
Line of text
Line of text
Line of text
Line of text
Line of text
Line of text
Line of text
Line of text
Line of text
Line of text
Line of text
Line of text
Line of text
Line of text
Line of text
Line of text
Line of text
Line of text
Line of text
Line of text
Line of text
Line of text
Line of text
Line of text
Line of text
Line of text
Line of text
Line of text
Line of text
Line of text
Line of text - the last one
Executing in:
Exception setting "BufferHeight": "The console buffer size must not be less than the current size and position of the
console window, nor greater than or equal to Int16.MaxValue.
Parameter name: height
Actual value was 54."
At C:\q\! SCRIPTS\ZZZ_TEST.ps1:106 char:5
+ [System.Console]::BufferHeight = $height
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], SetValueInvocationException
+ FullyQualifiedErrorId : ExceptionWhenSetting
Script has been executed
To close this window press either:
Enter
Space
Esc
i.e. it shows an error