【问题标题】:Find Font size of an active console Window查找活动控制台窗口的字体大小
【发布时间】:2023-03-05 18:39:01
【问题描述】:

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

目前关于如何查找当前字体大小的尝试和研究:

  • 检查 wmic 是否有可用值:

    wmic path Win32_VideoController get * /format:value

  • this similar question 的公认解决方案:

    for /f "tokens=3" %A in ('reg query "HKEY_CURRENT_USER\Control Panel\Desktop\WindowMetrics" /v AppliedDPI') do echo %A

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

  • 搜索Dostips

  • 使用外部可执行文件强制字体大小(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:\\.\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

【问题讨论】:

  • 程序就是这样做的 docs.microsoft.com/en-us/windows/console/getconsolefontsize 你可以从 powershell、VB.NET 或 C# 中调用它。
  • 不幸的是,我在这方面没有取得任何进展。我对这些语言非常不熟悉,到目前为止,我从thisthis 源代码中利用powershell 的尝试还没有走得太远。
  • 知道窗口大小会有帮助吗?例如C:\WINDOWS\system32&gt;"C:\Users\User\Desktop\Bat+Vbs\GetWindowRect\GetWindowRect.exe" 返回0 0 1087 643
  • 如果你有兴趣,我修改了这个程序winsourcecode.blogspot.com/2020/01/… 以使用当前控制台窗口(因为你输入的内容成为控制台标题的一部分,所以你会转圈)如果有用的话?
  • 如果您查看我linked to 的演示,您会发现我已经能够控制窗口大小、位置和窗口内文本的对齐方式。它只是确定我需要确定的字体大小,因为字体大小的任何变化都会改变给定屏幕分辨率的最大列和行——它们之间的关系是对齐计算的基础。我仍在尝试使用您最初链接的内容,希望能找到一个 powershell 解决方案,但是,由于我对 powershell 不熟悉,可能需要一段时间。

标签: batch-file cmd


【解决方案1】:

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

;   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

您可以查看this site 使用的 WIN32 API 函数的文档。

要获取可执行程序,请将此代码复制到fontsize.asm 源程序中,并通过MASM32 SDK package 组装它。您也可以执行以下 .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:\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

【讨论】:

  • 可爱的工作@Aacini,鉴于我以前从未编译过一个 exe,我按照你的指示在 5 分钟内完成了这个工作。
  • 很好!是否安装了 MASM32 SDK 并组装了 .asm 源程序?
  • 当然可以。安装 MASM 后,我在 5 分钟内完成了 getfont exe 的排序。有相关问题需要解决,因为字体本身对给定控制台的最大行数/列数有影响,我正在研究字符宽度 x 高度的比率与它与屏幕分辨率的关系之间的关系。不同的比率需要对我的公式进行不同的调整,试图将其缩小到尽可能少的步骤
【解决方案2】:

有了compiled .exe Aacini 对craft 非常友好,我已经能够充实控制台大小和位置计算的剩余问题。

剩下的难题在于显示器的缩放系数,直到 this discussion 出现之前我才考虑到这一点

捕获缩放屏幕大小/位置所需的变量值

::: { 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
::: }

计算窗口位置的子程序,创建和启动伴随文件以重新打开具有所需属性的脚本

: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
::: }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-11-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-28
    • 2010-12-20
    • 2014-01-05
    相关资源
    最近更新 更多