Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save mortalis13/273c100a7e816252314eaff7a17fcd7a to your computer and use it in GitHub Desktop.
Save mortalis13/273c100a7e816252314eaff7a17fcd7a to your computer and use it in GitHub Desktop.

Script for changing the font of the title bar in Windows, without modifying registry directly and restarting the session.
Execute it with AutoHotkey v2 (put the code in the file font.ahk and run):

SetFont() {
    static SPI_GETNONCLIENTMETRICS := 0x0029
    static SPI_SETNONCLIENTMETRICS := 0x002A
    static SPIF_UPDATEINIFILE := 0x01
    static SPIF_SENDCHANGE := 0x02

    static StructureSize := 40 + 5 * 92  ; NONCLIENTMETRICS size: fields + 5 LOGFONT instances
    static lfCaptionFont_Offset := 24

    static lfFaceName_Offset := 28  ; start of the font name field in LOGFONT structure
    static LF_FACESIZE := 32  ; size of the font name
    static lfHeight_Offset := 0
    static lfWeight_Offset := 16

    MetricsStructure := Buffer(StructureSize, 0)
    NumPut("UInt", StructureSize, MetricsStructure, 0)  ; cbSize

    ; Get current metrics
    DllCall("SystemParametersInfo", "UInt", SPI_GETNONCLIENTMETRICS, "UInt", StructureSize, "Ptr", MetricsStructure, "UInt", 0)

    Name := StrGet(MetricsStructure.Ptr + lfCaptionFont_Offset + lfFaceName_Offset, LF_FACESIZE)
    Height := NumGet(MetricsStructure.Ptr + lfCaptionFont_Offset + lfHeight_Offset, "Int")
    Size := DllCall("MulDiv", "Int", -Height, "Int", 72, "Int", A_ScreenDPI)
    Weight := NumGet(MetricsStructure.Ptr + lfCaptionFont_Offset + lfWeight_Offset, "Int")

    ; Change only required properties
    Size := 11
    Height := -DllCall("MulDiv", "Int", Size, "Int", A_ScreenDPI, "Int", 72)
    NumPut("Int", Height, MetricsStructure, lfCaptionFont_Offset + lfHeight_Offset)

    Weight := 800
    NumPut("Int", Weight, MetricsStructure, lfCaptionFont_Offset + lfWeight_Offset)

    DllCall("SystemParametersInfo", "UInt", SPI_SETNONCLIENTMETRICS, "UInt", StructureSize, "Ptr", MetricsStructure, "UInt", SPIF_UPDATEINIFILE | SPIF_SENDCHANGE)
}
SetFont

This uses calls to SystemParametersInfo function to first get the existing font metrics and then to update only the necessary properties (font size 11 and weight bold).

To see the font name and its properties, this line can be used after getting metrics structure:

MsgBox Format("Name: {1}, Height: {2}, Size: {3}, Weight: {4}", Name, Height, Size, Weight)

The structure size and offsets are based on the Win32 API reference definitions:
NONCLIENTMETRICS: https://learn.microsoft.com/en-us/windows/win32/api/winuser/ns-winuser-nonclientmetricsa
LOGFONT: https://learn.microsoft.com/en-us/windows/win32/api/wingdi/ns-wingdi-logfonta


Definitions:

BOOL SystemParametersInfo(UINT uiAction, UINT uiParam, PVOID pvParam, UINT fWinIni);
typedef struct tagNONCLIENTMETRICS {
  UINT     cbSize;
  int      iBorderWidth;
  int      iScrollWidth;
  int      iScrollHeight;
  int      iCaptionWidth;
  int      iCaptionHeight;
  LOGFONTA lfCaptionFont;
  int      iSmCaptionWidth;
  int      iSmCaptionHeight;
  LOGFONTA lfSmCaptionFont;
  int      iMenuWidth;
  int      iMenuHeight;
  LOGFONTA lfMenuFont;
  LOGFONTA lfStatusFont;
  LOGFONTA lfMessageFont;
  int      iPaddedBorderWidth;
} NONCLIENTMETRICS;
typedef struct tagLOGFONT {
  LONG lfHeight;
  LONG lfWidth;
  LONG lfEscapement;
  LONG lfOrientation;
  LONG lfWeight;
  BYTE lfItalic;
  BYTE lfUnderline;
  BYTE lfStrikeOut;
  BYTE lfCharSet;
  BYTE lfOutPrecision;
  BYTE lfClipPrecision;
  BYTE lfQuality;
  BYTE lfPitchAndFamily;
  CHAR lfFaceName[LF_FACESIZE];
} LOGFONT;

Based on the following:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment