Re: Complete control of cmd windows
Posted: 08 Oct 2022 15:41
Is it possible to make a move_window starting from the latter?
A Forum all about DOS Batch
https://www.dostips.com/forum/
Code: Select all
set move_window=for %%i in (1 2) do if %%i==2 (%\n%
%=% for /f "tokens=1*" %%j in ("^!arg^!") do (%\n%
powershell -NoProfile -ExecutionPolicy Bypass -Command ^"^
%=% $w=Add-Type -Name WAPI -PassThru -MemberDefinition '^
%===% [DllImport(\"kernel32.dll\")] static extern IntPtr GetConsoleWindow();^
%===% [DllImport(\"user32.dll\")] static extern void GetWindowRect(IntPtr hwnd,int[] rect);^
%===% [DllImport(\"user32.dll\")] static extern void GetMonitorInfoW(IntPtr hMonitor,int[] lpmi);^
%===% [DllImport(\"user32.dll\")] static extern IntPtr MonitorFromWindow(IntPtr hwnd,int dwFlags);^
%===% [DllImport(\"user32.dll\")] static extern void MoveWindow(IntPtr hwnd,int x,int y,int w,int h,int repaint);^
%===% public static void center() {^
%=====% var hwnd=GetConsoleWindow();^
%=====% var rect=new int[4];^
%=====% GetWindowRect(hwnd,rect);^
%=====% var moninf=new int[10];^
%=====% moninf[0]=40;^
%=====% GetMonitorInfoW(MonitorFromWindow(hwnd,2),moninf);^
%=====% MoveWindow(hwnd,^
%=======% %%~j,^
%=======% %%~k,^
%=======% rect[2]-rect[0],^
%=======% rect[3]-rect[1],^
%=======% 0);^
%===% }';^
%=% $w::center();^"%\n%
%=% )%\n%
%=% endlocal%\n%
) else setlocal EnableDelayedExpansion ^&set arg=
Code: Select all
@echo off &setlocal enableDelayedExpansion
mode con lines=20 cols=50
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: 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,cfx=N,cfy=N,ccx=N,ccy=N,clx=N,cly=N
:: With:
:: N different integral values of the below properties
:: cml left pixel boundary of the monitor's workspace
:: cmt top pixel boundary of the monitor's workspace
:: cmr right pixel boundary of the monitor's workspace
:: cmb bottom pixel boundary of the monitor's workspace
:: cwx current width of the console window as number of pixels
:: cwy current height of the console window as number of pixels
:: cfx console font width as number of pixels
:: cfy console font height as number of pixels
:: ccx current width of the console window as number of character cells
:: ccy current height of the console window as number of character cells
:: clx largest width of the console window as number of character cells
:: cly largest height of the console 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(\"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 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^);^
%=% ';^
^
%=% $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;^
%=% $w::GetMonitorInfoW($w::MonitorFromWindow($hwnd, 2^), $moninf^);^
^
%= The $rect 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. =% ^
%=% $rect=[int[]]::new(4^);^
%=% $w::GetWindowRect($hwnd, $rect^);^
^
%=% $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},cfx={6},cfy={7},ccx={8},ccy={9},clx={10},cly={11}' -f^
%===% $moninf[5], $moninf[6], $moninf[7], $moninf[8],^
%===% ($rect[2]-$rect[0]^), ($rect[3]-$rect[1]^),^
%===% ($fntinf[1] -band 0xFFFF^), ($fntinf[1] -shr 16^),^
%===% $cur.Width, $cur.Height,^
%===% $lrg.Width, $lrg.Height;^
^"
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
for /f %%i in ('%ConsoleInfo%') do set /a "%%i"
echo console monitor boundaries: %cml%, %cmt%, %cmr%, %cmb%
echo console window size: %cwx%, %cwy%
echo console font size: %cfx%, %cfy%
echo console current size: %ccx%, %ccy%
echo console largest size: %clx%, %cly%
echo(
rem for macro definition/readability
(set \n=^^^
%= This creates an escaped Line Feed - DO NOT ALTER =%
)
set move_window=for %%i in (1 2) do if %%i==2 (%\n%
%=% for /f "tokens=1*" %%j in ("^!arg^!") do (%\n%
%=====% powershell.exe -NoProfile -ExecutionPolicy Bypass -Command ^"try{$c=Add-Type -Name WinAPI -PassThru -MemberDefinition '^
%=====% [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(^);';^
%=====% $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%%move_window%% X Y`r`n X left side of the window`r`n Y top of the window\"^);^
%=========% exit 1;^
%=====% }^
%=====% exit [int]($c::SetWindowPos($c::GetConsoleWindow(^)^, [IntPtr]::Zero^, $x^, $y^, 0^, 0^, 5^) -eq 0^);}catch{exit 1;}^"%\n%
%=% )%\n%
%=% endlocal%\n%
) else setlocal EnableDelayedExpansion ^&set arg=
:: center the window
set /a "newX=cml+(cmr-cml)/2-cwx/2"
set /a "newY=cmt+(cmb-cmt)/2-cwy/2"
%move_window% %newX% %newY%
pause
Code: Select all
console monitor boundaries: 0, 0, 1920, 1040
console window size: 366, 739
console font size: 7, 14
console current size: 50, 50
console largest size: 274, 72
calculate window size: 350 700
misurated 350x730 header 30px
Premere un tasto per continuare . . .
Code: Select all
@echo off & setlocal enableDelayedExpansion & if NOT "%1"=="" goto :subs
Start "Sphere" "%0" .
goto :eof
:subs
rem test with font 7x14 courier new
mode con lines=50 cols=50
call :init
echo console monitor boundaries: %cml%, %cmt%, %cmr%, %cmb%
echo console window size: %cwx%, %cwy%
echo console font size: %cfx%, %cfy%
echo console current size: %ccx%, %ccy%
echo console largest size: %clx%, %cly%
echo(
set /a cws.X=cfx*ccx, cws.Y=cfy*ccy
echo calculate window size: %cws.X% %cws.Y%
echo misurated 350x730 header 30px
pause
goto :eof
:: center the window
set /a "newX=cml+(cmr-cml)/2-cwx/2"
set /a "newY=cmt+(cmb-cmt)/2-cwy/2"
%move_window% %newX% %newY%
pause
rem choose console size
set /A img.x=50, img.y=50
(
rem setting request console size and remove buffers size on max
mode CON: COLS=!img.x! LINES=!img.y!
rem update Consoleinfo, I don't launch powershell again for the bug on win10 for chcp 65001
set /A ConsoleSize.X=img.x, ConsoleSize.Y=img.y
)
rem center the windows
(
rem is strange formula but work well
set /A "center.x=(Screen.Width-img.x*FontSize.X)/2-8"
rem to do : tuning.
set /A "center.y=(Screen.height-img.y*FontSize.Y)/2-8-35"
%move_window% !center.x! !center.y!
)
pause>nul
goto :eof
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:init
rem clear environment for faster execution of SET command
(
rem set "Path=%SystemRoot%\system32"
for /F "Tokens=1 delims==" %%v in ('set') do if not %%v==ESC if not %%v==TMP if not %%v==Path if not %%v==SystemRoot set "%%v="
)
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: 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,cfx=N,cfy=N,ccx=N,ccy=N,clx=N,cly=N
:: With:
:: N different integral values of the below properties
:: cml left pixel boundary of the monitor's workspace
:: cmt top pixel boundary of the monitor's workspace
:: cmr right pixel boundary of the monitor's workspace
:: cmb bottom pixel boundary of the monitor's workspace
:: cwx current width of the console window as number of pixels
:: cwy current height of the console window as number of pixels
:: cfx console font width as number of pixels
:: cfy console font height as number of pixels
:: ccx current width of the console window as number of character cells
:: ccy current height of the console window as number of character cells
:: clx largest width of the console window as number of character cells
:: cly largest height of the console 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(\"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 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^);^
%=% ';^
^
%=% $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;^
%=% $w::GetMonitorInfoW($w::MonitorFromWindow($hwnd, 2^), $moninf^);^
^
%= The $rect 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. =% ^
%=% $rect=[int[]]::new(4^);^
%=% $w::GetWindowRect($hwnd, $rect^);^
^
%=% $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},cfx={6},cfy={7},ccx={8},ccy={9},clx={10},cly={11}' -f^
%===% $moninf[5], $moninf[6], $moninf[7], $moninf[8],^
%===% ($rect[2]-$rect[0]^), ($rect[3]-$rect[1]^),^
%===% ($fntinf[1] -band 0xFFFF^), ($fntinf[1] -shr 16^),^
%===% $cur.Width, $cur.Height,^
%===% $lrg.Width, $lrg.Height;^
^"
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
for /f %%i in ('%ConsoleInfo%') do set /a "%%i"
rem echo console monitor boundaries: %cml%, %cmt%, %cmr%, %cmb%
rem echo console window size: %cwx%, %cwy%
rem echo console font size: %cfx%, %cfy%
rem echo console current size: %ccx%, %ccy%
rem echo console largest size: %clx%, %cly%
rem echo(
rem font size in pixels
set /a "FontSize.X=%cfx%, FontSize.Y=%cfy%"
rem max/largest Size of cmd window/console window in chars
set /a "MaxConsoleSize.X=%clx%, MaxConsoleSize.Y=%cly%"
rem Current Size of cmd window/console window in chars
set /a "ConsoleSize.X=%ccx%, ConsoleSize.Y=%ccy%"
rem console window size in pixels
set /a "ConsoleWindowSize.X=%cwx%, ConsoleWindowSize.Y=%cwy%"
rem console monitor boundaries
set /A Monitor.left=%cml%, Monitor.top=%cmt% ,Monitor.right=%cmr% ,Monitor.bottom=%cmb%
rem get resolution of screen
for /f "usebackq tokens=1,2 delims= " %%x in (`mshta "javascript:new ActiveXObject('Scripting.FileSystemObject').GetStandardStream(1).Write(screen.width+' '+screen.height);close();noflash"`) do set /A Screen.Width=%%x, Screen.Height=%%y
rem for macro definition/readability
(set \n=^^^
%= This creates an escaped Line Feed - DO NOT ALTER =%
)
set move_window=for %%i in (1 2) do if %%i==2 (%\n%
%=% for /f "tokens=1*" %%j in ("^!arg^!") do (%\n%
%=====% powershell.exe -NoProfile -ExecutionPolicy Bypass -Command ^"try{$c=Add-Type -Name WinAPI -PassThru -MemberDefinition '^
%=====% [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(^);';^
%=====% $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%%move_window%% X Y`r`n X left side of the window`r`n Y top of the window\"^);^
%=========% exit 1;^
%=====% }^
%=====% exit [int]($c::SetWindowPos($c::GetConsoleWindow(^)^, [IntPtr]::Zero^, $x^, $y^, 0^, 0^, 5^) -eq 0^);}catch{exit 1;}^"%\n%
%=% )%\n%
%=% endlocal%\n%
) else setlocal EnableDelayedExpansion ^&set arg=
:: center the window
rem set /a "newX=cml+(cmr-cml)/2-cwx/2"
rem set /a "newY=cmt+(cmb-cmt)/2-cwy/2"
rem %rem move_window% %newX% %newY%
rem pause
Code: Select all
@echo off &setlocal enableDelayedExpansion
mode con lines=20 cols=50
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: 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;^
^"
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
for /f %%i in ('%ConsoleInfo%') do set /a "%%i"
echo console monitor boundaries: %cml%, %cmt%, %cmr%, %cmb%
echo console window size: %cwx%, %cwy%
echo console viewport size: %cvx%, %cvy%
echo console font size: %cfx%, %cfy%
echo console charcell size: %chx%, %chy%
echo console current size: %ccx%, %ccy%
echo console largest size: %clx%, %cly%
echo(
rem for macro definition/readability
(set \n=^^^
%= This creates an escaped Line Feed - DO NOT ALTER =%
)
set move_window=for %%i in (1 2) do if %%i==2 (%\n%
%=% for /f "tokens=1*" %%j in ("^!arg^!") do (%\n%
%=====% powershell.exe -NoProfile -ExecutionPolicy Bypass -Command ^"try{$c=Add-Type -Name WinAPI -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(^);';^
%=====% try{$c::SetProcessDpiAwareness(2^)}catch{$c::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%%move_window%% X Y`r`n X left side of the window`r`n Y top of the window\"^);^
%=========% exit 1;^
%=====% }^
%=====% exit [int]($c::SetWindowPos($c::GetConsoleWindow(^)^, [IntPtr]::Zero^, $x^, $y^, 0^, 0^, 5^) -eq 0^);}catch{exit 1;}^"%\n%
%=% )%\n%
%=% endlocal%\n%
) else setlocal EnableDelayedExpansion ^&set arg=
:: center the window
set /a "newX=cml+(cmr-cml)/2-cwx/2"
set /a "newY=cmt+(cmb-cmt)/2-cwy/2"
%move_window% %newX% %newY%
pause
Code: Select all
@echo off
rem save this script in UTF-8
set "me=%~f0"
setlocal enableDelayedExpansion
if "%1"=="" (
rem restart maximized
Start "Sphere" /MAX cmd.exe /c ""!me!" max"
goto :eof
)
if "%1"=="sphere" (
call :sphere %2 %3 %4 %5 %6 %7
goto :eof
)
rem "%1" is "max" if we reach out to this point
call :GetInfo
rem setting request console size and remove buffers size on max
mode CON: COLS=!ConsoleSize.X! LINES=!ConsoleSize.Y!
rem multithread 9 thread
set /A "deltaX=ConsoleSize.X/3, deltaY=ConsoleSize.Y/3, Radius=deltaY/2"
start "" /B cmd.exe /c ""!me!" sphere Red 1 1 !deltaX! !deltaY! !Radius!"
start "" /B cmd.exe /c ""!me!" sphere Green !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 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 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!"
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"
rem (performance) we compare colors first instead of doing it for each painted cell
if "%1"=="Red" (
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"
if !S! leq 0 %plot% %%x %%y !C! 0 0
)
)
%flush%
goto :eof
)
if "%1"=="Green" (
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"
if !S! leq 0 %plot% %%x %%y 0 !C! 0
)
)
%flush%
goto :eof
)
if "%1"=="Blue" (
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"
if !S! leq 0 %plot% %%x %%y 0 0 !C!
)
)
%flush%
goto :eof
)
if "%1"=="Yellow" (
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"
if !S! leq 0 %plot% %%x %%y !C! !C! 0
)
)
%flush%
goto :eof
)
if "%1"=="Cyan" (
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"
if !S! leq 0 %plot% %%x %%y 0 !C! !C!
)
)
%flush%
goto :eof
)
if "%1"=="Magenta" (
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"
if !S! leq 0 %plot% %%x %%y !C! 0 !C!
)
)
%flush%
goto :eof
)
if "%1"=="White" (
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"
if !S! leq 0 %plot% %%x %%y !C! !C! !C!
)
)
%flush%
goto :eof
)
if "%1"=="Orange" (
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 !C! !CL! 0
)
)
%flush%
goto :eof
)
if "%1"=="Pink" (
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 !C! 0 !CL!
)
)
%flush%
goto :eof
)
%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;^
^"
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
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%"
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=*"
rem for macro definition/readability
(set \n=^^^
%= This creates an escaped Line Feed - DO NOT ALTER =%
)
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: macro Plot=Screen.Setpixel X Y R G B
set "Buffer="
set Plot=for %%# in (1 2) do if %%#==2 (%\n%
for /f "tokens=1-5 delims=, " %%1 in ("^!args^!") do ( %\n%
if not defined Buffer (%\n%
set "Buffer=^!ESC^![%%2;%%1H^!ESC^![38;2;%%3;%%4;%%5m^!Char^!" %\n%
) else ( %\n%
if "^!Buffer:~100,1^!"=="" ( %\n%
set "Buffer=^!Buffer^!^!ESC^![%%2;%%1H^!ESC^![38;2;%%3;%%4;%%5m^!Char^!" %\n%
) else ( %\n%
^<nul set /p "=^!Buffer^!^!ESC^![%%2;%%1H^!ESC^![38;2;%%3;%%4;%%5m^!Char^!^!ESC^![0m" %\n%
set "Buffer=" %\n%
) %\n%
) %\n%
)) else set args=
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: Flush flush the variable buffer.
set Flush=^<nul set /p "=^!Buffer^!^!ESC^![0m" ^& set "Buffer="
goto :eof
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
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
)
title Spheres
mode CON: COLS=100 LINES=40
call :GetInfoAndCenter
rem multithread 9 thread
set /A "deltaX=ConsoleSize.X/3, deltaY=ConsoleSize.Y/3, Radius=deltaY/2"
start "" /B cmd.exe /c ""!me!" sphere Red 1 1 !deltaX! !deltaY! !Radius!"
start "" /B cmd.exe /c ""!me!" sphere Green !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 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 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!"
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"
rem (performance) we compare colors first instead of doing it for each painted cell
if "%1"=="Red" (
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"
if !S! leq 0 %plot% %%x %%y !C! 0 0
)
)
%flush%
goto :eof
)
if "%1"=="Green" (
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"
if !S! leq 0 %plot% %%x %%y 0 !C! 0
)
)
%flush%
goto :eof
)
if "%1"=="Blue" (
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"
if !S! leq 0 %plot% %%x %%y 0 0 !C!
)
)
%flush%
goto :eof
)
if "%1"=="Yellow" (
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"
if !S! leq 0 %plot% %%x %%y !C! !C! 0
)
)
%flush%
goto :eof
)
if "%1"=="Cyan" (
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"
if !S! leq 0 %plot% %%x %%y 0 !C! !C!
)
)
%flush%
goto :eof
)
if "%1"=="Magenta" (
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"
if !S! leq 0 %plot% %%x %%y !C! 0 !C!
)
)
%flush%
goto :eof
)
if "%1"=="White" (
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"
if !S! leq 0 %plot% %%x %%y !C! !C! !C!
)
)
%flush%
goto :eof
)
if "%1"=="Orange" (
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 !C! !CL! 0
)
)
%flush%
goto :eof
)
if "%1"=="Pink" (
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 !C! 0 !CL!
)
)
%flush%
goto :eof
)
goto :eof
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:GetInfoAndCenter
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: 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"
:: center the window
set /a "newX=cml+(cmr-cml)/2-cwx/2, newY=cmt+(cmb-cmt)/2-cwy/2"
%MoveWindow% %newX% %newY%
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%"
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
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
Code: Select all
console monitor boundaries: 0, 0, 1920, 1030
console window size: 1058, 587
console viewport size: 1040, 540
console font size: 6, 14
console charcell size: 8, 18
console current size: 130, 30
console largest size: 240, 55
Code: Select all
console monitor boundaries is OK
console window size NOT OK
console viewport size is OK
console font size NOT OK
console charcell is OK
console current size is OK
console largest size is OK
Code: Select all
:: center the window
set /a "newX=cml+(cmr-cml)/2-cwx/2"
set /a "newY=cmt+(cmb-cmt)/2-cwy/2"
Code: Select all
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"=="Green" 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^!"
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"
if !S! leq 0 %plot% %%x %%y %RGB%
)
)
%flush%
goto :eof
Yeah, good ideafor reduce code you can use this part
Yes, the centering is still good although the data seem incorrect.aGerman wrote: ↑09 Oct 2022 16:12It's a mess if you try inferring dots from pixels. I actually trust the values I get from the API because the results are promising. Centering works well for me.
And in order to avoid working with the font size in pixels (reported by the Console API), I calculate the size of the character cells in dots from values reported by the GDI API. This is more relying and makes spheres round with all fonts and font sizes I tried.
Yeah, good ideafor reduce code you can use this part
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
)
title Spheres
mode CON: COLS=100 LINES=50
call :GetInfo
set /A Newsize.X=clx-1, Newsize.Y=cly-2
mode CON: COLS=!Newsize.X! LINES=!Newsize.Y!
call :GetInfo
call :AndCenter
rem multithread 9 thread
set /A "deltaX=ConsoleSize.X/3, deltaY=ConsoleSize.Y/3, Radius=deltaY/2"
start "" /B cmd.exe /c ""!me!" sphere Red 1 1 !deltaX! !deltaY! !Radius!"
start "" /B cmd.exe /c ""!me!" sphere Green !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 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 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!"
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"=="Green" 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^!"
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"
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%"
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%
title Move to %newX%,%newY%
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
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::