查找活动控制台窗口的字体大小



第一个脚本目标 我无法找到自己的解决方案。

到目前为止,关于如何找到当前字体大小的尝试和研究:

  • 检查 WMIC 的可用值:

    wmic path Win32_VideoController get * /format:value

  • 这个类似问题的公认解决方案:

    for /f "tokens=3" %A in ('reg query "HKEY_CURRENT_USERControl PanelDesktopWindowMetrics" /v AppliedDPI') do echo %A

    • 无论我的计算机上的字体大小如何,此解决方案都会返回相同的结果 - 0x12
  • 在stackoverflow上搜索问答

  • 搜索多斯提示

  • 使用外部可执行文件强制调整字体大小 (BG.exe(

    • 并非所有我使用它的脚本都会保证用户需要下载支持的可执行文件

脚本执行适用于支持 ASCII 转义码的 Windows 10 系统

需要当前字体大小的上下文:

我开发了一个用于控制控制台大小和位置的例程,该例程在不同分辨率下保持准确,但是它目前取决于基于假定字体大小 16x8 的最大行和列的值

有了确定字体大小的可靠方法,我可以取消这种假设,并使用实际字体大小、最大行/列和屏幕分辨率之间的关系来制定定位。 我仍然需要确定上述关系 - 如果有人已经知道,请随时分享。

::: { 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:\.rootcimv2"^)
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
::: }

上述例程的演示

我编写了这个小型 MASM32 汇编语言程序来获取当前 cmd .exe窗口的字体大小:

;   FontSize.asm: Returns the current font size of cmd.exe window - Antonio Perez Ayala
include         masm32includemasm32rt.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

您可以查看本网站上使用的 WIN32 API 函数的文档。

若要获取可执行程序,请将此代码复制到源程序中fontsize.asm并通过 MASM32 SDK 包对其进行组装。您还可以执行以下.bat批处理文件并将其从创建的fontsize.zip文件中提取:

@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程序通过 %ERRORLEVEL% 值返回字体大小。例如:

C:UsersAntonioDocumentsASMBMASM32 Assembler for Windows
> fontsize.exe
C:UsersAntonioDocumentsASMBMASM32 Assembler for Windows
> set /A "height=%errorlevel% >> 16, width=%errorlevel% & 0xFF"
8
C:UsersAntonioDocumentsASMBMASM32 Assembler for Windows
> echo The font size is %width% x %height%
The font size is 8 x 16

通过编译.exe Aacini 很友好地制作,我已经能够充实控制台尺寸和位置计算的剩余问题。

剩下的一块难题是显示器的比例因子,直到在这次讨论中出现之前,我才考虑过这一点。

捕获缩放屏幕尺寸/位置所需的变量值

::: { 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 "HKCUControl PanelDesktopWindowMetrics" /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
::: }

子例程,用于计算窗口位置,创建和启动配套文件以重新打开具有所需属性的脚本

: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:\.rootcimv2"^)
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
::: }

最新更新