Complete control of cmd windows
Moderator: DosItHelp
-
- Expert
- Posts: 960
- Joined: 15 Jun 2012 13:16
- Location: Italy, Rome
-
- Expert
- Posts: 960
- Joined: 15 Jun 2012 13:16
- Location: Italy, Rome
Re: Complete control of cmd windows
I am doing some testing and found a problem when I center a window and have the screen zoom setting at 125%. Can you give me feedback? I can't find a solution.
this is a code used to do the test.
this is a code used to do the test.
Code: Select all
@echo off & setlocal enableDelayedExpansion & if NOT "%1"=="" goto :subs
rem save this script in UTF-8
rem test other mode (aspect ratio /font size)
Start "Sphere" "%0" .
goto :eof
:subs
call :init
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 many thanks aGerman and Aacini
set ConsoleInfo=^
powershell ^
^"$w=Add-Type -Name WAPI -PassThru -MemberDefinition ' ^
[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^); ^
'; ^
[int[]]$info=0,0; ^
$h=$w::CreateFile('CONOUT$',0xC0000000,2,[IntPtr]::Zero,3,0,[IntPtr]::Zero^); ^
$w::GetCurrentConsoleFont($h,0,$info^); ^
$w::CloseHandle($h^); ^
\"cfx^=$($info[1] -band 0xFFFF^)^,cfy^=$($info[1] -shr 16^)\"; ^
$r=$host.UI.RawUI; ^
$c=$r.WindowSize; ^
\"ccx^=$($c.Width^)^,ccy^=$($c.Height^)\"; ^
$l=$r.MaxPhysicalWindowSize; ^
\",clx^=$($l.Width^)^,cly^=$($l.Height^)\"; ^
^"
for /f %%i in ('%ConsoleInfo%') do set /a "%%i"
rem font size in pixels
set /a "FontSize.X=%cfx%, FontSize.Y=%cfy%"
rem max/largest Size of cmd window/console window
set /a "MaxConsoleSize.X=%clx%, MaxConsoleSize.Y=%cly%"
rem Current Size of cmd window/console window
set /a "ConsoleSize.X=%ccx%, ConsoleSize.Y=%ccy%"
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 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="
set /a "FontSize.X=%FontSize.X% , FontSize.Y=%FontSize.Y%"
set /a "ConsoleSize.X=%ConsoleSize.X% , ConsoleSize.Y=%ConsoleSize.Y%"
set /a "MaxConsoleSize.X=%MaxConsoleSize.X% , MaxConsoleSize.Y=%MaxConsoleSize.Y%"
set /A Screen.Width=%Screen.Width%, Screen.Height=%Screen.Height%
)
rem this code must execute after GetConsoleFontSize macro, if not this change font family to TERMINAL/RASTER, in window 10
chcp 65001 >nul
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=
goto :eof
-
- Expert
- Posts: 960
- Joined: 15 Jun 2012 13:16
- Location: Italy, Rome
Re: Complete control of cmd windows
also there is a bug that if I execute the move_window after the selection of the page 65001 the fonts are changed in raster / terminal
but at this point i try to see if i can move chcp 65001 after move_window
but at this point i try to see if i can move chcp 65001 after move_window
Re: Complete control of cmd windows
I think you need DPI awareness.
......
...
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.exe -NoProfile -ExecutionPolicy Bypass -Command ^"try{$c=Add-Type -Name WinAPI -PassThru -MemberDefinition '^
%=====% [DllImport(\"user32.dll\"^)] public static extern void SetProcessDPIAware(^);^
%=====% [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(^);';^
%=====% $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=
-
- Expert
- Posts: 960
- Joined: 15 Jun 2012 13:16
- Location: Italy, Rome
Re: Complete control of cmd windows
work well for raster/terminal fontsaGerman wrote: ↑08 Oct 2022 07:16I think you need DPI awareness.
......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.exe -NoProfile -ExecutionPolicy Bypass -Command ^"try{$c=Add-Type -Name WinAPI -PassThru -MemberDefinition '^ %=====% [DllImport(\"user32.dll\"^)] public static extern void SetProcessDPIAware(^);^ %=====% [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(^);';^ %=====% $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=
for other fonts work on X but on Y don't
Code: Select all
@echo off & setlocal enableDelayedExpansion & if NOT "%1"=="" goto :subs
rem save this script in UTF-8
rem test other mode (aspect ratio /font size)
Start "Sphere" "%0" .
goto :eof
:subs
call :init
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
)
pause
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 many thanks aGerman and Aacini
set ConsoleInfo=^
powershell ^
^"$w=Add-Type -Name WAPI -PassThru -MemberDefinition ' ^
[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^); ^
'; ^
[int[]]$info=0,0; ^
$h=$w::CreateFile('CONOUT$',0xC0000000,2,[IntPtr]::Zero,3,0,[IntPtr]::Zero^); ^
$w::GetCurrentConsoleFont($h,0,$info^); ^
$w::CloseHandle($h^); ^
\"cfx^=$($info[1] -band 0xFFFF^)^,cfy^=$($info[1] -shr 16^)\"; ^
$r=$host.UI.RawUI; ^
$c=$r.WindowSize; ^
\"ccx^=$($c.Width^)^,ccy^=$($c.Height^)\"; ^
$l=$r.MaxPhysicalWindowSize; ^
\",clx^=$($l.Width^)^,cly^=$($l.Height^)\"; ^
^"
for /f %%i in ('%ConsoleInfo%') do set /a "%%i"
rem font size in pixels
set /a "FontSize.X=%cfx%, FontSize.Y=%cfy%"
rem max/largest Size of cmd window/console window
set /a "MaxConsoleSize.X=%clx%, MaxConsoleSize.Y=%cly%"
rem Current Size of cmd window/console window
set /a "ConsoleSize.X=%ccx%, ConsoleSize.Y=%ccy%"
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 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="
set /a "FontSize.X=%FontSize.X% , FontSize.Y=%FontSize.Y%"
set /a "ConsoleSize.X=%ConsoleSize.X% , ConsoleSize.Y=%ConsoleSize.Y%"
set /a "MaxConsoleSize.X=%MaxConsoleSize.X% , MaxConsoleSize.Y=%MaxConsoleSize.Y%"
set /A Screen.Width=%Screen.Width%, Screen.Height=%Screen.Height%
)
rem for macro definition/readability
(set \n=^^^
%= This creates an escaped Line Feed - DO NOT ALTER =%
)
set move_window_old=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=
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(\"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(^);';^
%=====% $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=
goto :eof
Re: Complete control of cmd windows
I doubt you'll get any better resuls. I'm pretty sure that ther's some kind of margin around a glyph (at least I've seen the MS console folks doing fun stuff to make box-drawings and frames connect in the display). So, the font size is not the same as the size of a character cell. It might be good enough to calculate the ratio for your circles. However, calculating the window size out of it is most likely just bogus.
Maybe consider something like
But this is most certainly still bogus because the margin won't be the same for all fonts and all font sizes.
Maybe consider something like
Code: Select all
rem center the windows
(
rem is strange formula but work well
set /A "center.x=(Screen.Width-img.x*(FontSize.X+3))/2-8"
rem to do : tuning.
set /A "center.y=(Screen.height-img.y*(FontSize.Y+5))/2-8-35"
%move_window% !center.x! !center.y!
)
-
- Expert
- Posts: 960
- Joined: 15 Jun 2012 13:16
- Location: Italy, Rome
Re: Complete control of cmd windows
your center do the job well in any font (thanks to GetSystemMetrics?)
i tryed to escaped but i failed
center escaped
can you help me?
i tryed to escaped but i failed
center escaped
Code: Select all
@echo off &setlocal EnableDelayedExpansion
mode con lines=20 cols=50
(set \n=^^^
%= This creates an escaped Line Feed - DO NOT ALTER =%
)
set center=for %%i in (1 2) do if %%i==2 (%\n%
%=% if defined arg set arg=^^!arg:/?=help^^!%\n%
%=% for /f %%j in ("^!arg^! middle") do (%\n%
%=====% powershell -NoProfile -ExecutionPolicy Bypass -Command ^"try {^
%=========% Add-Type -TypeDefinition '^
%=========% using System;^
%=========% using System.Runtime.InteropServices;^
%=========% public class C {^
%=============% [StructLayout(LayoutKind.Sequential^)]^
%=============% public struct POINT {^
%=================% public int x;^
%=================% public int y;^
%=============% }^
%=============% [StructLayout(LayoutKind.Sequential^)]^
%=============% public struct RECT {^
%=================% public int Left;^
%=================% public int Top;^
%=================% public int Right;^
%=================% public int Bottom;^
%=============% }^
%=============% [StructLayout(LayoutKind.Sequential^)]^
%=============% public struct WINDOWPLACEMENT {^
%=================% public uint length;^
%=================% public uint flags;^
%=================% public uint showCmd;^
%=================% public POINT ptMinPosition;^
%=================% public POINT ptMaxPosition;^
%=================% public RECT rcNormalPosition;^
%=============% }^
%=============% [DllImport(\^"user32.dll\^"^)]^
%=============% public static extern int GetSystemMetrics(int nIndex^);^
%=============% [DllImport(\^"kernel32.dll\^"^)]^
%=============% public static extern IntPtr GetConsoleWindow(^);^
%=============% [DllImport(\^"user32.dll\^"^)]^
%=============% public static extern int GetWindowPlacement(IntPtr hWnd^, ref WINDOWPLACEMENT lpwndpl^);^
%=============% [DllImport(\^"user32.dll\^"^)]^
%=============% public static extern int SetWindowPlacement(IntPtr hWnd^, ref WINDOWPLACEMENT lpwndpl^);^
%=============% public void center_middle(^) {^
%=================% int screen_width = GetSystemMetrics(16^)^, screen_height = GetSystemMetrics(17^);^
%=================% var wpl = new WINDOWPLACEMENT(^) {length = (uint^)Marshal.SizeOf(typeof(WINDOWPLACEMENT^)^)};^
%=================% GetWindowPlacement(GetConsoleWindow(^)^, ref wpl^);^
%=================% int top = screen_height / 2 - (wpl.rcNormalPosition.Bottom - wpl.rcNormalPosition.Top^) / 2^,^
%=====================% left = screen_width / 2 - (wpl.rcNormalPosition.Right - wpl.rcNormalPosition.Left^) / 2^,^
%=====================% bottom = screen_height / 2 + (wpl.rcNormalPosition.Bottom - wpl.rcNormalPosition.Top^) / 2^,^
%=====================% right = screen_width / 2 + (wpl.rcNormalPosition.Right - wpl.rcNormalPosition.Left^) / 2;^
%=================% wpl.flags = 0;^
%=================% wpl.showCmd = 1;^
%=================% wpl.rcNormalPosition.Left = left;^
%=================% wpl.rcNormalPosition.Top = top;^
%=================% wpl.rcNormalPosition.Right = right;^
%=================% wpl.rcNormalPosition.Bottom = bottom;^
%=================% SetWindowPlacement(GetConsoleWindow(^)^, ref wpl^);^
%=============% }^
%=============% public void center_left(^) {^
%=================% int screen_height = GetSystemMetrics(17^);^
%=================% var wpl = new WINDOWPLACEMENT(^) {length = (uint^)Marshal.SizeOf(typeof(WINDOWPLACEMENT^)^)};^
%=================% GetWindowPlacement(GetConsoleWindow(^)^, ref wpl^);^
%=================% int top = screen_height / 2 - (wpl.rcNormalPosition.Bottom - wpl.rcNormalPosition.Top^) / 2^,^
%=====================% right = wpl.rcNormalPosition.Right - wpl.rcNormalPosition.Left^,^
%=====================% bottom = screen_height / 2 + (wpl.rcNormalPosition.Bottom - wpl.rcNormalPosition.Top^) / 2;^
%=================% wpl.flags = 0;^
%=================% wpl.showCmd = 1;^
%=================% wpl.rcNormalPosition.Left = 0;^
%=================% wpl.rcNormalPosition.Top = top;^
%=================% wpl.rcNormalPosition.Right = right;^
%=================% wpl.rcNormalPosition.Bottom = bottom;^
%=================% SetWindowPlacement(GetConsoleWindow(^)^, ref wpl^);^
%=============% }^
%=============% public void center_top(^) {^
%=================% int screen_width = GetSystemMetrics(16^);^
%=================% var wpl = new WINDOWPLACEMENT(^) {length = (uint^)Marshal.SizeOf(typeof(WINDOWPLACEMENT^)^)};^
%=================% GetWindowPlacement(GetConsoleWindow(^)^, ref wpl^);^
%=================% int left = screen_width / 2 - (wpl.rcNormalPosition.Right - wpl.rcNormalPosition.Left^) / 2^,^
%=====================% right = screen_width / 2 + (wpl.rcNormalPosition.Right - wpl.rcNormalPosition.Left^) / 2^,^
%=====================% bottom = wpl.rcNormalPosition.Bottom - wpl.rcNormalPosition.Top;^
%=================% wpl.flags = 0;^
%=================% wpl.showCmd = 1;^
%=================% wpl.rcNormalPosition.Left = left;^
%=================% wpl.rcNormalPosition.Top = 0;^
%=================% wpl.rcNormalPosition.Right = right;^
%=================% wpl.rcNormalPosition.Bottom = bottom;^
%=================% SetWindowPlacement(GetConsoleWindow(^)^, ref wpl^);^
%=============% }^
%=============% public void center_right(^) {^
%=================% int screen_width = GetSystemMetrics(16^)^, screen_height = GetSystemMetrics(17^);^
%=================% var wpl = new WINDOWPLACEMENT(^) {length = (uint^)Marshal.SizeOf(typeof(WINDOWPLACEMENT^)^)};^
%=================% GetWindowPlacement(GetConsoleWindow(^)^, ref wpl^);^
%=================% int top = screen_height / 2 - (wpl.rcNormalPosition.Bottom - wpl.rcNormalPosition.Top^) / 2^,^
%=====================% left = screen_width - (wpl.rcNormalPosition.Right - wpl.rcNormalPosition.Left^)^,^
%=====================% bottom = screen_height / 2 + (wpl.rcNormalPosition.Bottom - wpl.rcNormalPosition.Top^) / 2;^
%=================% wpl.flags = 0;^
%=================% wpl.showCmd = 1;^
%=================% wpl.rcNormalPosition.Left = left;^
%=================% wpl.rcNormalPosition.Top = top;^
%=================% wpl.rcNormalPosition.Right = screen_width;^
%=================% wpl.rcNormalPosition.Bottom = bottom;^
%=================% SetWindowPlacement(GetConsoleWindow(^)^, ref wpl^);^
%=============% }^
%=============% public void center_bottom(^) {^
%=================% int screen_width = GetSystemMetrics(16^)^, screen_height = GetSystemMetrics(17^);^
%=================% var wpl = new WINDOWPLACEMENT(^) {length = (uint^)Marshal.SizeOf(typeof(WINDOWPLACEMENT^)^)};^
%=================% GetWindowPlacement(GetConsoleWindow(^)^, ref wpl^);^
%=================% int top = screen_height - (wpl.rcNormalPosition.Bottom - wpl.rcNormalPosition.Top^)^,^
%=====================% left = screen_width / 2 - (wpl.rcNormalPosition.Right - wpl.rcNormalPosition.Left^) / 2^,^
%=====================% right = screen_width / 2 + (wpl.rcNormalPosition.Right - wpl.rcNormalPosition.Left^) / 2;^
%=================% wpl.flags = 0;^
%=================% wpl.showCmd = 1;^
%=================% wpl.rcNormalPosition.Left = left;^
%=================% wpl.rcNormalPosition.Top = top;^
%=================% wpl.rcNormalPosition.Right = right;^
%=================% wpl.rcNormalPosition.Bottom = screen_height;^
%=================% SetWindowPlacement(GetConsoleWindow(^)^, ref wpl^);^
%=============% }^
%=========% }';^
%=========% (New-Object C^).center_%%~j(^);^
%=========% exit 0;^
%=====% }^
%=====% catch {^
%========% $hlp = \^" Usage:`r`n%%center%% [middle^^^|left^^^|top^^^|right^^^|bottom^^^|help]\^";^
%========% if ('%%~j' -eq 'help'^) {^
%=============% \^"Center The Current Console Window`r`n`r`n\^" + $hlp;^
%=============% exit 0;^
%=========% } else {^
%============% [Console]::Error.WriteLine(\^"Syntax Error`r`n`r`n\^" + $hlp^);^
%============% exit 1;^
%========% }^
%=====% }^"%\n%
%=% )%\n%
%=% endlocal%\n%
) else setlocal EnableDelayedExpansion ^&set arg=
pause
%center% help
pause
rem for /l %%i in () do (
%center%
%center% left
%center% right
%center% top
%center% bottom
rem )
pause
-
- Expert
- Posts: 960
- Joined: 15 Jun 2012 13:16
- Location: Italy, Rome
Re: Complete control of cmd windows
i escaped with ^ (caret) the "," (comma) and the ")" and one caret at ! enclosed in double quotes else two caret ^^
there are other rules?
there are other rules?
Re: Complete control of cmd windows
As to my understanding all you want to do is centering in the middle of the screen. You neither need arguments nor all the other types of centering, right?
Just shorten the thing to what you're actually looking for.
EDIT:
Further shortened by replacing the structures with a single array.
Just shorten the thing to what you're actually looking for.
Code: Select all
@echo off &setlocal EnableDelayedExpansion
mode con lines=20 cols=50
set center=powershell -NoProfile -ExecutionPolicy Bypass -Command ^"^
%=% Add-Type -TypeDefinition '^
%=% using System;^
%=% using System.Runtime.InteropServices;^
%=% public class C {^
%===% [StructLayout(LayoutKind.Sequential)]^
%===% public struct POINT {^
%=====% public int x;^
%=====% public int y;^
%===% }^
%===% [StructLayout(LayoutKind.Sequential)]^
%===% public struct RECT {^
%=====% public int Left;^
%=====% public int Top;^
%=====% public int Right;^
%=====% public int Bottom;^
%===% }^
%===% [StructLayout(LayoutKind.Sequential)]^
%===% public struct WINDOWPLACEMENT {^
%=====% public uint length;^
%=====% public uint flags;^
%=====% public uint showCmd;^
%=====% public POINT ptMinPosition;^
%=====% public POINT ptMaxPosition;^
%=====% public RECT rcNormalPosition;^
%===% }^
%===% [DllImport(\^"user32.dll\^")]^
%===% public static extern int GetSystemMetrics(int nIndex);^
%===% [DllImport(\^"kernel32.dll\^")]^
%===% public static extern IntPtr GetConsoleWindow();^
%===% [DllImport(\^"user32.dll\^")]^
%===% public static extern int GetWindowPlacement(IntPtr hWnd, ref WINDOWPLACEMENT lpwndpl);^
%===% [DllImport(\^"user32.dll\^")]^
%===% public static extern int SetWindowPlacement(IntPtr hWnd, ref WINDOWPLACEMENT lpwndpl);^
%===% public void center() {^
%=====% int screen_width = GetSystemMetrics(16), screen_height = GetSystemMetrics(17);^
%=====% var wpl = new WINDOWPLACEMENT() {length = (uint)Marshal.SizeOf(typeof(WINDOWPLACEMENT))};^
%=====% GetWindowPlacement(GetConsoleWindow(), ref wpl);^
%=====% int top = screen_height / 2 - (wpl.rcNormalPosition.Bottom - wpl.rcNormalPosition.Top) / 2,^
%=========% left = screen_width / 2 - (wpl.rcNormalPosition.Right - wpl.rcNormalPosition.Left) / 2,^
%=========% bottom = screen_height / 2 + (wpl.rcNormalPosition.Bottom - wpl.rcNormalPosition.Top) / 2,^
%=========% right = screen_width / 2 + (wpl.rcNormalPosition.Right - wpl.rcNormalPosition.Left) / 2;^
%=====% wpl.flags = 0;^
%=====% wpl.showCmd = 1;^
%=====% wpl.rcNormalPosition.Left = left;^
%=====% wpl.rcNormalPosition.Top = top;^
%=====% wpl.rcNormalPosition.Right = right;^
%=====% wpl.rcNormalPosition.Bottom = bottom;^
%=====% SetWindowPlacement(GetConsoleWindow(), ref wpl);^
%===% }^
%=% }';^
%=% (New-Object C).center();^"
%center%
pause
Further shortened by replacing the structures with a single array.
Code: Select all
@echo off &setlocal EnableDelayedExpansion
mode con lines=20 cols=50
set center=powershell -NoProfile -ExecutionPolicy Bypass -Command ^"^
%=% $w=Add-Type -Name WAPI -PassThru -MemberDefinition '^
%===% [DllImport(\"user32.dll\")] static extern int GetSystemMetrics(int nIndex);^
%===% [DllImport(\"kernel32.dll\")] static extern IntPtr GetConsoleWindow();^
%===% [DllImport(\"user32.dll\")] static extern int GetWindowPlacement(IntPtr hWnd, int[] lpwndpl);^
%===% [DllImport(\"user32.dll\")] static extern int SetWindowPlacement(IntPtr hWnd, int[] lpwndpl);^
%===% public static void center() {^
%=====% int screen_width=GetSystemMetrics(16), screen_height=GetSystemMetrics(17);^
%=====% var wpl=new int[11];^
%=====% wpl[0]=44;^
%=====% GetWindowPlacement(GetConsoleWindow(), wpl);^
%=====% int top=screen_height / 2 - (wpl[10] - wpl[8]) / 2,^
%=========% left=screen_width / 2 - (wpl[9] - wpl[7]) / 2,^
%=========% bottom=top + (wpl[10] - wpl[8]),^
%=========% right=left + (wpl[9] - wpl[7]);^
%=====% SetWindowPlacement(GetConsoleWindow(),^
%=======% new []{wpl[0], 0, 1, wpl[3], wpl[4], wpl[5], wpl[6], left, top, right, bottom});^
%===% }^
%=% ';^
%=% $w::center();^"
%center%
pause
-
- Expert
- Posts: 960
- Joined: 15 Jun 2012 13:16
- Location: Italy, Rome
Re: Complete control of cmd windows
A big thanks! I do some tests and report here if there are problems
I am trying to have as much control possible of the windows and the centering is one of the functions that are aesthetically better.
I am trying to have as much control possible of the windows and the centering is one of the functions that are aesthetically better.
-
- Expert
- Posts: 960
- Joined: 15 Jun 2012 13:16
- Location: Italy, Rome
Re: Complete control of cmd windows
This is the script to take various tests. The centering is a little too high. The formula you used I was unable to understand it.
Code: Select all
@echo off & setlocal enableDelayedExpansion & if NOT "%1"=="" goto :subs
rem save this script in UTF-8
rem multithread
rem test other mode (aspect ratio /font size)
rem Start "Sphere" "%0" Red
Start "Sphere" "%0" Green NearMax
pause
rem Start "Sphere" /MAX "%0" Blue Max
::Start "Sphere" "%0" Yellow
::Start "Sphere" "%0" Cyan
::Start "Sphere" "%0" Magenta
::Start "Sphere" "%0" White
::Start "Sphere" "%0" Orange
::Start "Sphere" "%0" Pink
::Start "Sphere" "%0" Salmon
::Start "Sphere" "%0" Navy
::Start "Sphere" "%0" Gray
:: TODO concurrent access of console with ansi escape sequences
goto :eof
:subs
rem title %1
call :init
rem setting console size in char 50x50 or max or near max
if NOT "%2"=="Max" (
if "%2"=="NearMax" (
rem leave the size of one char on x and 3 char on Y
set /A img.x=MaxConsoleSize.X-1, img.y=MaxConsoleSize.Y-3
) else set /A img.x=50, img.y=50
) else (
set /A img.x=ConsoleSize.X, img.y=ConsoleSize.Y
)
(
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
)
if NOT "%2"=="Max" (
rem is strange formula but work well
rem set /A "center.x=(Screen.Width-img.x*FontSize.X)/2-8"
rem not too good
rem set /A "center.y=(Screen.height-img.y*FontSize.Y)/2-8-35"
%center%
)
rem this code must execute after GetConsoleIndo/Move_window macro, if not this change font family to TERMINAL/RASTER, in window 10
chcp 65001 >nul
rem ALT+219
set "Char=█"
rem set "Char=*"
rem font size in pixels
set /A xc=FontSize.X, yc=FontSize.Y
set /A width=img.x*xc, height=img.y*yc
rem calculate bigger from width and height, use for radius
if !width! leq !height! ( set /a res=width ) else ( set /a res=height )
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
set /A "R=res/2, X0=width/2, Y0=height/2"
rem setting step for better smoothing colors
set /A "mS=-(R*R), step=255*100000/-mS, stepL=128*100000/-mS"
For /L %%y in (1,1,!img.y!) do (
For /L %%x in (1,1,!img.x!) do (
rem calculate circle equation and color for smooting.
rem This code generate multiple circlesof different color and simulate a 3D sphere.
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 (
if "%1"=="Red" %plot% %%x %%y !C! 0 0
if "%1"=="Green" %plot% %%x %%y 0 !C! 0
if "%1"=="Blue" %plot% %%x %%y 0 0 !C!
if "%1"=="Yellow" %plot% %%x %%y !C! !C! 0
if "%1"=="Cyan" %plot% %%x %%y 0 !C! !C!
if "%1"=="Magenta" %plot% %%x %%y !C! 0 !C!
if "%1"=="White" %plot% %%x %%y !C! !C! !C!
if "%1"=="Orange" %plot% %%x %%y !C! !CL! 0
if "%1"=="Pink" %plot% %%x %%y !C! 0 !CL!
if "%1"=="Salmon" %plot% %%x %%y !C! !CL! !CL!
if "%1"=="Navy" %plot% %%x %%y 0 0 !CL!
if "%1"=="Gray" %plot% %%x %%y !CL! !CL! !CL!
)
)
)
%flush%
pause>nul
goto :eof
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:init
rem for ansi sequence
for /F %%a in ('echo prompt $E^| %ComSpec%') do set "ESC=%%a"
:: Hide the cursor
<nul set /p "=!ESC![?25l"
rem many thanks aGerman and Aacini
set ConsoleInfo=^
powershell ^
^"$w=Add-Type -Name WAPI -PassThru -MemberDefinition ' ^
[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^); ^
'; ^
[int[]]$info=0,0; ^
$h=$w::CreateFile('CONOUT$',0xC0000000,2,[IntPtr]::Zero,3,0,[IntPtr]::Zero^); ^
$w::GetCurrentConsoleFont($h,0,$info^); ^
$w::CloseHandle($h^); ^
\"cfx^=$($info[1] -band 0xFFFF^)^,cfy^=$($info[1] -shr 16^)\"; ^
$r=$host.UI.RawUI; ^
$c=$r.WindowSize; ^
\"ccx^=$($c.Width^)^,ccy^=$($c.Height^)\"; ^
$l=$r.MaxPhysicalWindowSize; ^
\",clx^=$($l.Width^)^,cly^=$($l.Height^)\"; ^
^"
for /f %%i in ('%ConsoleInfo%') do set /a "%%i"
rem font size in pixels
set /a "FontSize.X=%cfx%, FontSize.Y=%cfy%"
rem max/largest Size of cmd window/console window
set /a "MaxConsoleSize.X=%clx%, MaxConsoleSize.Y=%cly%"
rem Current Size of cmd window/console window
set /a "ConsoleSize.X=%ccx%, ConsoleSize.Y=%ccy%"
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 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="
set /a "FontSize.X=%FontSize.X% , FontSize.Y=%FontSize.Y%"
set /a "ConsoleSize.X=%ConsoleSize.X% , ConsoleSize.Y=%ConsoleSize.Y%"
set /a "MaxConsoleSize.X=%MaxConsoleSize.X% , MaxConsoleSize.Y=%MaxConsoleSize.Y%"
set /A Screen.Width=%Screen.Width%, Screen.Height=%Screen.Height%
)
set center=powershell -NoProfile -ExecutionPolicy Bypass -Command ^"^
%=% $w=Add-Type -Name WAPI -PassThru -MemberDefinition '^
%===% [DllImport(\"user32.dll\")] static extern int GetSystemMetrics(int nIndex);^
%===% [DllImport(\"kernel32.dll\")] static extern IntPtr GetConsoleWindow();^
%===% [DllImport(\"user32.dll\")] static extern int GetWindowPlacement(IntPtr hWnd, int[] lpwndpl);^
%===% [DllImport(\"user32.dll\")] static extern int SetWindowPlacement(IntPtr hWnd, int[] lpwndpl);^
%===% public static void center() {^
%=====% int screen_width=GetSystemMetrics(16), screen_height=GetSystemMetrics(17);^
%=====% var wpl=new int[11];^
%=====% wpl[0]=44;^
%=====% GetWindowPlacement(GetConsoleWindow(), wpl);^
%=====% int top=screen_height / 2 - (wpl[10] - wpl[8]) / 2,^
%=========% left=screen_width / 2 - (wpl[9] - wpl[7]) / 2,^
%=========% bottom=top + (wpl[10] - wpl[8]),^
%=========% right=left + (wpl[9] - wpl[7]);^
%=====% SetWindowPlacement(GetConsoleWindow(),^
%=======% new []{wpl[0], 0, 1, wpl[3], wpl[4], wpl[5], wpl[6], left, top, right, bottom});^
%===% }^
%=% ';^
%=% $w::center();^"
rem for macro definition/readability
(set \n=^^^
%= This creates an escaped Line Feed - DO NOT ALTER =%
)
rem bugged
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=
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: 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:~1500,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
-
- Expert
- Posts: 960
- Joined: 15 Jun 2012 13:16
- Location: Italy, Rome
Re: Complete control of cmd windows
ok, i understand it. but it's too high the center. It's possible print/show the value top ,bottom, left,right, before calculation, for debug?
-
- Expert
- Posts: 960
- Joined: 15 Jun 2012 13:16
- Location: Italy, Rome
Re: Complete control of cmd windows
the is about 1016 at (1980x1080) at 100% zoom
Code: Select all
screen_height=GetSystemMetrics(17)
Re: Complete control of cmd windows
There’s more than one way to skin a cat Let's just try another approach then.
Code: Select all
@echo off &setlocal EnableDelayedExpansion
mode con lines=20 cols=50
set center=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,^
%=======% moninf[5]+(moninf[7]-moninf[5])/2-(rect[2]-rect[0])/2,^
%=======% moninf[6]+(moninf[8]-moninf[6])/2-(rect[3]-rect[1])/2,^
%=======% rect[2]-rect[0],^
%=======% rect[3]-rect[1],^
%=======% 0);^
%===% }';^
%=% $w::center();^"
%center%
pause
-
- Expert
- Posts: 960
- Joined: 15 Jun 2012 13:16
- Location: Italy, Rome
Re: Complete control of cmd windows
very good job!aGerman wrote: ↑08 Oct 2022 14:18There’s more than one way to skin a cat Let's just try another approach then.Code: Select all
@echo off &setlocal EnableDelayedExpansion mode con lines=20 cols=50 set center=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,^ %=======% moninf[5]+(moninf[7]-moninf[5])/2-(rect[2]-rect[0])/2,^ %=======% moninf[6]+(moninf[8]-moninf[6])/2-(rect[3]-rect[1])/2,^ %=======% rect[2]-rect[0],^ %=======% rect[3]-rect[1],^ %=======% 0);^ %===% }';^ %=% $w::center();^" %center% pause