Click to See Complete Forum and Search --> : Can't Detect Windows Font Size Change


kgantchev
October 17th, 2008, 10:13 AM
Hi,
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 when I receive an OnSettingChange call, I would like to see if the Font Size or the DPI has changed.

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).

kgantchev
October 20th, 2008, 12:47 AM
I found out that a WM_THEMECHANGED message is sent when the Font Size changes, but then I have to use OpenThemeData and cache initial settings, then compare every time I get the message... OpenThemeData expects a string with the class name for which I'm interested to see data, but I only know of one class name ("button").

Does anybody know what are the possible classes for the second parameter of that function?