T3RR0R
T3RR0R

Reputation: 2961

Find Font size of an active console Window

first scripting goal I haven't been able to uncover my own solution for.

Attempts and research on how to find current font size so far:

Script execution is intended for Windows 10 systems supporting ASCII escape codes

The context for needing current font size:

I've developed a routine for controlling console size and position, which remains accurate accross different resolutions, however it currently depends on values for maximum lines and columns based on an assumed font size of 16x8

With a reliable means to determine font size, I can do away with this assumption and formulate positioning using the relationship between the actual font size, maximum lines / columns and screen resolution. I still need to determine the above relationship - if anyone already knows it, feel free to share.

::: { Subroutine to process output of wmic command into usable variables for screen dimensions (resolution)
::: - Formula based on Consolas 16x8 Font
:ChangeConsole <Lines> <Columns> <Label to Resume From> <If a 4th parameter is Defined, Aligns screen at top left>
::: - Get screen Dimensions
    For /f "delims=" %%# in  ('"wmic path Win32_VideoController  get CurrentHorizontalResolution,CurrentVerticalResolution /format:value"') do (
        Set "%%#">nul
    )
::: - Calculation of X axis relative to screen resolution and console size. Resolution scales to Max Columns ~ 165
    Set /A XresScale=CurrentHorizontalResolution / 165
    Set /A HorzCentre=CurrentHorizontalResolution / 2
    Set /A CentreX= ( HorzCentre - ( ( %~2 * XresScale ) / 2 ) ) - 8
::: - Calculation of Y axis relative to screen resolution and console size. Resolution scales to Max Lines ~ 43
    Set /A YresScale=CurrentVerticalResolution / 43
    Set /A VertCentre=CurrentVerticalResolution / 2
    Set /A CentreY=VertCentre - ( ( %~1 * YresScale ) / 2 )
::: - Optional 4th parameter can be used to align console at top left of screen instead of screen centre
    If Not "%~4"=="" (Set /A CentreY=0,CentreX=-8)
::: - Creates a batch file to reopen the main script using Call with parameters to define properties for console change and the label to resume from.
    (
    Echo.@Mode Con: lines=%~1 cols=%~2
    Echo.@Title %ProgName%
    Echo.@Call "%AlignFile%" "%~1" "%~2" "%~3" "%AlignFile%" 
    )>"%temp%\ChangeConsole.bat"
::: - .Vbs script creation
    (
    Echo.Set objWMIService = GetObject^("winmgmts:\\.\root\cimv2"^)
    Echo.Set objConfig = objWMIService.Get^("Win32_ProcessStartup"^)
    Echo.objConfig.SpawnInstance_
    Echo.objConfig.X = %CentreX%
    Echo.objConfig.Y = %CentreY%
    Echo.Set objNewProcess = objWMIService.Get^("Win32_Process"^)
    Echo.intReturn = objNewProcess.Create^("%temp%\ChangeConsole.bat", Null, objConfig, intProcessID^)
    )>"%temp%\Consolepos.vbs"
::: - .Vbs Starts the companion batch script to Change Console properties, ends the parent.
    Start "" "%temp%\Consolepos.vbs" & Exit
::: }

A demo of the above routine

Upvotes: 1

Views: 683

Answers (2)

T3RR0R
T3RR0R

Reputation: 2961

With the compiled .exe Aacini was kind enough to craft, I've been able to flesh out the remaining issues with console size and position calculations.

The remaining piece of the puzzle was in the scaling factor of the display, something I failed to consider until it came up in this discussion

Capture variable values required for scaling screen size / position

::: { Variable used in calling this script from the Self created resizing Batch.    
    Set "ThisFile=%~F0"
::: }
::: { Get screen Dimensions
    For /f "delims=" %%# in  ('"wmic path Win32_VideoController get CurrentHorizontalResolution,CurrentVerticalResolution /format:value"') do (
        Set "%%#">nul
    )
::: - Calculate scale Factor in effect. Registry value requires restart to update if scale has changed.
    For /F "Tokens=3 Delims= " %%A in ('REG QUERY "HKCU\Control Panel\Desktop\WindowMetrics" /V AppliedDPI') Do Set /A SF=%%A / 100 + 1
::: - Get Font Size
    (For /F "Delims=" %%S in ('dir GetFontSize.exe /B /S') Do (%%S)) 2> Nul
    Set /A "Font.H=%errorlevel% >> 16, Font.W=%errorlevel% & 0xFF"
    Set /A Max.Width= ( CurrentHorizontalResolution / ( Font.W * SF ) )
    rem // account for title and start bar
    Set /A Max.Height= ( ( CurrentVerticalResolution / Font.H ) / SF ) - 4
::: }
::: { Call Subroutine to Resize and Position the Console
    Call :ChangeConsole %Max.Height% %Max.Width% Matrix TL
::: }

Subroutine to calculate window position, create and launch companion files to reopen script with desired properties

:ChangeConsole <Lines> <Columns> <Label to Resume From> <If a 4th parameter is Defined, Aligns screen at top left>
::: - Calculation of X axis relative to screen resolution and console size. Resolution scales to Max Columns.
    Set /A XresScale= CurrentHorizontalResolution / Max.Width
    Set /A HorzCentre= CurrentHorizontalResolution / 2
    Set /A CentreX= ( HorzCentre - ( ( %~2 * XresScale ) / 2 ) )
::: - Calculation of Y axis relative to screen resolution and console size. Resolution scales to Max Lines.
    Set /A YresScale= CurrentVerticalResolution / Max.Height
    Set /A VertCentre= CurrentVerticalResolution / 2
    Set /A CentreY= VertCentre - ( ( %~1 * YresScale ) / 2 )
::: - Optional 4th parameter can be used to align console at top left of screen instead of screen centre
    If Not "%~4"=="" (Set /A CentreY=0,CentreX=-8)
::: - Creates a batch file to reopen the main script using Call with parameters to define properties for console change and the label to resume from.
    (
    Echo.@Mode Con: lines=%~1 cols=%~2
    Echo.@Title %ProgName%
    Echo.@Call "%ThisFile%" "%~1" "%~2" "%~3" "%ThisFile%" 
    )>"%temp%\ChangeConsole.bat"
::: - .Vbs script creation
    (
    Echo.Set objWMIService = GetObject^("winmgmts:\\.\root\cimv2"^)
    Echo.Set objConfig = objWMIService.Get^("Win32_ProcessStartup"^)
    Echo.objConfig.SpawnInstance_
    Echo.objConfig.X = %CentreX%
    Echo.objConfig.Y = %CentreY%
    Echo.Set objNewProcess = objWMIService.Get^("Win32_Process"^)
    Echo.intReturn = objNewProcess.Create^("%temp%\ChangeConsole.bat", Null, objConfig, intProcessID^)
    )>"%temp%\Consolepos.vbs"
::: - .Vbs Starts the companion batch script to Change Console properties, ends the parent.
    Start "" "%temp%\Consolepos.vbs" & Exit
::: }

Upvotes: 0

Aacini
Aacini

Reputation: 67296

I wrote this small MASM32 assembly language program to get the size of the font of the current cmd.exe window:

;   FontSize.asm: Returns the current font size of cmd.exe window - Antonio Perez Ayala

        include         \masm32\include\masm32rt.inc

    .data

CONSOLE_FONT_INFO STRUCT
  nFont                 DWORD ?
  dwFontSize            COORD <>
CONSOLE_FONT_INFO ENDS

    hConsoleOutput      DD          ?
    ConsoleCurrentFont  CONSOLE_FONT_INFO   <>

    .code

Main    PROC

        invoke  GetStdHandle, STD_OUTPUT_HANDLE                                 ;EAX = console output handle
        mov     hConsoleOutput, eax                                             ;store it
        invoke  GetCurrentConsoleFont, eax, FALSE, ADDR ConsoleCurrentFont      ;get current font info
        invoke  GetConsoleFontSize, hConsoleOutput, ConsoleCurrentFont.nFont    ;EAX = font size 
        invoke  ExitProcess, eax                                                ;return it in ERRORLEVEL

Main    ENDP

        end     Main

You may review the documentation of the WIN32 API functions used at this site.

To get the executable program copy this code into fontsize.asm source program and assembly it via MASM32 SDK package. You may also execute the following .bat Batch file and extract it from the created fontsize.zip file:

@certutil -decode "%~F0" fontsize.zip & goto :EOF

-----BEGIN CERTIFICATE-----
UEsDBBQAAAAIAMtAvVDPMRDXlAEAAAAKAAAMAAAAZm9udHNpemUuZXhl7ZI9LwRB
GMf/644cDidRUGC8JarNhaiQXOK1IDZOJYh1O3F79mZlbyTiMyjkGgWdTqVQiIoP
cIVvoJFcq1DKmtkXTgiFKMj+ss/zn+f/PDO7k+zi6hFiAOIiXBe4gk8G33MhorX3
uhWXjZW+K2Wh0reSN0tk17G3Hb1IcjpjNidblDh7jJiMTC9lSdE2qNrS0jQYnLG+
VrztmoyVwzjuT5V7hD50t5c7hS6bubz0w3dqM8CCEkMlcbcRevdoU5qV+iTq4F9E
kgqCyCLjr+ve2qF6Fw2KWLgxVauv4tFBgGH8AkSc/UVb5XSfC52XRQp4d9cAAmyq
jqFzHTgPDG+u4f1cRjyqP4akNNLBXOLD3A0i/jWFp+q4kDOkM8jHRSpAqw4Ixx2T
lTsmG1X5l2hVOe8OJYmwh+DluJcTIkf8TTYIwEUcitCI702Qt/6pXNfUtXy29wQz
+ybXHDtHSyU8Yo7yKZuVbIvO2oxnzQMKPHvunuNQVttEQRF+lhvzOjMsMbdDHUat
0RHVsKzPvyAiIuInvABQSwECFAAUAAAACADLQL1QzzEQ15QBAAAACgAADAAAAAAA
AAAAACAAAAAAAAAAZm9udHNpemUuZXhlUEsFBgAAAAABAAEAOgAAAL4BAAAAAA==
-----END CERTIFICATE-----

fontsize.exe program returns the font size via %ERRORLEVEL% value. For example:

C:\Users\Antonio\Documents\ASMB\MASM32 Assembler for Windows
> fontsize.exe

C:\Users\Antonio\Documents\ASMB\MASM32 Assembler for Windows
> set /A "height=%errorlevel% >> 16, width=%errorlevel% & 0xFF"
8

C:\Users\Antonio\Documents\ASMB\MASM32 Assembler for Windows
> echo The font size is %width% x %height%
The font size is 8 x 16

Upvotes: 1

Related Questions