Pregunta

Estoy tratando de determinar cómo puedo detectar cuando el usuario cambia el tamaño de fuente de Windows de fuentes normales a extra grandes, el tamaño de fuente se selecciona ejecutando los siguientes pasos en una máquina con Windows XP:

  1. Haga clic derecho en el escritorio y seleccione Propiedades.
  2. Haga clic en la pestaña Apariencia.
  3. Seleccione el tamaño de fuente: fuentes normales / grandes / fuentes extragrandes

Entiendo que el cambio de tamaño de fuente produce un cambio de DPI, así que esto es lo que he intentado hasta ahora.


Mi objetivo:

Deseo detectar cuándo el Tamaño de fuente de Windows ha cambiado de Fuentes normales a Grandes o Extragrandes y tomar algunas medidas en función de ese cambio de tamaño de fuente. Supongo que cuando el Tamaño de fuente de Windows cambia, el DPI también cambiará (especialmente cuando el tamaño es Fuentes extragrandes


Lo que he probado hasta ahora:

Recibo varios mensajes que incluyen: WM_SETTINGCHANGE, WM_NCCALCSIZE, WM_NCPAINT, etc. Pero ninguno de estos mensajes es exclusivo de la situación cuando cambia el tamaño de la fuente, en otras palabras, cuando recibo el mensaje WM_SETTINGSCHANGE quiero saber qué cambiado.

En teoría, cuando defino OnSettingChange y Windows lo llama, lpszSection debería decirme cuál es la sección de cambio, y eso funciona bien, pero luego verifico la sección dada llamando a SystemParametersInfo y paso la acción SPI_GETNONCLIENTMETRICS, y Paso por el depurador y me aseguro de mirar los datos en el NONCLIENTMETRICS devuelto para ver si hay cambios en la fuente, pero ninguno ocurre.

Incluso si eso no funcionara, aún debería poder verificar el DPI cuando cambie la Configuración. Realmente no me importarían los otros detalles, cada vez que recibo el mensaje WM_SETTINGCHANGE, simplemente verifico el DPI y realizo las acciones que me interesa realizar, pero tampoco puedo obtener el DPI del sistema.

He intentado obtener el DPI invocando el método GetSystemMetrics, también para cada DC:

Dekstop DC- > GetDeviceCaps LOGPIXELSX / LOGPIXELSY Ventana DC- > GetDeviceCaps LOGPIXELSX / LOGPIXELSY DC- > GetDeviceCaps actuales LOGPIXELSX / LOGPIXELSY

Incluso si cambio el DPI en la Ventana de Propiedades Gráficas, estos valores no devuelven nada diferente, siempre muestran 96.

¿Alguien podría ayudarme a resolver esto por favor? ¿Qué debería estar buscando? ¿Dónde debería estar mirando?

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);
}

El DPI siempre devuelve 96, pero los cambios en la configuración tienen efecto cuando cambio el tamaño de fuente a Fuentes extragrandes o si cambio el DPI a 120 (desde las propiedades de los gráficos).

¿Fue útil?

Solución

[EDITAR después de volver a leer] Estoy casi seguro de que cambiar a " Fuentes grandes " no causa un cambio de DPI, sino que es una configuración de tema. Debería poder verificar mediante la aplicación de " Fuentes grandes " cambiar y luego abrir las propiedades de visualización avanzadas donde vive la configuración de DPI, debería haber permanecido en 96 ppp.


Se supone que el cambio de DPI requiere un reinicio. ¿Tal vez la configuración no se ha propagado a un lugar donde GetDeviceCaps pueda recuperarla?

Quizás intente cambiar una configuración que no requiera reinicio (resolución quizás) y luego vea si puede detectar el cambio. Si puede, es probable que su respuesta sea que no puede detectar el cambio de DPI hasta después del reinicio.

Otros consejos

Cuando llama a GetDeviceCaps () en Desktop DC, ¿está utilizando un DC que MFC puede almacenar en caché y, por lo tanto, contiene información desactualizada? ¿Está realizando la llamada GetDeviceCaps () sincrónicamente desde el controlador OnSettingsChange? Pude ver cómo una o ambas de estas cosas pueden obtener una versión desactualizada de DPI.

Raymond Chen escribió sobre esto y su la solución se veía así (tenga en cuenta que he agregado :: operadores para evitar llamar a los contenedores MFC de las API):

int GetScreenDPI()
{
  HDC hdcScreen = ::GetDC(NULL);
  int iDPI = -1; // assume failure
  if (hdcScreen) {
    iDPI = ::GetDeviceCaps(hdcScreen, LOGPIXELSX);
    ::ReleaseDC(NULL, hdcScreen);
  }
  return iDPI;
}

Tengo el presentimiento de que WM_THEMECHANGED se encargará de ti. Sin embargo, no tiene ninguna pista sobre lo que cambió. Tendrá que usar OpenThemeData y la configuración inicial de la memoria caché, luego comparar cada vez que reciba el mensaje.

Probablemente no necesite preocuparse por lo que cambió, ¿no puede tener una rutina de diseño de propósito general que ajuste su forma / diálogo / lo que sea teniendo en cuenta todo y suponga que comienza desde cero?

¿Qué problema estás tratando de resolver?

Ver http://msdn.microsoft.com /en-us/library/ms701681(VS.85).aspx , esto se explica allí (cita: " Si no cancela la escala de ppp, esta llamada devuelve el valor predeterminado de 96 ppp. ")

No creo que el DPI de la pantalla cambie cuando cambia el tamaño de la fuente. Es probable que Windows solo envíe los mensajes WM_PAINT y WM_NCPAINT a todas las ventanas abiertas, y se vuelven a dibujar utilizando la fuente del sistema actual (ahora grande).

Mire estos valores en el Registro:

Tema de Windows XP HKCU \ Software \ Microsoft \ Windows \ CurrentVersion \ ThemeManager \ SizeName Valores posibles: NormalSize, LargeFonts y ExtraLargeFonts Estos valores son independientes del idioma .

Tema clásico de Windows HKCU \ Panel de control \ Apariencia \ Actual Valores posibles: Windows Classic, Windows Classic (grande), Windows Classic (extra grande), Windows Standard, Windows Standard (grande), Windows Standard (extra grande) Tenga en cuenta que estos valores son dependientes del idioma .

Windows Vista no es compatible con esta función. Si queremos una fuente más grande, simplemente cambie la configuración de DPI. En ese caso, GetDeviceCaps debería funcionar.

Espero que esto ayude.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top