SystemParametersInfoForDpi will corrupt the window title font on rescaling

Miroslav Pavlíček 30 Reputation points
2023-05-23T08:43:19.9733333+00:00

There is a simple console application, created from default Visual Studio template. At startup, the following code is added:

NONCLIENTMETRICSW ncInfo{};
ncInfo.cbSize = sizeof(ncInfo);
SystemParametersInfoForDpi(SPI_GETNONCLIENTMETRICS, sizeof(ncInfo), &ncInfo, 0, 72);

When this function is called, everything works correctly until the scale (%) in Windows display setting is changed. After that, the font of window title of all windows in the system becomes very tiny until restart or sign out/in. Without this function call, this issue does not exist and changes of display scale percentage do not damage the windows title font.

Here I send a gif video of the process of setting up the situation:

  • Create empty project.
  • Run it and after that try to change display scale - everything OK.
  • Add given 3 lines of code into project and run it.
  • After display scale change, windows title font is not correct now.
Windows API - Win32
Windows API - Win32
A core set of Windows application programming interfaces (APIs) for desktop and server applications. Previously known as Win32 API.
2,432 questions
{count} votes

2 answers

Sort by: Most helpful
  1. Miroslav Pavlíček 30 Reputation points
    2023-06-06T10:24:58.66+00:00

    @David Lowndes , @Xiaopo Yang - MSFT

    There is no difference in behavior in Windows 11 22H2 22621.1778, nor in the latest Windows 10 update. Tested with Visual Studio 2022 17.6.2 with the latest Windows SDK. As David mentioned, it is visible in system Win32 windows, not in windows with custom title bars created by higher-level frameworks.

    It is definitely a bug. It is unacceptable that calling the api function to read system information would leave such side effects on the system.

    May you pass this problem on to the appropriate MSFT team whose interest is to make the system work properly?


  2. Miroslav Pavlíček 30 Reputation points
    2023-10-05T12:19:51.42+00:00

    The SPI_GETNONCLIENTMETRICS action seems to SET the font size of the caption to the value it returns in the result structure, and then no further calls will change this value:

    NONCLIENTMETRICSW ncInfo{};
    ncInfo.cbSize = sizeof(ncInfo);
    
    UINT dpi_1 = 96;
    UINT dpi_2 = 200;
    
    // 1. call:
    SystemParametersInfoForDpi(SPI_GETNONCLIENTMETRICS, sizeof(ncInfo), &ncInfo, 0, dpi_1);
    // Return value of ncInfo.lfCaptionFont.lfHeight is -12 now.
    
    // 2. call:
    SystemParametersInfoForDpi(SPI_GETNONCLIENTMETRICS, sizeof(ncInfo), &ncInfo, 0, dpi_2);
    // Return value of ncInfo.lfCaptionFont.lfHeight is -25 now and after Windows screen
    // scale change, the font of all window titles is the wrong size.
    
    // 3. call (same as 1.)
    SystemParametersInfoForDpi(SPI_GETNONCLIENTMETRICS, sizeof(ncInfo), &ncInfo, 0, dpi_1);
    // Return value of ncInfo.lfCaptionFont.lfHeight is still -25 now, not -12 as in the
    // first call.
    

    If you want to repeat the test, you will need to sign out/in for the system to return to the correct state.

    0 comments No comments