Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can't detect when Windows Font Size has changed C++ MFC

I'm trying to determine how I can detect when the user changes the Windows Font Size from Normal to Extra Large Fonts, the font size is selected by executing the following steps on a Windows XP machine:

  1. Right-click on the desktop and select Properties.
  2. Click on the Appearance Tab.
  3. Select the Font Size: Normal/Large Fonts/Extra Large Fonts

My understanding is that the font size change results in a DPI change, so here is what I've tried so far.


My Goal:

I want to detect when the Windows Font Size has changed from Normal to Large or Extra Large Fonts and take some actions based on that font size change. I assume that when the Windows Font Size changes, the DPI will also change (especially when the size is Extra Large Fonts


What I've tried so far:

I receive several messages including: WM_SETTINGCHANGE, WM_NCCALCSIZE, WM_NCPAINT, etc... but none of these messages are unique to the situation when the font size changes, in other words, when I receive the WM_SETTINGSCHANGE message I want to know what changed.

In theory when I define the OnSettingChange and Windows calls it, the lpszSection should tell me what the changing section is, and that works fine, but then I check the given section by calling SystemParametersInfo and I pass in the action SPI_GETNONCLIENTMETRICS, and I step through the debugger and I make sure that I watch the data in the returned NONCLIENTMETRICS for any font changes, but none occur.

Even if that didn't work, I should still be able to check the DPI when the Settings change. I really wouldn't care about the other details, every time I get the WM_SETTINGCHANGE message, I would just check the DPI and perform the actions I'm interested in performing, but I'm not able to get the system DPI either.

I have tried to get the DPI by invoking the method GetSystemMetrics, also for each DC:

Dekstop DC->GetDeviceCaps LOGPIXELSX/LOGPIXELSY Window DC->GetDeviceCaps LOGPIXELSX/LOGPIXELSY Current DC->GetDeviceCaps LOGPIXELSX/LOGPIXELSY

Even if I change the DPI in the Graphic Properties Window these values don't return anything different, they always show 96.

Could anybody help me figure this out please? What should I be looking for? Where should I be looking at?

afx_msg void CMainFrame::OnSettingChange(UINT uFlags, LPCTSTR lpszSection)
{
    int windowDPI = 0;
    int deviceDPI = 0;
    int systemDPI = 0;
    int desktopDPI = 0;
    int dpi_00_X = 0;
    int dpi_01_X = 0;
    int dpi_02_X = 0;
    int dpi_03_X = 0;

    CDC* windowDC = CWnd::GetWindowDC(); // try with window DC
    HDC desktop = ::GetDC(NULL); // try with desktop DC
    CDC* device = CWnd::GetDC(); // try with current DC
    HDC hDC = *device; // try with HDC
    if( windowDC )
    {
        windowDPI = windowDC->GetDeviceCaps(LOGPIXELSY); 
        // always 96 regardless if I change the Font 
        // Size to Extra Large Fonts or keep it at Normal

        dpi_00_X = windowDC->GetDeviceCaps(LOGPIXELSX); // 96
    }

    if( desktop )
    {
        desktopDPI = ::GetDeviceCaps(desktop, LOGPIXELSY); // 96
        dpi_01_X = ::GetDeviceCaps(desktop, LOGPIXELSX); // 96
    }

    if( device )
    {
        deviceDPI = device->GetDeviceCaps(LOGPIXELSY); // 96
        dpi_02_X = device->GetDeviceCaps(LOGPIXELSX); // 96
    }

    systemDPI = ::GetDeviceCaps(hDC, LOGPIXELSY); // 96
    dpi_03_X = ::GetDeviceCaps(hDC, LOGPIXELSX); // 96

    CWnd::ReleaseDC(device);
    CWnd::ReleaseDC(windowDC);
    ::ReleaseDC(NULL, desktop);
    ::ReleaseDC(NULL, hDC);

    CWnd::OnWinSettingChange(uFlags, lpszSection);
}

The DPI always returns 96, but the settings changes DO take effect when I change the font size to Extra Large Fonts or if I change the DPI to 120 (from the graphics properties).

like image 604
Kiril Avatar asked Oct 16 '08 23:10

Kiril


1 Answers

[EDIT after re-read] I'm almost positive that changing to "Large fonts" does not cause a DPI change, rather it's a theme setting. You should be able to verify by applying the "Large fonts" change and then opening the advanced display properties where the DPI setting lives, it should have remained at 96dpi.


DPI change is supposed to require a reboot. Maybe the setting hasn't propagated to a place where GetDeviceCaps can retrieve it?

Maybe try changing a non-reboot-requiring setting (resolution perhaps) and then see if you can detect the change. If you can, your answer is probably that you can't detect DPI change until after reboot.

like image 69
Aidan Ryan Avatar answered Oct 22 '22 08:10

Aidan Ryan