Complete control of cmd windows

Discussion forum for all Windows batch related topics.

Moderator: DosItHelp

Message
Author
aGerman
Expert
Posts: 4678
Joined: 22 Jan 2010 18:01
Location: Germany

Re: Complete control of cmd windows

#61 Post by aGerman » 09 Oct 2022 17:10

It's probably exactly what you want. The actual window edge is not the visible window edge on Win10. You can observe it by moving the mouse pointer slowly from outside towards a window. The position where the default mouse pointer turns into the double arrow pointer is the actual window edge. It's ~6 pixels away from the visible edge of the window (this area is called "drop shadow" because it shows the indication of a shadow on the background). The negative X value makes the visible edge of the window being very close to the monitor edge instead of leaving a gap for the drop shadow.

einstein1969
Expert
Posts: 960
Joined: 15 Jun 2012 13:16
Location: Italy, Rome

Re: Complete control of cmd windows

#62 Post by einstein1969 » 10 Oct 2022 12:41

yes I noticed.

I thought it was the old windows edge win2k, xp, ...

this thread would like to continue with the SET of some basic settings such as the "font".

I know that neorobin had presented a possibility through the use of the register. Also I remember that Antonio Acini had also created small fonts useful for drawing on the screen. I wanted to know if there was a chance with these powershell methods mixed with low-level functions.

I am also interested in setting some properties of the dos window besides the fonts (family and size), the properties found in the first tab (tab) "options" for example quick editing, legacy mode etc.

aGerman
Expert
Posts: 4678
Joined: 22 Jan 2010 18:01
Location: Germany

Re: Complete control of cmd windows

#63 Post by aGerman » 10 Oct 2022 13:22

Regarding getting/setting the font refer to:
viewtopic.php?f=3&t=10156

Settings can be retrieved and updated using the GetConsoleMode and SetConsoleMode API functions. Refer to one of their manpages to see which of them are supported:
https://learn.microsoft.com/en-us/windo ... onsolemode
I can certainly write 2 more PowerShell macros. One to get the current flags (the errorlevel value has enough bits to represent them) and one to update the flags. The bitwise operations to set or remove flags can be performed using SET /A in batch code.

Using the legacy console is a different story though. I'm not aware of any API function to update this setting (and it will require a restart of the console host anyway). However, an update of this setting just leads to an update of value "ForceV2" in the registry key "HKCU\Console" which can easily be done using REG ADD as well.

aGerman
Expert
Posts: 4678
Joined: 22 Jan 2010 18:01
Location: Germany

Re: Complete control of cmd windows

#64 Post by aGerman » 11 Oct 2022 11:25

GetConsoleMode and SetConsoleMode macros along with named flags as described on the MS manpage:

Code: Select all

@echo off &setlocal enableDelayedExpansion

::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: Flags to be used to update the bitset returned by the GetConsoleMode macro
::  and passed to the SetConsoleMode macro.
:: For more information refer to:
::  https://learn.microsoft.com/en-us/windows/console/getconsolemode
:: The flags for the input mode are 16 bits left-shifted in order to be able
::  getting both the input flags and the output flags merged in just one value.
:: ENABLE_AUTO_POSITION is undocumented.
:: Setting or removing ENABLE_EXTENDED_FLAGS is not effective because the
::  SetConsoleMode macro will overrule you by setting this flag by default. This
::  is necessary to make updates of ENABLE_QUICK_EDIT_MODE work.
set /a ^"^
 %= flags for the input mode =%^
  ENABLE_PROCESSED_INPUT             = 0x00010000,^
  ENABLE_LINE_INPUT                  = 0x00020000,^
  ENABLE_ECHO_INPUT                  = 0x00040000,^
  ENABLE_WINDOW_INPUT                = 0x00080000,^
  ENABLE_MOUSE_INPUT                 = 0x00100000,^
  ENABLE_INSERT_MODE                 = 0x00200000,^
  ENABLE_QUICK_EDIT_MODE             = 0x00400000,^
  ENABLE_EXTENDED_FLAGS              = 0x00800000,^
  ENABLE_AUTO_POSITION               = 0x01000000,^
  ENABLE_VIRTUAL_TERMINAL_INPUT      = 0x02000000,^
 %= flags for the output mode =%^
  ENABLE_PROCESSED_OUTPUT            = 0x00000001,^
  ENABLE_WRAP_AT_EOL_OUTPUT          = 0x00000002,^
  ENABLE_VIRTUAL_TERMINAL_PROCESSING = 0x00000004,^
  DISABLE_NEWLINE_AUTO_RETURN        = 0x00000008,^
  ENABLE_LVB_GRID_WORLDWIDE          = 0x00000010^"
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: Get the default mode of the console host.
:: The mode is returned as bitset in the errorlevel value.
set GetConsoleMode=^
%=% powershell -nop -ep Bypass -c ^"^
%===% $w=Add-Type -Name WAPI -PassThru -MemberDefinition '^
%=====% [DllImport(\"kernel32.dll\"^)]^
%=======% public static extern IntPtr GetStdHandle(int idx^);^
%=====% [DllImport(\"kernel32.dll\"^)]^
%=======% public static extern int GetConsoleMode(IntPtr h, ref int mode^);^
%===% ';^
%===% $STD_INPUT_HANDLE=-10;^
%===% $STD_OUTPUT_HANDLE=-11;^
%===% $inmode=0;^
%===% $inret=$w::GetConsoleMode($w::GetStdHandle($STD_INPUT_HANDLE^), [ref]$inmode^);^
%===% $outmode=0;^
%===% $outret=$w::GetConsoleMode($w::GetStdHandle($STD_OUTPUT_HANDLE^), [ref]$outmode^);^
%===% if (-not $inret -or -not $outret^) {exit -1;}^
%===% exit ($inmode -shl 16^) -bor $outmode;^
%=% ^"
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: Set the mode of the current console host session.
:: The mode is passed as integer which represents a bitset.
set SetConsoleMode=for %%# in (1 2) do if %%#==2 (for /f %%1 in ("^!arg^!"^) do (^
%=% powershell -nop -ep Bypass -c ^"^
%===% $w=Add-Type -Name WAPI -PassThru -MemberDefinition '^
%=====% [DllImport(\"kernel32.dll\"^)]^
%=======% public static extern IntPtr GetStdHandle(int idx^);^
%=====% [DllImport(\"kernel32.dll\"^)]^
%=======% public static extern int SetConsoleMode(IntPtr h, int mode^);^
%===% ';^
%===% $mode=0;^
%===% if ((-not [Int32]::TryParse(\"%%~1\"^, [ref]$mode^)^) -or ($mode -lt 0^)^) {exit 1;}^
%===% $STD_INPUT_HANDLE=-10;^
%===% $STD_OUTPUT_HANDLE=-11;^
%===% $inret=$w::SetConsoleMode($w::GetStdHandle($STD_INPUT_HANDLE^), ($mode -shr 16^) -bor 0x80^);^
%===% $outret=$w::SetConsoleMode($w::GetStdHandle($STD_OUTPUT_HANDLE^), $mode -band 0xFFFF^);^
%===% exit (-not $inret -or -not $outret^);^
%=% ^"^) ^&endlocal^) else setlocal EnableDelayedExpansion ^&set arg=
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

%GetConsoleMode%
set "oldmode=%errorlevel%"

echo(
echo Enable Quick Edit Mode ...
set /a "newmode1=oldmode | ENABLE_QUICK_EDIT_MODE"
%SetConsoleMode% %newmode1%
echo *** Try to mark something with your mouse. ***
pause

echo(
echo Disable Quick Edit Mode ...
set /a "newmode2=newmode1 & ~ENABLE_QUICK_EDIT_MODE"
%SetConsoleMode% %newmode2%
echo *** Try again to mark something. ***
pause

:: At this point we don't care what we've changed because the updates only
:: affected this conhost session. Defaults are still the same.
//EDIT Check for negative value in SetConsoleMode to fail fast.

einstein1969
Expert
Posts: 960
Joined: 15 Jun 2012 13:16
Location: Italy, Rome

Re: Complete control of cmd windows

#65 Post by einstein1969 » 12 Oct 2022 11:21

Very good work! Thanks

this is a demo , i have added other color

Image

Code: Select all

@echo off

rem save this script in UTF-8

set "me=%~f0"
setlocal enableDelayedExpansion


if "%1"=="sphere" (
  call :sphere %2 %3 %4 %5 %6 %7
  goto :eof
)

call  :init_setfont

%setfont% 4 Terminal

call :GetInfo

rem I want about 5% of free space around console window
set /a "Delta.X=(cmr-cml)*5/100, Delta.Y=(cmb-cmt)*5/100"
rem round using one decimal point
set /a "Delta.X=(Delta.X*10/CellSize.X+5)/10, Delta.Y=(Delta.Y*10/CellSize.Y+5)/10"

set /A Newsize.X=clx-Delta.X, Newsize.Y=cly-Delta.Y

mode CON: COLS=!Newsize.X! LINES=!Newsize.Y!

call :GetInfo

call :AndCenter

%GetConsoleMode%
set "oldmode=%errorlevel%"

set /a "newmode1=oldmode &  ~ENABLE_QUICK_EDIT_MODE"
%SetConsoleMode% %newmode1%

rem multithread 20 thread

set /A "deltaX=ConsoleSize.X/5, deltaY=ConsoleSize.Y/4, Radius=deltaY/2"

start "" /B cmd.exe /c ""!me!" sphere Red     1 1 !deltaX! !deltaY! !Radius!"
start "" /B cmd.exe /c ""!me!" sphere Lime    !deltaX! 1 !deltaX!*2 !deltaY! !Radius!"
start "" /B cmd.exe /c ""!me!" sphere Blue    !deltaX!*2 1 !deltaX!*3 !deltaY! !Radius!"
start "" /B cmd.exe /c ""!me!" sphere Salmon  !deltaX!*3 1 !deltaX!*4 !deltaY! !Radius!"
start "" /B cmd.exe /c ""!me!" sphere Purple  !deltaX!*4 1 !deltaX!*5 !deltaY! !Radius!"

start "" /B cmd.exe /c ""!me!" sphere Yellow  1 !deltaY!+1 !deltaX! !deltaY!*2 !Radius!"
start "" /B cmd.exe /c ""!me!" sphere Cyan    !deltaX! !deltaY!+1 !deltaX!*2 !deltaY!*2 !Radius!"
start "" /B cmd.exe /c ""!me!" sphere Magenta !deltaX!*2 !deltaY!+1 !deltaX!*3 !deltaY!*2 !Radius!"
start "" /B cmd.exe /c ""!me!" sphere Navy    !deltaX!*3 !deltaY!+1 !deltaX!*4 !deltaY!*2 !Radius!"
start "" /B cmd.exe /c ""!me!" sphere SpringGreen    !deltaX!*4 !deltaY!+1 !deltaX!*5 !deltaY!*2 !Radius!"

start "" /B cmd.exe /c ""!me!" sphere White   1 !deltaY!*2+1 !deltaX! !deltaY!*3 !Radius!"
start "" /B cmd.exe /c ""!me!" sphere Orange  !deltaX! !deltaY!*2+1 !deltaX!*2 !deltaY!*3 !Radius!"
start "" /B cmd.exe /c ""!me!" sphere Pink    !deltaX!*2 !deltaY!*2+1 !deltaX!*3 !deltaY!*3 !Radius!"
start "" /B cmd.exe /c ""!me!" sphere Chartreuse    !deltaX!*3 !deltaY!*2+1 !deltaX!*4 !deltaY!*3 !Radius!"
start "" /B cmd.exe /c ""!me!" sphere Gray    !deltaX!*4 !deltaY!*2+1 !deltaX!*5 !deltaY!*3 !Radius!"

start "" /B cmd.exe /c ""!me!" sphere Maroon  1 !deltaY!*3+1 !deltaX! !deltaY!*4 !Radius!"
start "" /B cmd.exe /c ""!me!" sphere Olive   !deltaX! !deltaY!*3+1 !deltaX!*2 !deltaY!*4 !Radius!"
start "" /B cmd.exe /c ""!me!" sphere Green   !deltaX!*2 !deltaY!*3+1 !deltaX!*3 !deltaY!*4 !Radius!"
start "" /B cmd.exe /c ""!me!" sphere Teal    !deltaX!*3 !deltaY!*3+1 !deltaX!*4 !deltaY!*4 !Radius!"
start "" /B cmd.exe /c ""!me!" sphere Canary  !deltaX!*4 !deltaY!*3+1 !deltaX!*5 !deltaY!*4 !Radius!"

pause>nul
goto :eof
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:sphere color Begin.X Begin.Y End.X End.Y Radius

rem title %1 %2 %3 %4 %5 %6
rem pause 

call :init

set /A Bimg.x=%2, Bimg.y=%3
set /A Eimg.x=%4, Eimg.y=%5
set /A Radius=%6

rem cell size in dots
set /A xc=CellSize.X, yc=CellSize.Y

rem draw a circle (x-x0)^2+(y-y0)^2=r^2 . Implicit equation for simpler math.

rem set radius and center in cmd windows, assume screen ratio greater than one ie 1280/720=1.777

set /A "R=Radius*yc, X0=((Eimg.x-Bimg.x)/2+Bimg.x)*xc, Y0=Bimg.y*yc+R"


rem setting step for better smoothing colors
set /A "mS=-(R*R), step=255*100000/-mS, stepL=128*100000/-mS"

if "%1"=="Red"		set "RGB=^!C^! 0 0"
if "%1"=="Lime"		set "RGB=0 ^!C^! 0"
if "%1"=="Blue"		set "RGB=0 0 ^!C^!"
if "%1"=="Yellow"	set "RGB=^!C^! ^!C^! 0"
if "%1"=="Cyan"		set "RGB=0 ^!C^! ^!C^!"
if "%1"=="Magenta"	set "RGB=^!C^! 0 ^!C^!"
if "%1"=="White"	set "RGB=^!C^! ^!C^! ^!C^!"
if "%1"=="Orange"	set "RGB=^!C^! ^!CL^! 0"
if "%1"=="Pink"		set "RGB=^!C^! 0 ^!CL^!"
if "%1"=="Salmon"	set "RGB=^!C^! ^!CL^! ^!CL^!"
if "%1"=="Navy"		set "RGB=0 0 ^!CL^!"
if "%1"=="Gray"		set "RGB=^!CL^! ^!CL^! ^!CL^!"
if "%1"=="Maroon"	set "RGB=^!CL^! 0 0"
if "%1"=="Olive"	set "RGB=^!CL^! ^!CL^! 0"
if "%1"=="Green"	set "RGB=0 ^!CL^! 0"
if "%1"=="Teal"		set "RGB=0 ^!CL^! ^!CL^!"
if "%1"=="Purple"	set "RGB=^!CL^! 0 ^!CL^!"
if "%1"=="SpringGreen"	set "RGB=0 ^!C^! ^!CL^!"
if "%1"=="Chartreuse"	set "RGB=^!CL^! ^!C^! 0"
if "%1"=="Canary"	set "RGB=^!C^! ^!C^! ^!CL^!"

rem (performance) we compare colors first instead of doing it for each painted cell
  For /L %%y in (!Bimg.y!,1,!Eimg.y!) do (
    For /L %%x in (!Bimg.x!,1,!Eimg.x!) do (
      set /A "px=%%x*xc, py=%%y*yc, x=px-x0, y=py-y0, S=y*y+x*x-R*R, C=-S*step/100000, CL=-S*stepL/100000"
      if !S! leq 0 %plot% %%x %%y %RGB%
    )
  )
  %flush%
goto :eof
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:GetInfo

::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: The %ConsoleInfo% macro collects properties of the console window and its environment.
:: It prints a string in the following format to StdOut:
::   cml=N,cmt=N,cmr=N,cmb=N,cwx=N,cwy=N,cvx=N,cvy=N,cfx=N,cfy=N,chx=N,chy=N,ccx=N,ccy=N,clx=N,cly=N
:: With:
::   N    different integral values of the below properties
::   cml  left dots boundary of the monitor's workspace
::   cmt  top dots boundary of the monitor's workspace
::   cmr  right dots boundary of the monitor's workspace
::   cmb  bottom dots boundary of the monitor's workspace
::   cwx  current width of the console window as number of dots
::   cwy  current height of the console window as number of dots
::   cvx  current width of the console viewport as number of dots
::   cvy  current height of the console viewport as number of dots
::   cfx  console font width as number of pixels
::   cfy  console font height as number of pixels
::   chx  approximated console charcell width as number of dots
::   chy  approximated console charcell height as number of dots
::   ccx  current width of the console client window as number of character cells
::   ccy  current height of the console client window as number of character cells
::   clx  largest width of the console client window as number of character cells
::   cly  largest height of the console client window as number of character cells
:: To define variables %cfx% .. %cly%, execute the macro in a FOR /F loop like that:
::   FOR /F %%I IN ('%ConsoleInfo%') DO SET /A "%%I"
set ConsoleInfo=^
powershell -nop -ep Bypass -c ^"^
%=% $w=Add-Type -Name WAPI -PassThru -MemberDefinition '^
%===% [DllImport(\"user32.dll\"^)]^
%=====% public static extern void SetProcessDPIAware(^);^
%===% [DllImport(\"shcore.dll\"^)]^
%=====% public static extern void SetProcessDpiAwareness(int value^);^
%===% [DllImport(\"kernel32.dll\"^)]^
%=====% public static extern IntPtr GetConsoleWindow(^);^
%===% [DllImport(\"user32.dll\"^)]^
%=====% public static extern void GetWindowRect(IntPtr hwnd, int[] rect^);^
%===% [DllImport(\"user32.dll\"^)]^
%=====% public static extern void GetClientRect(IntPtr hwnd, int[] rect^);^
%===% [DllImport(\"user32.dll\"^)]^
%=====% public static extern void GetMonitorInfoW(IntPtr hMonitor, int[] lpmi^);^
%===% [DllImport(\"user32.dll\"^)]^
%=====% public static extern IntPtr MonitorFromWindow(IntPtr hwnd, int dwFlags^);^
%===% [DllImport(\"kernel32.dll\"^)]^
%=====% public static extern IntPtr CreateFile(string name, int acc, int share, IntPtr sec, int how, int flags, IntPtr tmplt^);^
%===% [DllImport(\"kernel32.dll\"^)]^
%=====% public static extern void GetCurrentConsoleFont(IntPtr hOut, int isMax, int[] info^);^
%===% [DllImport(\"kernel32.dll\"^)]^
%=====% public static extern void CloseHandle(IntPtr h^);^
%=% ';^
 ^
%=% $PROCESS_PER_MONITOR_DPI_AWARE=2;^
%=% try {$w::SetProcessDpiAwareness($PROCESS_PER_MONITOR_DPI_AWARE^)} catch {$w::SetProcessDPIAware(^)}^
 ^
%=% $hwnd=$w::GetConsoleWindow(^);^
%=   The $moninf array is a replacement for the MONITORINFO structure. The elements at index         =% ^
%=   5, 6, 7, and 8 represent left, top, right, and bottom boundaries of the monitor's work space.   =% ^
%=% $moninf=[int[]]::new(10^);^
%=% $moninf[0]=40;^
%=% $MONITOR_DEFAULTTONEAREST=2;^
%=% $w::GetMonitorInfoW($w::MonitorFromWindow($hwnd, $MONITOR_DEFAULTTONEAREST^), $moninf^);^
 ^
%=   The $wrect array is a replacement for the RECT structure. The elements at index    =% ^
%=   0, 1, 2, and 3 represent left, top, right, and bottom boundaries of the window.   =% ^
%=% $wrect=[int[]]::new(4^);^
%=% $w::GetWindowRect($hwnd, $wrect^);^
 ^
%=   The $crect array is a replacement for the RECT structure. The elements at index          =% ^
%=   0, 1, 2, and 3 represent left, top, right, and bottom boundaries of the client window.   =% ^
%=% $crect=[int[]]::new(4^);^
%=% $w::GetClientRect($hwnd, $crect^);^
 ^
%=% $NIL=[IntPtr]::Zero;^
%=% $GENERIC_READ=0x80000000;^
%=% $GENERIC_WRITE=0x40000000;^
%=% $FILE_SHARE_WRITE=0x00000002;^
%=% $OPEN_EXISTING=3;^
%=   Because the StdOut stream is redirected to a pipe behind the scenes of a FOR /F loop,   =% ^
%=   we need to explicitly open a handle to the console output device (alias 'CONOUT$').     =% ^
%=% $out=$w::CreateFile('CONOUT$', $GENERIC_READ -bor $GENERIC_WRITE, $FILE_SHARE_WRITE, $NIL, $OPEN_EXISTING, 0, $NIL^);^
%=   The $fntinf array is a replacement for the CONSOLE_FONT_INFO structure. The 16 low order bits of the   =% ^
%=   second element represent the font width, while its 16 high order bits represent the font height.       =% ^
%=% $fntinf=[int[]]::new(2^);^
%=% $w::GetCurrentConsoleFont($out, 0, $fntinf^);^
%=% $w::CloseHandle($out^);^
 ^
%=% $raw=$host.UI.RawUI;^
%=% $cur=$raw.WindowSize;^
%=% $lrg=$raw.MaxPhysicalWindowSize;^
 ^
%=% 'cml={0},cmt={1},cmr={2},cmb={3},cwx={4},cwy={5},cvx={6},cvy={7},cfx={8},cfy={9},chx={10},chy={11},ccx={12},ccy={13},clx={14},cly={15}' -f^
%===% $moninf[5], $moninf[6], $moninf[7], $moninf[8],^
%===% ($wrect[2]-$wrect[0]^), ($wrect[3]-$wrect[1]^),^
%===% ($crect[2]-$crect[0]^), ($crect[3]-$crect[1]^),^
%===% ($fntinf[1] -band 0xFFFF^), ($fntinf[1] -shr 16^),^
%===% [math]::Round(($crect[2]-$crect[0]^)/$cur.Width^), [math]::Round(($crect[3]-$crect[1]^)/$cur.Height^),^
%===% $cur.Width, $cur.Height,^
%===% $lrg.Width, $lrg.Height;^
 ^"
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: %MoveWindow% X Y
::   X  left side of the window
::   Y  top of the window
set MoveWindow=for %%i in (1 2) do if %%i==2 (^
%=% for /f "tokens=1*" %%j in ("^!arg^!") do (powershell.exe -nop -ep Bypass -Command ^"^
%===% try {$w=Add-Type -Name WAPI -PassThru -MemberDefinition '^
%=====% [DllImport(\"user32.dll\"^)]^
%=======% public static extern void SetProcessDPIAware(^);^
%=====% [DllImport(\"shcore.dll\"^)]^
%=======% public static extern void SetProcessDpiAwareness(int value^);^
%=====% [DllImport(\"user32.dll\"^)]^
%=======% public static extern int SetWindowPos(IntPtr hWnd^, IntPtr hWndInsertAfter^, int X^, int Y^, int cx^, int cy^, uint uFlags^);^
%=====% [DllImport(\"kernel32.dll\"^)]^
%=======% public static extern IntPtr GetConsoleWindow(^);^
%===% ';^
%===% $PROCESS_PER_MONITOR_DPI_AWARE=2;^
%===% try {$w::SetProcessDpiAwareness($PROCESS_PER_MONITOR_DPI_AWARE^)} catch {$w::SetProcessDPIAware(^)}^
%===% $x=0; $y=0;^
%===% if (([Int32]::TryParse(\"%%~j\"^, [ref]$x^) -eq $false^) -or ([Int32]::TryParse(\"%%~k\"^, [ref]$y^) -eq $false^)^){^
%=====% [Console]::Error.WriteLine(\"Syntax Error`r`n Usage:`r`n%%MoveWindow%% X Y`r`n   X  left side of the window`r`n   Y  top of the window\"^);^
%=====% exit 1;^
%===% }^
%===% exit [int]($w::SetWindowPos($w::GetConsoleWindow(^)^, [IntPtr]::Zero^, $x^, $y^, 0^, 0^, 5^) -eq 0^)} catch {exit 1}^"^
%=% )^
%=% ^&endlocal^
) else setlocal EnableDelayedExpansion ^&set arg=
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
::
for /f %%i in ('%ConsoleInfo%') do set /a "%%i"

rem cell size in dots
set /a "CellSize.X=%chx%, CellSize.Y=%chy%"

rem Current Size of cmd window/console window
set /a "ConsoleSize.X=%ccx%, ConsoleSize.Y=%ccy%"

:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

:: Flags to be used to update the bitset returned by the GetConsoleMode macro
::  and passed to the SetConsoleMode macro.
:: For more information refer to:
::  https://learn.microsoft.com/en-us/windows/console/getconsolemode
:: The flags for the input mode are 16 bits left-shifted in order to be able
::  getting both the input flags and the output flags merged in just one value.
:: ENABLE_AUTO_POSITION is undocumented.
:: Setting or removing ENABLE_EXTENDED_FLAGS is not effective because the
::  SetConsoleMode macro will overrule you by setting this flag by default. This
::  is necessary to make updates of ENABLE_QUICK_EDIT_MODE work.
set /a ^"^
 %= flags for the input mode =%^
  ENABLE_PROCESSED_INPUT             = 0x00010000,^
  ENABLE_LINE_INPUT                  = 0x00020000,^
  ENABLE_ECHO_INPUT                  = 0x00040000,^
  ENABLE_WINDOW_INPUT                = 0x00080000,^
  ENABLE_MOUSE_INPUT                 = 0x00100000,^
  ENABLE_INSERT_MODE                 = 0x00200000,^
  ENABLE_QUICK_EDIT_MODE             = 0x00400000,^
  ENABLE_EXTENDED_FLAGS              = 0x00800000,^
  ENABLE_AUTO_POSITION               = 0x01000000,^
  ENABLE_VIRTUAL_TERMINAL_INPUT      = 0x02000000,^
 %= flags for the output mode =%^
  ENABLE_PROCESSED_OUTPUT            = 0x00000001,^
  ENABLE_WRAP_AT_EOL_OUTPUT          = 0x00000002,^
  ENABLE_VIRTUAL_TERMINAL_PROCESSING = 0x00000004,^
  DISABLE_NEWLINE_AUTO_RETURN        = 0x00000008,^
  ENABLE_LVB_GRID_WORLDWIDE          = 0x00000010^"
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: Get the default mode of the console host.
:: The mode is returned as bitset in the errorlevel value.
set GetConsoleMode=^
%=% powershell -nop -ep Bypass -c ^"^
%===% $w=Add-Type -Name WAPI -PassThru -MemberDefinition '^
%=====% [DllImport(\"kernel32.dll\"^)]^
%=======% public static extern IntPtr GetStdHandle(int idx^);^
%=====% [DllImport(\"kernel32.dll\"^)]^
%=======% public static extern int GetConsoleMode(IntPtr h, ref int mode^);^
%===% ';^
%===% $STD_INPUT_HANDLE=-10;^
%===% $STD_OUTPUT_HANDLE=-11;^
%===% $inmode=0;^
%===% $inret=$w::GetConsoleMode($w::GetStdHandle($STD_INPUT_HANDLE^), [ref]$inmode^);^
%===% $outmode=0;^
%===% $outret=$w::GetConsoleMode($w::GetStdHandle($STD_OUTPUT_HANDLE^), [ref]$outmode^);^
%===% if (-not $inret -or -not $outret^) {exit -1;}^
%===% exit ($inmode -shl 16^) -bor $outmode;^
%=% ^"
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: Set the mode of the current console host session.
:: The mode is passed as integer which represents a bitset.
set SetConsoleMode=for %%# in (1 2) do if %%#==2 (for /f %%1 in ("^!arg^!"^) do (^
%=% powershell -nop -ep Bypass -c ^"^
%===% $w=Add-Type -Name WAPI -PassThru -MemberDefinition '^
%=====% [DllImport(\"kernel32.dll\"^)]^
%=======% public static extern IntPtr GetStdHandle(int idx^);^
%=====% [DllImport(\"kernel32.dll\"^)]^
%=======% public static extern int SetConsoleMode(IntPtr h, int mode^);^
%===% ';^
%===% $mode=0;^
%===% if ((-not [Int32]::TryParse(\"%%~1\"^, [ref]$mode^)^) -or ($mode -lt 0^)^) {exit 1;}^
%===% $STD_INPUT_HANDLE=-10;^
%===% $STD_OUTPUT_HANDLE=-11;^
%===% $inret=$w::SetConsoleMode($w::GetStdHandle($STD_INPUT_HANDLE^), ($mode -shr 16^) -bor 0x80^);^
%===% $outret=$w::SetConsoleMode($w::GetStdHandle($STD_OUTPUT_HANDLE^), $mode -band 0xFFFF^);^
%===% exit (-not $inret -or -not $outret^);^
%=% ^"^) ^&endlocal^) else setlocal EnableDelayedExpansion ^&set arg=
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

goto :eof
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:AndCenter

:: center the window
set /a "newX=cml+(cmr-cml)/2-cwx/2, newY=cmt+(cmb-cmt)/2-cwy/2"
%MoveWindow% %newX% %newY%

rem title Move to %newX%,%newY%

goto :eof

:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

:init_setfont
:: - BRIEF -
::  Get or set the console font size and font name.
:: - SYNTAX -
::  %setfont% [fontSize [fontName]]
::    fontSize   Size of the font. (Can be 0 to preserve the size.)
::    fontName   Name of the font. (Can be omitted to preserve the name.)
:: - EXAMPLES -
::  Output the current console font size and font name:
::    %setfont%
::  Set the console font size to 14 and the font name to Lucida Console:
::    %setfont% 14 Lucida Console
setlocal DisableDelayedExpansion
set setfont=for /l %%# in (1 1 2) do if %%#==2 (^
%=% for /f "tokens=1,2*" %%- in ("? ^^!arg^^!") do endlocal^&powershell.exe -nop -ep Bypass -c ^"Add-Type '^
%===% using System;^
%===% using System.Runtime.InteropServices;^
%===% [StructLayout(LayoutKind.Sequential,CharSet=CharSet.Unicode)] public struct FontInfo{^
%=====% public int objSize;^
%=====% public int nFont;^
%=====% public short fontSizeX;^
%=====% public short fontSizeY;^
%=====% public int fontFamily;^
%=====% public int fontWeight;^
%=====% [MarshalAs(UnmanagedType.ByValTStr,SizeConst=32)] public string faceName;}^
%===% public class WApi{^
%=====% [DllImport(\"kernel32.dll\")] public static extern IntPtr CreateFile(string name,int acc,int share,IntPtr sec,int how,int flags,IntPtr tmplt);^
%=====% [DllImport(\"kernel32.dll\")] public static extern void GetCurrentConsoleFontEx(IntPtr hOut,int maxWnd,ref FontInfo info);^
%=====% [DllImport(\"kernel32.dll\")] public static extern void SetCurrentConsoleFontEx(IntPtr hOut,int maxWnd,ref FontInfo info);^
%=====% [DllImport(\"kernel32.dll\")] public static extern void CloseHandle(IntPtr handle);}';^
%=% $hOut=[WApi]::CreateFile('CONOUT$',-1073741824,2,[IntPtr]::Zero,3,0,[IntPtr]::Zero);^
%=% $fInf=New-Object FontInfo;^
%=% $fInf.objSize=84;^
%=% [WApi]::GetCurrentConsoleFontEx($hOut,0,[ref]$fInf);^
%=% If('%%~.'){^
%===% $fInf.nFont=0; $fInf.fontSizeX=0; $fInf.fontFamily=0; $fInf.fontWeight=0;^
%===% If([Int16]'%%~.' -gt 0){$fInf.fontSizeY=[Int16]'%%~.'}^
%===% If('%%~/'){$fInf.faceName='%%~/'}^
%===% [WApi]::SetCurrentConsoleFontEx($hOut,0,[ref]$fInf);}^
%=% Else{(''+$fInf.fontSizeY+' '+$fInf.faceName)}^
%=% [WApi]::CloseHandle($hOut);^") else setlocal EnableDelayedExpansion^&set arg=
endlocal &set "setfont=%setfont%"
if !!# neq # set "setfont=%setfont:^^!=!%"
goto :eof
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:init

rem this code must execute after ConsoleInfo macro, if not this change font family to TERMINAL/RASTER, in window 10
chcp 65001 >nul

rem clear environment for faster execution of SET command
(
  for /F "Tokens=1 delims==" %%v in ('set') do set "%%v="
  set "Path=%SystemRoot%\system32"
  set /a "CellSize.X=%CellSize.X%, CellSize.Y=%CellSize.Y%"
  set /a "ConsoleSize.X=%ConsoleSize.X%, ConsoleSize.Y=%ConsoleSize.Y%"
)

rem for ansi sequence
for /F %%a in ('echo prompt $E^| cmd.exe') do set "ESC=%%a"

:: Hide the cursor
<nul set /p "=!ESC![?25l"

rem ALT+219
set "Char=█"
rem set "Char=*"

::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: macro Plot=Screen.Setpixel X Y R G B

set "Buffer="
rem (performance) variables ESC and Char are already defined, we expand them
rem only once during macro definition rather than each time the macro is called;
rem execute "likely" code in the IF branch, and "unlikely" code in the ELSE branch
set Plot=for %%# in (1 2) do if %%#==2 (^
%=% for /f "tokens=1-5 delims=, " %%1 in ("^!args^!") do (^
%===% if defined Buffer (^
%=====% if "^!Buffer:~100^!"=="" (^
%=======% set "Buffer=^!Buffer^!%ESC%[%%2;%%1H%ESC%[38;2;%%3;%%4;%%5m%Char%"^
%=====% ) else (^
%=======% ^<nul set /p "=^!Buffer^!%ESC%[%%2;%%1H%ESC%[38;2;%%3;%%4;%%5m%Char%%ESC%[0m"^
%=======% ^& set "Buffer="^
%=====% )^
%===% ) else (^
%=====% set "Buffer=%ESC%[%%2;%%1H%ESC%[38;2;%%3;%%4;%%5m%Char%"^
%===% )^
%=% )) else set args=

:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: Flush flush the variable buffer.

set Flush=^<nul set /p "=^!Buffer^!%ESC%[0m" ^& set "Buffer="

goto :eof
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:)
Last edited by einstein1969 on 13 Oct 2022 11:26, edited 1 time in total.

einstein1969
Expert
Posts: 960
Joined: 15 Jun 2012 13:16
Location: Italy, Rome

Re: Complete control of cmd windows

#66 Post by einstein1969 » 12 Oct 2022 12:03

There are too many clicks in the window size change. Do you have any ideas for minimizing and then eventually restoring the window?

I have tried with poor results

Code: Select all

powershell -window minimized -command ""

aGerman
Expert
Posts: 4678
Joined: 22 Jan 2010 18:01
Location: Germany

Re: Complete control of cmd windows

#67 Post by aGerman » 12 Oct 2022 12:54

this is a demo
Looks great :D
I'm afraid the more spheres you add the longer does it take. The console output is queued. This avoids race conditions. However, it also makes it literally impossible to write output from several processes really at the same time. It might be written interleaved but not in parallel.
I have tried with poor results
Hmm. It works just fine for me.

Code: Select all

@echo off &setlocal
powershell -window minimized -command ""
timeout 2
powershell -window normal -command ""
pause
However, you have to carefully order your tasks. My thoughts (without actually trying):
- you may fail to get the correct size properties from a minimized window
- you will most likely fail to resize the window buffer as long as it is minimized
- same with moving the window without making it automatically shown again
- however, you will likely succeed changing the font and mode flags even if the window is minimized

aGerman
Expert
Posts: 4678
Joined: 22 Jan 2010 18:01
Location: Germany

Re: Complete control of cmd windows

#68 Post by aGerman » 12 Oct 2022 13:33

Maybe this will work ... I don't recall if I ever published this macro. However, there's a possibility to make the window fully transparent (pass 100), and opaque again (pass 0). That way you don't need to minimize it.

Code: Select all

@echo off
setlocal EnableDelayedExpansion

call :init_transparent

echo(&echo  set 10%% transparency
%transparent% 10
if errorlevel 1 (echo error) else echo success
pause

echo(&echo  set 30%% transparency
%transparent% 30
if errorlevel 1 (echo error) else echo success
pause

echo(&echo  set opaque
%transparent% 0
if errorlevel 1 (echo error) else echo success
pause

for /l %%i in (0 10 100) do %transparent% %%i

exit /b


:init_transparent
setlocal DisableDelayedExpansion
:: Define the transparency of the console window.
:: Usage:
:: %transparent% percentage
::   percentage  0 (opaque) to 100 (limpid)
set transparent=for %%- in (1 2) do if %%-==2 (for /f %%. in ("^^!arg^^! x") do ^
%=% powershell -nop -ep Bypass -c ^"^
%===% $w=Add-Type -Name WAPI -PassThru -MemberDefinition '^
%=====% [DllImport(\"user32.dll\")]^
%=======% public static extern void SetWindowLong(IntPtr wnd, int idx, int newLong);^
%=====% [DllImport(\"user32.dll\")]^
%=======% public static extern void SetWindowLongPtr(IntPtr wnd, int idx, Int64 newLong);^
%=====% [DllImport(\"user32.dll\")]^
%=======% public static extern int GetWindowLong(IntPtr wnd, int idx);^
%=====% [DllImport(\"user32.dll\")]^
%=======% public static extern Int64 GetWindowLongPtr(IntPtr wnd, int idx);^
%=====% [DllImport(\"user32.dll\")]^
%=======% public static extern int SetLayeredWindowAttributes(IntPtr wnd, int color, byte alpha, int flags);^
%=====% [DllImport(\"kernel32.dll\")]^
%=======% public static extern IntPtr GetConsoleWindow();^
%===% ';^
%===% $val=0;^
%===% if (-not [Int32]::TryParse(\"%%~.\", [ref]$val) -or $val -lt 0 -or $val -gt 100) {exit 1;}^
%===% $GWL_EXSTYLE=-20;^
%===% $WS_EX_LAYERED=0x80000;^
%===% $wnd=$w::GetConsoleWindow();^
%===% if ([IntPtr]::Size -eq 4) { %= Win x86 =%^
%=====% $w::SetWindowLong($wnd, $GWL_EXSTYLE, $w::GetWindowLong($wnd, $GWL_EXSTYLE) -bOr $WS_EX_LAYERED);^
%===% } else { %= Win x64 =%^
%=====% $w::SetWindowLongPtr($wnd, $GWL_EXSTYLE, $w::GetWindowLongPtr($wnd, $GWL_EXSTYLE) -bOr [Int64]$WS_EX_LAYERED);^
%===% }^
%===% $LWA_ALPHA=2;^
%===% exit ($w::SetLayeredWindowAttributes($wnd, 0, [byte](2.55 * (100 - $val) + 0.5), $LWA_ALPHA) -eq 0);^
%=% ^" ^&endlocal) else setlocal EnableDelayedExpansion ^&set arg=

endlocal &set "transparent=%transparent%"
if !!# neq # set "transparent=%transparent:^^=%"
exit /b

einstein1969
Expert
Posts: 960
Joined: 15 Jun 2012 13:16
Location: Italy, Rome

Re: Complete control of cmd windows

#69 Post by einstein1969 » 13 Oct 2022 11:22

You are a genius! :shock:

This is a demo:

Code: Select all

@echo off & setlocal EnableDelayedExpansion 

rem save how utf8

call :GetInfo

set /a X=ccx/2, Y=ccy/2

mode con cols=!X! lines=!Y!

call :init_transparent

for %%L in (50 100) do %transparent% %%L

call  :init_setfont

%setfont% 8 Terminal

mode con cols=82 lines=50

call :GetInfo
call :AndCenter

chcp 65001

for /f "delims=" %%E in (
    'forfiles /p "%~dp0." /m "%~nx0" /c "cmd /c echo(0x1B"'
  ) do (
    cls
    echo(
    <nul set /p "=%%E7"
    set "cls=<nul set /p "=%%E8""
    set "col=%%E[38;2;"
:: Hide the cursor
   <nul set /p "=%%E[?25l"
)

for /F "delims==" %%f in ('set') do if /i not "%%f"=="cls" if /i not "%%f"=="col" if /i not "%%f"=="Path" if not %%f==SystemRoot if not %%f==TMP set "%%f="

call :init_transparent

for /L %%L in (100,-25,0) do %transparent% %%L

rem ALT+219
set "P=█ "
set /a n=0

set "c1=((( ( ((((15625*(4054-%%Y*128-%%X)) %% 2000000)/10000*(2048000000/(4054-%%Y*128-%%X)*2)/100)/100)-((2048000000/(4054-%%Y*128-%%X)*2)/100) + (%%N*10000/64) )/3000 ^ (2048000000/(4054-%%Y*128-%%X)*2)/100000) ) & 1)*10000000"
set "c2=((( ( ((((15625*(4053-%%Y*128-%%X)) %% 2000000)/10000*(2048000000/(4053-%%Y*128-%%X)*2)/100)/100)-((2048000000/(4053-%%Y*128-%%X)*2)/100) + (%%N*10000/64) )/3000 ^ (2048000000/(4053-%%Y*128-%%X)*2)/100000) ) & 1)*1000000" 
set "c3=((( ( ((((15625*(4052-%%Y*128-%%X)) %% 2000000)/10000*(2048000000/(4052-%%Y*128-%%X)*2)/100)/100)-((2048000000/(4052-%%Y*128-%%X)*2)/100) + (%%N*10000/64) )/3000 ^ (2048000000/(4052-%%Y*128-%%X)*2)/100000) ) & 1)*100000"
set "c4=((( ( ((((15625*(4051-%%Y*128-%%X)) %% 2000000)/10000*(2048000000/(4051-%%Y*128-%%X)*2)/100)/100)-((2048000000/(4051-%%Y*128-%%X)*2)/100) + (%%N*10000/64) )/3000 ^ (2048000000/(4051-%%Y*128-%%X)*2)/100000) ) & 1)*10000"
set "c5=((( ( ((((15625*(4050-%%Y*128-%%X)) %% 2000000)/10000*(2048000000/(4050-%%Y*128-%%X)*2)/100)/100)-((2048000000/(4050-%%Y*128-%%X)*2)/100) + (%%N*10000/64) )/3000 ^ (2048000000/(4050-%%Y*128-%%X)*2)/100000) ) & 1)*1000"
set "c6=((( ( ((((15625*(4049-%%Y*128-%%X)) %% 2000000)/10000*(2048000000/(4049-%%Y*128-%%X)*2)/100)/100)-((2048000000/(4049-%%Y*128-%%X)*2)/100) + (%%N*10000/64) )/3000 ^ (2048000000/(4049-%%Y*128-%%X)*2)/100000) ) & 1)*100"
set "c7=((( ( ((((15625*(4048-%%Y*128-%%X)) %% 2000000)/10000*(2048000000/(4048-%%Y*128-%%X)*2)/100)/100)-((2048000000/(4048-%%Y*128-%%X)*2)/100) + (%%N*10000/64) )/3000 ^ (2048000000/(4048-%%Y*128-%%X)*2)/100000) ) & 1)*10"
set "c8=((( ( ((((15625*(4047-%%Y*128-%%X)) %% 2000000)/10000*(2048000000/(4047-%%Y*128-%%X)*2)/100)/100)-((2048000000/(4047-%%Y*128-%%X)*2)/100) + (%%N*10000/64) )/3000 ^ (2048000000/(4047-%%Y*128-%%X)*2)/100000) ) & 1)"

rem 6.90fps, 8.55fps, 9.30fps, 9.74fps, 10,25fps

(
set cls=
set col=
set c1=
set c2=
set c3=
set c4=
set c5=
set c6=
set c7=
set c8=

for /L %%N in (-65,-1,-10000) do (


  %cls% 
  For /L %%Y in (6,-1,-28) do (
	set St=
	For /L %%X in (-20,8,52) do (

		set /a "a=100000000 + %c1% + %c2% + %c3% + %c4% + %c5% + %c6% + %c7% + %c8%"

		for /f "tokens=1-8" %%i in ("!a:~1,1! !a:~2,1! !a:~3,1! !a:~4,1! !a:~5,1! !a:~6,1! !a:~7,1! !a:~8,1!") do set St=!St!!P:~%%~i,1!!P:~%%~j,1!!P:~%%~k,1!!P:~%%~l,1!!P:~%%~m,1!!P:~%%~n,1!!P:~%%~o,1!!P:~%%~p,1!
	)
	
	set /a "H=H=(%%Y+28)*(2560/26)/10, V=(n+10)*40"

	if !V! gtr 10000 set V=10000

	set /a "mm = (h*10000/60 %% 20000) - 10000, mm=(mm>>31|1)*mm, C = V, X = C *(10000 - mm)/10000, C=C*255/10000, X=X*255/10000"

	if !H! lss 60 (set /a R=C, G=X, B=0) else (
   		if !H! lss 120 (set /a R=X, G=C, B=0) else (
      			if !H! lss 180 (set /a R=0, G=C, B=X) else (
         			if !H! lss 240 (set /a R=0, G=X, B=C) else (
            				if !H! lss 300 (set /a R=X, G=0, B=C) else (
               					if !H! lss 360 (set /a R=C, G=0, B=X) else (echo ERROR!)
            				)
         			)
      			)
   		)
	)

	echo( %col%!R!;!G!;!B!m!St!
  )

  set /a n+=1
 
  for /F "tokens=1-8 delims=:.," %%a in ("%time: =0%:!time: =0!") do set /a "a=(((1%%e-1%%a)*60)+1%%f-1%%b)*6000+1%%g%%h-1%%c%%d, a+=(a>>31) & 8640000, FPS=10000*n/a"
  title FPS=!FPS:~0,-2!.!FPS:~-2! &set "a="& set "FPS="
  
)
)

pause
goto :eof

:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:init_transparent
setlocal DisableDelayedExpansion
:: Define the transparency of the console window.
:: Usage:
:: %transparent% percentage
::   percentage  0 (opaque) to 100 (limpid)
set transparent=for %%- in (1 2) do if %%-==2 (for /f %%. in ("^^!arg^^! x") do ^
%=% powershell -nop -ep Bypass -c ^"^
%===% $w=Add-Type -Name WAPI -PassThru -MemberDefinition '^
%=====% [DllImport(\"user32.dll\")]^
%=======% public static extern void SetWindowLong(IntPtr wnd, int idx, int newLong);^
%=====% [DllImport(\"user32.dll\")]^
%=======% public static extern void SetWindowLongPtr(IntPtr wnd, int idx, Int64 newLong);^
%=====% [DllImport(\"user32.dll\")]^
%=======% public static extern int GetWindowLong(IntPtr wnd, int idx);^
%=====% [DllImport(\"user32.dll\")]^
%=======% public static extern Int64 GetWindowLongPtr(IntPtr wnd, int idx);^
%=====% [DllImport(\"user32.dll\")]^
%=======% public static extern int SetLayeredWindowAttributes(IntPtr wnd, int color, byte alpha, int flags);^
%=====% [DllImport(\"kernel32.dll\")]^
%=======% public static extern IntPtr GetConsoleWindow();^
%===% ';^
%===% $val=0;^
%===% if (-not [Int32]::TryParse(\"%%~.\", [ref]$val) -or $val -lt 0 -or $val -gt 100) {exit 1;}^
%===% $GWL_EXSTYLE=-20;^
%===% $WS_EX_LAYERED=0x80000;^
%===% $wnd=$w::GetConsoleWindow();^
%===% if ([IntPtr]::Size -eq 4) { %= Win x86 =%^
%=====% $w::SetWindowLong($wnd, $GWL_EXSTYLE, $w::GetWindowLong($wnd, $GWL_EXSTYLE) -bOr $WS_EX_LAYERED);^
%===% } else { %= Win x64 =%^
%=====% $w::SetWindowLongPtr($wnd, $GWL_EXSTYLE, $w::GetWindowLongPtr($wnd, $GWL_EXSTYLE) -bOr [Int64]$WS_EX_LAYERED);^
%===% }^
%===% $LWA_ALPHA=2;^
%===% exit ($w::SetLayeredWindowAttributes($wnd, 0, [byte](2.55 * (100 - $val) + 0.5), $LWA_ALPHA) -eq 0);^
%=% ^" ^&endlocal) else setlocal EnableDelayedExpansion ^&set arg=

endlocal &set "transparent=%transparent%"
if !!# neq # set "transparent=%transparent:^^=%"
exit /b
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:init_setfont
:: - BRIEF -
::  Get or set the console font size and font name.
:: - SYNTAX -
::  %setfont% [fontSize [fontName]]
::    fontSize   Size of the font. (Can be 0 to preserve the size.)
::    fontName   Name of the font. (Can be omitted to preserve the name.)
:: - EXAMPLES -
::  Output the current console font size and font name:
::    %setfont%
::  Set the console font size to 14 and the font name to Lucida Console:
::    %setfont% 14 Lucida Console
setlocal DisableDelayedExpansion
set setfont=for /l %%# in (1 1 2) do if %%#==2 (^
%=% for /f "tokens=1,2*" %%- in ("? ^^!arg^^!") do endlocal^&powershell.exe -nop -ep Bypass -c ^"Add-Type '^
%===% using System;^
%===% using System.Runtime.InteropServices;^
%===% [StructLayout(LayoutKind.Sequential,CharSet=CharSet.Unicode)] public struct FontInfo{^
%=====% public int objSize;^
%=====% public int nFont;^
%=====% public short fontSizeX;^
%=====% public short fontSizeY;^
%=====% public int fontFamily;^
%=====% public int fontWeight;^
%=====% [MarshalAs(UnmanagedType.ByValTStr,SizeConst=32)] public string faceName;}^
%===% public class WApi{^
%=====% [DllImport(\"kernel32.dll\")] public static extern IntPtr CreateFile(string name,int acc,int share,IntPtr sec,int how,int flags,IntPtr tmplt);^
%=====% [DllImport(\"kernel32.dll\")] public static extern void GetCurrentConsoleFontEx(IntPtr hOut,int maxWnd,ref FontInfo info);^
%=====% [DllImport(\"kernel32.dll\")] public static extern void SetCurrentConsoleFontEx(IntPtr hOut,int maxWnd,ref FontInfo info);^
%=====% [DllImport(\"kernel32.dll\")] public static extern void CloseHandle(IntPtr handle);}';^
%=% $hOut=[WApi]::CreateFile('CONOUT$',-1073741824,2,[IntPtr]::Zero,3,0,[IntPtr]::Zero);^
%=% $fInf=New-Object FontInfo;^
%=% $fInf.objSize=84;^
%=% [WApi]::GetCurrentConsoleFontEx($hOut,0,[ref]$fInf);^
%=% If('%%~.'){^
%===% $fInf.nFont=0; $fInf.fontSizeX=0; $fInf.fontFamily=0; $fInf.fontWeight=0;^
%===% If([Int16]'%%~.' -gt 0){$fInf.fontSizeX=[Int16]'%%~.';$fInf.fontSizeY=[Int16]'%%~.'}^
%===% If('%%~/'){$fInf.faceName='%%~/'}^
%===% [WApi]::SetCurrentConsoleFontEx($hOut,0,[ref]$fInf);}^
%=% Else{(''+$fInf.fontSizeY+' '+$fInf.faceName)}^
%=% [WApi]::CloseHandle($hOut);^") else setlocal EnableDelayedExpansion^&set arg=
endlocal &set "setfont=%setfont%"
if !!# neq # set "setfont=%setfont:^^!=!%"
goto :eof
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:GetInfo

::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: The %ConsoleInfo% macro collects properties of the console window and its environment.
:: It prints a string in the following format to StdOut:
::   cml=N,cmt=N,cmr=N,cmb=N,cwx=N,cwy=N,cvx=N,cvy=N,cfx=N,cfy=N,chx=N,chy=N,ccx=N,ccy=N,clx=N,cly=N
:: With:
::   N    different integral values of the below properties
::   cml  left dots boundary of the monitor's workspace
::   cmt  top dots boundary of the monitor's workspace
::   cmr  right dots boundary of the monitor's workspace
::   cmb  bottom dots boundary of the monitor's workspace
::   cwx  current width of the console window as number of dots
::   cwy  current height of the console window as number of dots
::   cvx  current width of the console viewport as number of dots
::   cvy  current height of the console viewport as number of dots
::   cfx  console font width as number of pixels
::   cfy  console font height as number of pixels
::   chx  approximated console charcell width as number of dots
::   chy  approximated console charcell height as number of dots
::   ccx  current width of the console client window as number of character cells
::   ccy  current height of the console client window as number of character cells
::   clx  largest width of the console client window as number of character cells
::   cly  largest height of the console client window as number of character cells
:: To define variables %cfx% .. %cly%, execute the macro in a FOR /F loop like that:
::   FOR /F %%I IN ('%ConsoleInfo%') DO SET /A "%%I"
set ConsoleInfo=^
powershell -nop -ep Bypass -c ^"^
%=% $w=Add-Type -Name WAPI -PassThru -MemberDefinition '^
%===% [DllImport(\"user32.dll\"^)]^
%=====% public static extern void SetProcessDPIAware(^);^
%===% [DllImport(\"shcore.dll\"^)]^
%=====% public static extern void SetProcessDpiAwareness(int value^);^
%===% [DllImport(\"kernel32.dll\"^)]^
%=====% public static extern IntPtr GetConsoleWindow(^);^
%===% [DllImport(\"user32.dll\"^)]^
%=====% public static extern void GetWindowRect(IntPtr hwnd, int[] rect^);^
%===% [DllImport(\"user32.dll\"^)]^
%=====% public static extern void GetClientRect(IntPtr hwnd, int[] rect^);^
%===% [DllImport(\"user32.dll\"^)]^
%=====% public static extern void GetMonitorInfoW(IntPtr hMonitor, int[] lpmi^);^
%===% [DllImport(\"user32.dll\"^)]^
%=====% public static extern IntPtr MonitorFromWindow(IntPtr hwnd, int dwFlags^);^
%===% [DllImport(\"kernel32.dll\"^)]^
%=====% public static extern IntPtr CreateFile(string name, int acc, int share, IntPtr sec, int how, int flags, IntPtr tmplt^);^
%===% [DllImport(\"kernel32.dll\"^)]^
%=====% public static extern void GetCurrentConsoleFont(IntPtr hOut, int isMax, int[] info^);^
%===% [DllImport(\"kernel32.dll\"^)]^
%=====% public static extern void CloseHandle(IntPtr h^);^
%=% ';^
 ^
%=% $PROCESS_PER_MONITOR_DPI_AWARE=2;^
%=% try {$w::SetProcessDpiAwareness($PROCESS_PER_MONITOR_DPI_AWARE^)} catch {$w::SetProcessDPIAware(^)}^
 ^
%=% $hwnd=$w::GetConsoleWindow(^);^
%=   The $moninf array is a replacement for the MONITORINFO structure. The elements at index         =% ^
%=   5, 6, 7, and 8 represent left, top, right, and bottom boundaries of the monitor's work space.   =% ^
%=% $moninf=[int[]]::new(10^);^
%=% $moninf[0]=40;^
%=% $MONITOR_DEFAULTTONEAREST=2;^
%=% $w::GetMonitorInfoW($w::MonitorFromWindow($hwnd, $MONITOR_DEFAULTTONEAREST^), $moninf^);^
 ^
%=   The $wrect array is a replacement for the RECT structure. The elements at index    =% ^
%=   0, 1, 2, and 3 represent left, top, right, and bottom boundaries of the window.   =% ^
%=% $wrect=[int[]]::new(4^);^
%=% $w::GetWindowRect($hwnd, $wrect^);^
 ^
%=   The $crect array is a replacement for the RECT structure. The elements at index          =% ^
%=   0, 1, 2, and 3 represent left, top, right, and bottom boundaries of the client window.   =% ^
%=% $crect=[int[]]::new(4^);^
%=% $w::GetClientRect($hwnd, $crect^);^
 ^
%=% $NIL=[IntPtr]::Zero;^
%=% $GENERIC_READ=0x80000000;^
%=% $GENERIC_WRITE=0x40000000;^
%=% $FILE_SHARE_WRITE=0x00000002;^
%=% $OPEN_EXISTING=3;^
%=   Because the StdOut stream is redirected to a pipe behind the scenes of a FOR /F loop,   =% ^
%=   we need to explicitly open a handle to the console output device (alias 'CONOUT$').     =% ^
%=% $out=$w::CreateFile('CONOUT$', $GENERIC_READ -bor $GENERIC_WRITE, $FILE_SHARE_WRITE, $NIL, $OPEN_EXISTING, 0, $NIL^);^
%=   The $fntinf array is a replacement for the CONSOLE_FONT_INFO structure. The 16 low order bits of the   =% ^
%=   second element represent the font width, while its 16 high order bits represent the font height.       =% ^
%=% $fntinf=[int[]]::new(2^);^
%=% $w::GetCurrentConsoleFont($out, 0, $fntinf^);^
%=% $w::CloseHandle($out^);^
 ^
%=% $raw=$host.UI.RawUI;^
%=% $cur=$raw.WindowSize;^
%=% $lrg=$raw.MaxPhysicalWindowSize;^
 ^
%=% 'cml={0},cmt={1},cmr={2},cmb={3},cwx={4},cwy={5},cvx={6},cvy={7},cfx={8},cfy={9},chx={10},chy={11},ccx={12},ccy={13},clx={14},cly={15}' -f^
%===% $moninf[5], $moninf[6], $moninf[7], $moninf[8],^
%===% ($wrect[2]-$wrect[0]^), ($wrect[3]-$wrect[1]^),^
%===% ($crect[2]-$crect[0]^), ($crect[3]-$crect[1]^),^
%===% ($fntinf[1] -band 0xFFFF^), ($fntinf[1] -shr 16^),^
%===% [math]::Round(($crect[2]-$crect[0]^)/$cur.Width^), [math]::Round(($crect[3]-$crect[1]^)/$cur.Height^),^
%===% $cur.Width, $cur.Height,^
%===% $lrg.Width, $lrg.Height;^
 ^"
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: %MoveWindow% X Y
::   X  left side of the window
::   Y  top of the window
set MoveWindow=for %%i in (1 2) do if %%i==2 (^
%=% for /f "tokens=1*" %%j in ("^!arg^!") do (powershell.exe -nop -ep Bypass -Command ^"^
%===% try {$w=Add-Type -Name WAPI -PassThru -MemberDefinition '^
%=====% [DllImport(\"user32.dll\"^)]^
%=======% public static extern void SetProcessDPIAware(^);^
%=====% [DllImport(\"shcore.dll\"^)]^
%=======% public static extern void SetProcessDpiAwareness(int value^);^
%=====% [DllImport(\"user32.dll\"^)]^
%=======% public static extern int SetWindowPos(IntPtr hWnd^, IntPtr hWndInsertAfter^, int X^, int Y^, int cx^, int cy^, uint uFlags^);^
%=====% [DllImport(\"kernel32.dll\"^)]^
%=======% public static extern IntPtr GetConsoleWindow(^);^
%===% ';^
%===% $PROCESS_PER_MONITOR_DPI_AWARE=2;^
%===% try {$w::SetProcessDpiAwareness($PROCESS_PER_MONITOR_DPI_AWARE^)} catch {$w::SetProcessDPIAware(^)}^
%===% $x=0; $y=0;^
%===% if (([Int32]::TryParse(\"%%~j\"^, [ref]$x^) -eq $false^) -or ([Int32]::TryParse(\"%%~k\"^, [ref]$y^) -eq $false^)^){^
%=====% [Console]::Error.WriteLine(\"Syntax Error`r`n Usage:`r`n%%MoveWindow%% X Y`r`n   X  left side of the window`r`n   Y  top of the window\"^);^
%=====% exit 1;^
%===% }^
%===% exit [int]($w::SetWindowPos($w::GetConsoleWindow(^)^, [IntPtr]::Zero^, $x^, $y^, 0^, 0^, 5^) -eq 0^)} catch {exit 1}^"^
%=% )^
%=% ^&endlocal^
) else setlocal EnableDelayedExpansion ^&set arg=
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
::
for /f %%i in ('%ConsoleInfo%') do set /a "%%i"
goto :eof
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:AndCenter

:: center the window
set /a "newX=cml+(cmr-cml)/2-cwx/2, newY=cmt+(cmb-cmt)/2-cwy/2"
%MoveWindow% %newX% %newY%

rem title Move to %newX%,%newY%

goto :eof

:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:)

Image

einstein1969
Expert
Posts: 960
Joined: 15 Jun 2012 13:16
Location: Italy, Rome

Re: Complete control of cmd windows

#70 Post by einstein1969 » 13 Oct 2022 12:22

continuous calls to powershell are very slow!!

Could you implement a pre-instantiation like dbenham did here?: https://www.dostips.com/forum/viewtopi ... 47#p46631

would be useful for the "move windows", "trasparent" and the "getInfo"

aGerman
Expert
Posts: 4678
Joined: 22 Jan 2010 18:01
Location: Germany

Re: Complete control of cmd windows

#71 Post by aGerman » 13 Oct 2022 13:18

This is a demo:
Another pretty example! :D

FWIW You can fade out the window at the very beginning. The ConsoleInfo macro and the MODE command will still work. Even if the window is limpid, it is still there. And better stay with 'echo prompt $E^| cmd.exe' for getting the escape character in order to continue supporting file names with special characters.
Could you implement a pre-instantiation like dbenham did here?
I don't think so. The reason is that all of the macros use platform invocation (the "DllImport..." stuff). Under the hood PowerShell writes those into a C# class code, compiles it to a temporary DLL file and uses it to get access to the Windows API.

einstein1969
Expert
Posts: 960
Joined: 15 Jun 2012 13:16
Location: Italy, Rome

Re: Complete control of cmd windows

#72 Post by einstein1969 » 13 Oct 2022 13:52

The "transparent" can be transformed into "Fade" in the sense that it takes 4 values (Trasparent_From, Trasparent_to, Trasparent_step, Delay_amount). You can implement in powershell a loop like?

Code: Select all

"For /L %%L in (Trasparent_From, Trasparent_step, Trasparent_to) do (Trasparent %%L & Delay_amount)"

aGerman
Expert
Posts: 4678
Joined: 22 Jan 2010 18:01
Location: Germany

Re: Complete control of cmd windows

#73 Post by aGerman » 13 Oct 2022 15:40

That's easy.

Code: Select all

@echo off
setlocal EnableDelayedExpansion

call :init_fade

%fade% 0 1 100 1
%fade% 100 -1 0 1

exit /b


:init_fade
setlocal DisableDelayedExpansion
:: fade the window in or out
:: Usage:
:: %fade% start end delay
::   start  percentage of transparency to begin with
::   step   number of percents the start value is changed in each iteration
::   end    percentage of transparency to end with
::   delay  milliseconds to wait between each step
set fade=for %%# in (1 2) do if %%#==2 (for /f "tokens=1-4" %%- in ("^^!args^^! x x x x") do ^
%=% powershell -nop -ep Bypass -c ^"^
%===% $w=Add-Type -Name WAPI -PassThru -MemberDefinition '^
%=====% [DllImport(\"user32.dll\")]^
%=======% public static extern void SetWindowLong(IntPtr wnd, int idx, int newLong);^
%=====% [DllImport(\"user32.dll\")]^
%=======% public static extern void SetWindowLongPtr(IntPtr wnd, int idx, Int64 newLong);^
%=====% [DllImport(\"user32.dll\")]^
%=======% public static extern int GetWindowLong(IntPtr wnd, int idx);^
%=====% [DllImport(\"user32.dll\")]^
%=======% public static extern Int64 GetWindowLongPtr(IntPtr wnd, int idx);^
%=====% [DllImport(\"user32.dll\")]^
%=======% public static extern void SetLayeredWindowAttributes(IntPtr wnd, int color, byte alpha, int flags);^
%=====% [DllImport(\"kernel32.dll\")]^
%=======% public static extern IntPtr GetConsoleWindow();^
%===% ';^
%===% $b=0; $s=0; $e=0; $d=0;^
%===% if (-not [Int32]::TryParse(\"%%~-\", [ref]$b) -or^
%=====% -not [Int32]::TryParse(\"%%~.\", [ref]$s) -or^
%=====% -not [Int32]::TryParse(\"%%~/\", [ref]$e) -or^
%=====% -not [Int32]::TryParse(\"%%~0\", [ref]$d) -or^
%=====% $b -lt 0 -or $b -gt 100 -or^
%=====% $e -lt 0 -or $e -gt 100 -or^
%=====% $d -lt 0^
%===% ) {exit 1;}^
%===% $GWL_EXSTYLE=-20;^
%===% $WS_EX_LAYERED=0x80000;^
%===% $wnd=$w::GetConsoleWindow();^
%===% if ([IntPtr]::Size -eq 4) { %= Win x86 =%^
%=====% $w::SetWindowLong($wnd, $GWL_EXSTYLE, $w::GetWindowLong($wnd, $GWL_EXSTYLE) -bOr $WS_EX_LAYERED);^
%===% } else { %= Win x64 =%^
%=====% $w::SetWindowLongPtr($wnd, $GWL_EXSTYLE, $w::GetWindowLongPtr($wnd, $GWL_EXSTYLE) -bOr [Int64]$WS_EX_LAYERED);^
%===% }^
%===% $LWA_ALPHA=2;^
%===% if (($b -lt $e) -and ($s -gt 0)) {^
%=====% for ($val=$b; $val -lt $e; $val=$val + $s) {^
%=======% $w::SetLayeredWindowAttributes($wnd, 0, [byte](2.55 * (100 - $val) + 0.5), $LWA_ALPHA);^
%=======% [Threading.Thread]::Sleep($d);^
%=====% }^
%===% } elseif (($b -gt $e) -and ($s -lt 0)) {^
%=====% for ($val=$b; $val -gt $e; $val=$val + $s) {^
%=======% $w::SetLayeredWindowAttributes($wnd, 0, [byte](2.55 * (100 - $val) + 0.5), $LWA_ALPHA);^
%=======% [Threading.Thread]::Sleep($d);^
%=====% }^
%===% } else {exit 1;}^
%===% $w::SetLayeredWindowAttributes($wnd, 0, [byte](2.55 * (100 - $e) + 0.5), $LWA_ALPHA);^
%=% ^" ^&endlocal) else setlocal EnableDelayedExpansion ^&set args=

endlocal &set "fade=%fade%"
if !!# neq # set "fade=%fade:^^=%"
exit /b
Almost everything you are doing to control the console host requires PowerShell. I'm more and more wondering why you don't just do the rest in PowerShell, too? You wouldn't have to bother with the repeated delays of umpteen new PowerShell instances in a batch code.

npocmaka_
Posts: 516
Joined: 24 Jun 2013 17:10
Location: Bulgaria
Contact:

Re: Complete control of cmd windows

#74 Post by npocmaka_ » 14 Oct 2022 03:09

Another approach could be a creation of lnk file and editing the ConsoleaDataBlock : https://learn.microsoft.com/en-us/opens ... 8695e8dd0c - it requires binary editing of that block.

Here's an old C# hybrid that tickles the quick edit mode - https://github.com/npocmaka/batch.scrip ... ckEdit.bat

This also can be useful: https://www.pinvoke.net/default.aspx/ke ... tions.html

einstein1969
Expert
Posts: 960
Joined: 15 Jun 2012 13:16
Location: Italy, Rome

Re: Complete control of cmd windows

#75 Post by einstein1969 » 14 Oct 2022 05:09

Sublime!

the precedent example little modified and usage of "fade"

Code: Select all

@echo off & setlocal EnableDelayedExpansion 

rem save how utf8

call :GetInfo

set /a X=ccx/2, Y=ccy/2

for /L %%L in (1,1,15) do (
	set /a nx=ccx/%%L, ny=ccy/%%L
        if !nx! leq 15 set nx=15
	mode con cols=!nx! lines=!ny!
)

call :init_fade

%fade% 0 10 100 1

call  :init_setfont

%setfont% 8 Terminal

mode con cols=82 lines=50

call :GetInfo
call :AndCenter

%fade% 100 -5 0 20

chcp 65001 >nul

for /f "delims=" %%E in (
    'forfiles /p "%~dp0." /m "%~nx0" /c "cmd /c echo(0x1B"'
  ) do (
    cls
    echo(
    <nul set /p "=%%E7"
    set "cls=<nul set /p "=%%E8""
    set "col=%%E[38;2;"
:: Hide the cursor
   <nul set /p "=%%E[?25l"
)

for /F "delims==" %%f in ('set') do if /i not "%%f"=="cls" if /i not "%%f"=="col" if /i not "%%f"=="Path" if not %%f==SystemRoot if not %%f==TMP set "%%f="

rem ALT+219
set "P=█ "
set /a n=0

set "c1=((( ( ((((15625*(4054-%%Y*128-%%X)) %% 2000000)/10000*(2048000000/(4054-%%Y*128-%%X)*2)/100)/100)-((2048000000/(4054-%%Y*128-%%X)*2)/100) + (%%N*10000/64) )/3000 ^ (2048000000/(4054-%%Y*128-%%X)*2)/100000) ) & 1)*10000000"
set "c2=((( ( ((((15625*(4053-%%Y*128-%%X)) %% 2000000)/10000*(2048000000/(4053-%%Y*128-%%X)*2)/100)/100)-((2048000000/(4053-%%Y*128-%%X)*2)/100) + (%%N*10000/64) )/3000 ^ (2048000000/(4053-%%Y*128-%%X)*2)/100000) ) & 1)*1000000" 
set "c3=((( ( ((((15625*(4052-%%Y*128-%%X)) %% 2000000)/10000*(2048000000/(4052-%%Y*128-%%X)*2)/100)/100)-((2048000000/(4052-%%Y*128-%%X)*2)/100) + (%%N*10000/64) )/3000 ^ (2048000000/(4052-%%Y*128-%%X)*2)/100000) ) & 1)*100000"
set "c4=((( ( ((((15625*(4051-%%Y*128-%%X)) %% 2000000)/10000*(2048000000/(4051-%%Y*128-%%X)*2)/100)/100)-((2048000000/(4051-%%Y*128-%%X)*2)/100) + (%%N*10000/64) )/3000 ^ (2048000000/(4051-%%Y*128-%%X)*2)/100000) ) & 1)*10000"
set "c5=((( ( ((((15625*(4050-%%Y*128-%%X)) %% 2000000)/10000*(2048000000/(4050-%%Y*128-%%X)*2)/100)/100)-((2048000000/(4050-%%Y*128-%%X)*2)/100) + (%%N*10000/64) )/3000 ^ (2048000000/(4050-%%Y*128-%%X)*2)/100000) ) & 1)*1000"
set "c6=((( ( ((((15625*(4049-%%Y*128-%%X)) %% 2000000)/10000*(2048000000/(4049-%%Y*128-%%X)*2)/100)/100)-((2048000000/(4049-%%Y*128-%%X)*2)/100) + (%%N*10000/64) )/3000 ^ (2048000000/(4049-%%Y*128-%%X)*2)/100000) ) & 1)*100"
set "c7=((( ( ((((15625*(4048-%%Y*128-%%X)) %% 2000000)/10000*(2048000000/(4048-%%Y*128-%%X)*2)/100)/100)-((2048000000/(4048-%%Y*128-%%X)*2)/100) + (%%N*10000/64) )/3000 ^ (2048000000/(4048-%%Y*128-%%X)*2)/100000) ) & 1)*10"
set "c8=((( ( ((((15625*(4047-%%Y*128-%%X)) %% 2000000)/10000*(2048000000/(4047-%%Y*128-%%X)*2)/100)/100)-((2048000000/(4047-%%Y*128-%%X)*2)/100) + (%%N*10000/64) )/3000 ^ (2048000000/(4047-%%Y*128-%%X)*2)/100000) ) & 1)"

rem 6.90fps, 8.55fps, 9.30fps, 9.74fps, 10,25fps

(
set cls=
set col=
set c1=
set c2=
set c3=
set c4=
set c5=
set c6=
set c7=
set c8=

for /L %%N in (-65,-1,-10000) do (


  %cls% 
  For /L %%Y in (6,-1,-33) do (
	set St=
	For /L %%X in (-20,8,52) do (

		set /a "a=100000000 + %c1% + %c2% + %c3% + %c4% + %c5% + %c6% + %c7% + %c8%"

		for /f "tokens=1-8" %%i in ("!a:~1,1! !a:~2,1! !a:~3,1! !a:~4,1! !a:~5,1! !a:~6,1! !a:~7,1! !a:~8,1!") do set St=!St!!P:~%%~i,1!!P:~%%~j,1!!P:~%%~k,1!!P:~%%~l,1!!P:~%%~m,1!!P:~%%~n,1!!P:~%%~o,1!!P:~%%~p,1!

	)
	
	set /a "H=H=(%%Y+33)*(2560/28)/10, V=(n+10)*40"

	if !V! gtr 10000 set V=10000

	set /a "mm = (h*10000/60 %% 20000) - 10000, mm=(mm>>31|1)*mm, C = V, X = C *(10000 - mm)/10000, C=C*255/10000, X=X*255/10000"

	if !H! lss 60 (set /a R=C, G=X, B=0) else (
   		if !H! lss 120 (set /a R=X, G=C, B=0) else (
      			if !H! lss 180 (set /a R=0, G=C, B=X) else (
         			if !H! lss 240 (set /a R=0, G=X, B=C) else (
            				if !H! lss 300 (set /a R=X, G=0, B=C) else (
               					if !H! lss 360 (set /a R=C, G=0, B=X) else (echo ERROR!)
            				)
         			)
      			)
   		)
	)

	echo( %col%!R!;!G!;!B!m!St!
  )

  set /a n+=1
 
  for /F "tokens=1-8 delims=:.," %%a in ("%time: =0%:!time: =0!") do set /a "a=(((1%%e-1%%a)*60)+1%%f-1%%b)*6000+1%%g%%h-1%%c%%d, a+=(a>>31) & 8640000, FPS=10000*n/a"
  title FPS=!FPS:~0,-2!.!FPS:~-2! &set "a="& set "FPS="
  
)
)

pause
goto :eof

:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:init_transparent
setlocal DisableDelayedExpansion
:: Define the transparency of the console window.
:: Usage:
:: %transparent% percentage
::   percentage  0 (opaque) to 100 (limpid)
set transparent=for %%- in (1 2) do if %%-==2 (for /f %%. in ("^^!arg^^! x") do ^
%=% powershell -nop -ep Bypass -c ^"^
%===% $w=Add-Type -Name WAPI -PassThru -MemberDefinition '^
%=====% [DllImport(\"user32.dll\")]^
%=======% public static extern void SetWindowLong(IntPtr wnd, int idx, int newLong);^
%=====% [DllImport(\"user32.dll\")]^
%=======% public static extern void SetWindowLongPtr(IntPtr wnd, int idx, Int64 newLong);^
%=====% [DllImport(\"user32.dll\")]^
%=======% public static extern int GetWindowLong(IntPtr wnd, int idx);^
%=====% [DllImport(\"user32.dll\")]^
%=======% public static extern Int64 GetWindowLongPtr(IntPtr wnd, int idx);^
%=====% [DllImport(\"user32.dll\")]^
%=======% public static extern int SetLayeredWindowAttributes(IntPtr wnd, int color, byte alpha, int flags);^
%=====% [DllImport(\"kernel32.dll\")]^
%=======% public static extern IntPtr GetConsoleWindow();^
%===% ';^
%===% $val=0;^
%===% if (-not [Int32]::TryParse(\"%%~.\", [ref]$val) -or $val -lt 0 -or $val -gt 100) {exit 1;}^
%===% $GWL_EXSTYLE=-20;^
%===% $WS_EX_LAYERED=0x80000;^
%===% $wnd=$w::GetConsoleWindow();^
%===% if ([IntPtr]::Size -eq 4) { %= Win x86 =%^
%=====% $w::SetWindowLong($wnd, $GWL_EXSTYLE, $w::GetWindowLong($wnd, $GWL_EXSTYLE) -bOr $WS_EX_LAYERED);^
%===% } else { %= Win x64 =%^
%=====% $w::SetWindowLongPtr($wnd, $GWL_EXSTYLE, $w::GetWindowLongPtr($wnd, $GWL_EXSTYLE) -bOr [Int64]$WS_EX_LAYERED);^
%===% }^
%===% $LWA_ALPHA=2;^
%===% exit ($w::SetLayeredWindowAttributes($wnd, 0, [byte](2.55 * (100 - $val) + 0.5), $LWA_ALPHA) -eq 0);^
%=% ^" ^&endlocal) else setlocal EnableDelayedExpansion ^&set arg=

endlocal &set "transparent=%transparent%"
if !!# neq # set "transparent=%transparent:^^=%"
exit /b
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:init_setfont
:: - BRIEF -
::  Get or set the console font size and font name.
:: - SYNTAX -
::  %setfont% [fontSize [fontName]]
::    fontSize   Size of the font. (Can be 0 to preserve the size.)
::    fontName   Name of the font. (Can be omitted to preserve the name.)
:: - EXAMPLES -
::  Output the current console font size and font name:
::    %setfont%
::  Set the console font size to 14 and the font name to Lucida Console:
::    %setfont% 14 Lucida Console
setlocal DisableDelayedExpansion
set setfont=for /l %%# in (1 1 2) do if %%#==2 (^
%=% for /f "tokens=1,2*" %%- in ("? ^^!arg^^!") do endlocal^&powershell.exe -nop -ep Bypass -c ^"Add-Type '^
%===% using System;^
%===% using System.Runtime.InteropServices;^
%===% [StructLayout(LayoutKind.Sequential,CharSet=CharSet.Unicode)] public struct FontInfo{^
%=====% public int objSize;^
%=====% public int nFont;^
%=====% public short fontSizeX;^
%=====% public short fontSizeY;^
%=====% public int fontFamily;^
%=====% public int fontWeight;^
%=====% [MarshalAs(UnmanagedType.ByValTStr,SizeConst=32)] public string faceName;}^
%===% public class WApi{^
%=====% [DllImport(\"kernel32.dll\")] public static extern IntPtr CreateFile(string name,int acc,int share,IntPtr sec,int how,int flags,IntPtr tmplt);^
%=====% [DllImport(\"kernel32.dll\")] public static extern void GetCurrentConsoleFontEx(IntPtr hOut,int maxWnd,ref FontInfo info);^
%=====% [DllImport(\"kernel32.dll\")] public static extern void SetCurrentConsoleFontEx(IntPtr hOut,int maxWnd,ref FontInfo info);^
%=====% [DllImport(\"kernel32.dll\")] public static extern void CloseHandle(IntPtr handle);}';^
%=% $hOut=[WApi]::CreateFile('CONOUT$',-1073741824,2,[IntPtr]::Zero,3,0,[IntPtr]::Zero);^
%=% $fInf=New-Object FontInfo;^
%=% $fInf.objSize=84;^
%=% [WApi]::GetCurrentConsoleFontEx($hOut,0,[ref]$fInf);^
%=% If('%%~.'){^
%===% $fInf.nFont=0; $fInf.fontSizeX=0; $fInf.fontFamily=0; $fInf.fontWeight=0;^
%===% If([Int16]'%%~.' -gt 0){$fInf.fontSizeX=[Int16]'%%~.';$fInf.fontSizeY=[Int16]'%%~.'}^
%===% If('%%~/'){$fInf.faceName='%%~/'}^
%===% [WApi]::SetCurrentConsoleFontEx($hOut,0,[ref]$fInf);}^
%=% Else{(''+$fInf.fontSizeY+' '+$fInf.faceName)}^
%=% [WApi]::CloseHandle($hOut);^") else setlocal EnableDelayedExpansion^&set arg=
endlocal &set "setfont=%setfont%"
if !!# neq # set "setfont=%setfont:^^!=!%"
goto :eof
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:GetInfo

::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: The %ConsoleInfo% macro collects properties of the console window and its environment.
:: It prints a string in the following format to StdOut:
::   cml=N,cmt=N,cmr=N,cmb=N,cwx=N,cwy=N,cvx=N,cvy=N,cfx=N,cfy=N,chx=N,chy=N,ccx=N,ccy=N,clx=N,cly=N
:: With:
::   N    different integral values of the below properties
::   cml  left dots boundary of the monitor's workspace
::   cmt  top dots boundary of the monitor's workspace
::   cmr  right dots boundary of the monitor's workspace
::   cmb  bottom dots boundary of the monitor's workspace
::   cwx  current width of the console window as number of dots
::   cwy  current height of the console window as number of dots
::   cvx  current width of the console viewport as number of dots
::   cvy  current height of the console viewport as number of dots
::   cfx  console font width as number of pixels
::   cfy  console font height as number of pixels
::   chx  approximated console charcell width as number of dots
::   chy  approximated console charcell height as number of dots
::   ccx  current width of the console client window as number of character cells
::   ccy  current height of the console client window as number of character cells
::   clx  largest width of the console client window as number of character cells
::   cly  largest height of the console client window as number of character cells
:: To define variables %cfx% .. %cly%, execute the macro in a FOR /F loop like that:
::   FOR /F %%I IN ('%ConsoleInfo%') DO SET /A "%%I"
set ConsoleInfo=^
powershell -nop -ep Bypass -c ^"^
%=% $w=Add-Type -Name WAPI -PassThru -MemberDefinition '^
%===% [DllImport(\"user32.dll\"^)]^
%=====% public static extern void SetProcessDPIAware(^);^
%===% [DllImport(\"shcore.dll\"^)]^
%=====% public static extern void SetProcessDpiAwareness(int value^);^
%===% [DllImport(\"kernel32.dll\"^)]^
%=====% public static extern IntPtr GetConsoleWindow(^);^
%===% [DllImport(\"user32.dll\"^)]^
%=====% public static extern void GetWindowRect(IntPtr hwnd, int[] rect^);^
%===% [DllImport(\"user32.dll\"^)]^
%=====% public static extern void GetClientRect(IntPtr hwnd, int[] rect^);^
%===% [DllImport(\"user32.dll\"^)]^
%=====% public static extern void GetMonitorInfoW(IntPtr hMonitor, int[] lpmi^);^
%===% [DllImport(\"user32.dll\"^)]^
%=====% public static extern IntPtr MonitorFromWindow(IntPtr hwnd, int dwFlags^);^
%===% [DllImport(\"kernel32.dll\"^)]^
%=====% public static extern IntPtr CreateFile(string name, int acc, int share, IntPtr sec, int how, int flags, IntPtr tmplt^);^
%===% [DllImport(\"kernel32.dll\"^)]^
%=====% public static extern void GetCurrentConsoleFont(IntPtr hOut, int isMax, int[] info^);^
%===% [DllImport(\"kernel32.dll\"^)]^
%=====% public static extern void CloseHandle(IntPtr h^);^
%=% ';^
 ^
%=% $PROCESS_PER_MONITOR_DPI_AWARE=2;^
%=% try {$w::SetProcessDpiAwareness($PROCESS_PER_MONITOR_DPI_AWARE^)} catch {$w::SetProcessDPIAware(^)}^
 ^
%=% $hwnd=$w::GetConsoleWindow(^);^
%=   The $moninf array is a replacement for the MONITORINFO structure. The elements at index         =% ^
%=   5, 6, 7, and 8 represent left, top, right, and bottom boundaries of the monitor's work space.   =% ^
%=% $moninf=[int[]]::new(10^);^
%=% $moninf[0]=40;^
%=% $MONITOR_DEFAULTTONEAREST=2;^
%=% $w::GetMonitorInfoW($w::MonitorFromWindow($hwnd, $MONITOR_DEFAULTTONEAREST^), $moninf^);^
 ^
%=   The $wrect array is a replacement for the RECT structure. The elements at index    =% ^
%=   0, 1, 2, and 3 represent left, top, right, and bottom boundaries of the window.   =% ^
%=% $wrect=[int[]]::new(4^);^
%=% $w::GetWindowRect($hwnd, $wrect^);^
 ^
%=   The $crect array is a replacement for the RECT structure. The elements at index          =% ^
%=   0, 1, 2, and 3 represent left, top, right, and bottom boundaries of the client window.   =% ^
%=% $crect=[int[]]::new(4^);^
%=% $w::GetClientRect($hwnd, $crect^);^
 ^
%=% $NIL=[IntPtr]::Zero;^
%=% $GENERIC_READ=0x80000000;^
%=% $GENERIC_WRITE=0x40000000;^
%=% $FILE_SHARE_WRITE=0x00000002;^
%=% $OPEN_EXISTING=3;^
%=   Because the StdOut stream is redirected to a pipe behind the scenes of a FOR /F loop,   =% ^
%=   we need to explicitly open a handle to the console output device (alias 'CONOUT$').     =% ^
%=% $out=$w::CreateFile('CONOUT$', $GENERIC_READ -bor $GENERIC_WRITE, $FILE_SHARE_WRITE, $NIL, $OPEN_EXISTING, 0, $NIL^);^
%=   The $fntinf array is a replacement for the CONSOLE_FONT_INFO structure. The 16 low order bits of the   =% ^
%=   second element represent the font width, while its 16 high order bits represent the font height.       =% ^
%=% $fntinf=[int[]]::new(2^);^
%=% $w::GetCurrentConsoleFont($out, 0, $fntinf^);^
%=% $w::CloseHandle($out^);^
 ^
%=% $raw=$host.UI.RawUI;^
%=% $cur=$raw.WindowSize;^
%=% $lrg=$raw.MaxPhysicalWindowSize;^
 ^
%=% 'cml={0},cmt={1},cmr={2},cmb={3},cwx={4},cwy={5},cvx={6},cvy={7},cfx={8},cfy={9},chx={10},chy={11},ccx={12},ccy={13},clx={14},cly={15}' -f^
%===% $moninf[5], $moninf[6], $moninf[7], $moninf[8],^
%===% ($wrect[2]-$wrect[0]^), ($wrect[3]-$wrect[1]^),^
%===% ($crect[2]-$crect[0]^), ($crect[3]-$crect[1]^),^
%===% ($fntinf[1] -band 0xFFFF^), ($fntinf[1] -shr 16^),^
%===% [math]::Round(($crect[2]-$crect[0]^)/$cur.Width^), [math]::Round(($crect[3]-$crect[1]^)/$cur.Height^),^
%===% $cur.Width, $cur.Height,^
%===% $lrg.Width, $lrg.Height;^
 ^"
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: %MoveWindow% X Y
::   X  left side of the window
::   Y  top of the window
set MoveWindow=for %%i in (1 2) do if %%i==2 (^
%=% for /f "tokens=1*" %%j in ("^!arg^!") do (powershell.exe -nop -ep Bypass -Command ^"^
%===% try {$w=Add-Type -Name WAPI -PassThru -MemberDefinition '^
%=====% [DllImport(\"user32.dll\"^)]^
%=======% public static extern void SetProcessDPIAware(^);^
%=====% [DllImport(\"shcore.dll\"^)]^
%=======% public static extern void SetProcessDpiAwareness(int value^);^
%=====% [DllImport(\"user32.dll\"^)]^
%=======% public static extern int SetWindowPos(IntPtr hWnd^, IntPtr hWndInsertAfter^, int X^, int Y^, int cx^, int cy^, uint uFlags^);^
%=====% [DllImport(\"kernel32.dll\"^)]^
%=======% public static extern IntPtr GetConsoleWindow(^);^
%===% ';^
%===% $PROCESS_PER_MONITOR_DPI_AWARE=2;^
%===% try {$w::SetProcessDpiAwareness($PROCESS_PER_MONITOR_DPI_AWARE^)} catch {$w::SetProcessDPIAware(^)}^
%===% $x=0; $y=0;^
%===% if (([Int32]::TryParse(\"%%~j\"^, [ref]$x^) -eq $false^) -or ([Int32]::TryParse(\"%%~k\"^, [ref]$y^) -eq $false^)^){^
%=====% [Console]::Error.WriteLine(\"Syntax Error`r`n Usage:`r`n%%MoveWindow%% X Y`r`n   X  left side of the window`r`n   Y  top of the window\"^);^
%=====% exit 1;^
%===% }^
%===% exit [int]($w::SetWindowPos($w::GetConsoleWindow(^)^, [IntPtr]::Zero^, $x^, $y^, 0^, 0^, 5^) -eq 0^)} catch {exit 1}^"^
%=% )^
%=% ^&endlocal^
) else setlocal EnableDelayedExpansion ^&set arg=
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
::
for /f %%i in ('%ConsoleInfo%') do set /a "%%i"
goto :eof
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:AndCenter

:: center the window
set /a "newX=cml+(cmr-cml)/2-cwx/2, newY=cmt+(cmb-cmt)/2-cwy/2"
%MoveWindow% %newX% %newY%

rem title Move to %newX%,%newY%

goto :eof
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:init_fade
setlocal DisableDelayedExpansion
:: fade the window in or out
:: Usage:
:: %fade% start step end delay
::   start  percentage of transparency to begin with
::   step   number of percents the start value is changed in each iteration
::   end    percentage of transparency to end with
::   delay  milliseconds to wait between each step
set fade=for %%# in (1 2) do if %%#==2 (for /f "tokens=1-4" %%- in ("^^!args^^! x x x x") do ^
%=% powershell -nop -ep Bypass -c ^"^
%===% $w=Add-Type -Name WAPI -PassThru -MemberDefinition '^
%=====% [DllImport(\"user32.dll\")]^
%=======% public static extern void SetWindowLong(IntPtr wnd, int idx, int newLong);^
%=====% [DllImport(\"user32.dll\")]^
%=======% public static extern void SetWindowLongPtr(IntPtr wnd, int idx, Int64 newLong);^
%=====% [DllImport(\"user32.dll\")]^
%=======% public static extern int GetWindowLong(IntPtr wnd, int idx);^
%=====% [DllImport(\"user32.dll\")]^
%=======% public static extern Int64 GetWindowLongPtr(IntPtr wnd, int idx);^
%=====% [DllImport(\"user32.dll\")]^
%=======% public static extern void SetLayeredWindowAttributes(IntPtr wnd, int color, byte alpha, int flags);^
%=====% [DllImport(\"kernel32.dll\")]^
%=======% public static extern IntPtr GetConsoleWindow();^
%===% ';^
%===% $b=0; $s=0; $e=0; $d=0;^
%===% if (-not [Int32]::TryParse(\"%%~-\", [ref]$b) -or^
%=====% -not [Int32]::TryParse(\"%%~.\", [ref]$s) -or^
%=====% -not [Int32]::TryParse(\"%%~/\", [ref]$e) -or^
%=====% -not [Int32]::TryParse(\"%%~0\", [ref]$d) -or^
%=====% $b -lt 0 -or $b -gt 100 -or^
%=====% $e -lt 0 -or $e -gt 100 -or^
%=====% $d -lt 0^
%===% ) {exit 1;}^
%===% $GWL_EXSTYLE=-20;^
%===% $WS_EX_LAYERED=0x80000;^
%===% $wnd=$w::GetConsoleWindow();^
%===% if ([IntPtr]::Size -eq 4) { %= Win x86 =%^
%=====% $w::SetWindowLong($wnd, $GWL_EXSTYLE, $w::GetWindowLong($wnd, $GWL_EXSTYLE) -bOr $WS_EX_LAYERED);^
%===% } else { %= Win x64 =%^
%=====% $w::SetWindowLongPtr($wnd, $GWL_EXSTYLE, $w::GetWindowLongPtr($wnd, $GWL_EXSTYLE) -bOr [Int64]$WS_EX_LAYERED);^
%===% }^
%===% $LWA_ALPHA=2;^
%===% if (($b -lt $e) -and ($s -gt 0)) {^
%=====% for ($val=$b; $val -lt $e; $val=$val + $s) {^
%=======% $w::SetLayeredWindowAttributes($wnd, 0, [byte](2.55 * (100 - $val) + 0.5), $LWA_ALPHA);^
%=======% [Threading.Thread]::Sleep($d);^
%=====% }^
%===% } elseif (($b -gt $e) -and ($s -lt 0)) {^
%=====% for ($val=$b; $val -gt $e; $val=$val + $s) {^
%=======% $w::SetLayeredWindowAttributes($wnd, 0, [byte](2.55 * (100 - $val) + 0.5), $LWA_ALPHA);^
%=======% [Threading.Thread]::Sleep($d);^
%=====% }^
%===% } else {exit 1;}^
%===% $w::SetLayeredWindowAttributes($wnd, 0, [byte](2.55 * (100 - $e) + 0.5), $LWA_ALPHA);^
%=% ^" ^&endlocal) else setlocal EnableDelayedExpansion ^&set args=

endlocal &set "fade=%fade%"
if !!# neq # set "fade=%fade:^^=%"
exit /b

Post Reply