¿Qué fuente es la predeterminada para los controles de diálogo MFC?

La imagen siguiente (ampliada, por lo que es mejor ver las diferencias) muestra las diferencias de fuente entre los controles de edición creados dinámicamente (los dos ejemplos superiores) y los controles de edición creados desde el Editor de cuadros de diálogo (el ejemplo inferior). ¿Cómo puedo hacer que la fuente de mis controles CEdit creados dinámicamente se vea como la predeterminada (el ejemplo más bajo)?

enter image description here

He creado los controles CEdit como los siguientes:

obj->CreateEx(WS_EX_CLIENTEDGE, _T("EDIT"), _T(""), WS_CHILD | WS_VISIBLE | WS_TABSTOP, rect.left, rect.top, rect.Width(), rect.Height(), GetSafeHwnd(), reinterpret_cast(mId)); obj->SetFont(&mFont); // mFont was created in the Dialog Constructor // with mFont.CreatePointFont(80, _T("MS Shell Dlg")); 

¡Gracias por tu ayuda!

El primer ejemplo es usar la fuente del sistema ( SYSTEM_FONT ), recuperada con la función GetStockObject , que es una fuente de bitmap que no se usa desde los días de Windows 3. Hay más información disponible en el blog de Raymond Chen y en el blog de Michael Kaplan .

El segundo ejemplo es usar la fuente “MS Shell Dlg” , tal como lo solicitó. Eso realmente se asigna a una fuente llamada “Microsoft Sans Serif” o “MS Sans Serif”, la fuente de la interfaz de usuario en los días de Windows 95 y 98. Esto también se conoce como DEFAULT_GUI_FONT , que de hecho solía ser un nombre preciso para ello, pero, por desgracia, ya no es exacto.

A partir de Windows 2000 (y continuó en XP), se usó Tahoma como la fuente de UI predeterminada. Esto es lo que está viendo en el tercer ejemplo: Tahoma 8 pt. Desafortunadamente, incluso en esos sistemas operativos, “MS Shell Dlg” no devuelve Tahoma, todavía devuelve MS Sans Serif, por lo que se ve mal.

Por lo tanto, podría simplemente especificar Tahoma como la fuente de la GUI, pero eso no sería realmente correcto, porque se rompería en las versiones anteriores del sistema operativo donde Tahoma no está instalado o es compatible, o en versiones en idiomas extranjeros del sistema operativo, donde se usa una fuente diferente por necesidad. En cambio, se supone que debes especificar la DS_SHELLFONT , de la cual Raymond habla aquí .

Y todo estuvo bien hasta que salió Windows Vista. Y en Windows Vista, los poderes fácticos de Microsoft decidieron que Tahoma se estaba volviendo un poco introvertido y que a Windows le esperaba otra actualización de la fuente de UI . Desarrollaron su propia fuente especial interna llamada Segoe UI , supuestamente diseñada para una legibilidad óptima en pantalla. Y en un pequeño giro especial, decidieron que el tamaño predeterminado ahora debería ser de 9 puntos , en lugar de 8 puntos, tal como lo utilizaba cada versión anterior del sistema operativo, independientemente de la fuente. Y probablemente pienses que “MS Shell Dlg”, “MS Shell Dlg2” o DS_SHELLFONT (o los tres) obtendrían esta nueva fuente de UI de Segoe, pero estarías equivocado.

UH oh. Ahora las cosas se complican … Vista no solo usa una fuente diferente a XP a la que no se puede acceder fácilmente con un identificador único para todos, sino que también usa un tamaño diferente, cambiando la forma en que se verá su diálogo en esos sistemas, si puede lograr que se muestre en absoluto. En muchos, muchos lugares, el equipo shell de Windows parecía simplemente superar el desafío: Tahoma 8 pt se usa en todas partes , incluso con el tema Aero habilitado, cuando se supone que usa Segoe UI 9 pt. Este tipo de cosas realmente hacen que la interfaz de usuario se vea sin pulir, y fue tema de muchos detalles en los primeros días de Vista. Ahora, parece que la mayoría de la gente lo ha olvidado, pero la interfaz de usuario no ha comenzado a verse menos dispersa e inconsistente.

Y usted no es el equipo shell de Windows: no puede salirse con la suya con su propia aplicación. Las Reglas principales para la Experiencia de usuario de Windows Vista incluso indican explícitamente que siempre debe:

  • Use la IU de Segoe, la nueva fuente del sistema de Windows Vista.
  • Respete la configuración del usuario haciendo referencia siempre a la fuente, los tamaños y los colores del sistema con las API de Windows Theme. No use valores fijos para fonts, tamaños o colores.

Para ser sincero, todavía no he escuchado una buena solución a este problema. Y sospecho que para cuando lo haga, ya nadie tendrá que dar soporte a Windows XP (aunque la mayoría de la gente aún no está allí). Pero esto es lo que hago: Extraigo la fuente predeterminada del sistema en tiempo de ejecución utilizando la función SystemParametersInfo . Afortunadamente, la fuente del cuadro de mensaje del sistema ( lfMessageFont ) es la cara y el tamaño de fuente correctos, independientemente de la versión actual de Windows y del tema elegido por el usuario.

Mi código para inicializar ventanas o cuadros de diálogo generalmente se ve así ( SystemInfo::IsVistaOrLater es una función auxiliar que he escrito; la implementación es obvia):

 // Get the system message box font NONCLIENTMETRICS ncm; ncm.cbSize = sizeof(ncm); // If we're compiling with the Vista SDK or later, the NONCLIENTMETRICS struct // will be the wrong size for previous versions, so we need to adjust it. #if(_MSC_VER >= 1500 && WINVER >= 0x0600) if (!SystemInfo::IsVistaOrLater()) { // In versions of Windows prior to Vista, the iPaddedBorderWidth member // is not present, so we need to subtract its size from cbSize. ncm.cbSize -= sizeof(ncm.iPaddedBorderWidth); } #endif SystemParametersInfo(SPI_GETNONCLIENTMETRICS, ncm.cbSize, &ncm, 0); HFONT hDlgFont = CreateFontIndirect(&(ncm.lfMessageFont)); // Set the dialog to use the system message box font SetFont(m_DlgFont, TRUE); SendMessage(hWnd, WM_SETFONT, (WPARAM)hDlgFont, MAKELPARAM(FALSE, 0)); 

O incluso más fácil en MFC, con el práctico método SendMessageToDescendants
( m_DlgFont es un objeto de CFont definido para la clase):

 // Get the system message box font NONCLIENTMETRICS ncm; ncm.cbSize = sizeof(ncm); SystemParametersInfo(SPI_GETNONCLIENTMETRICS, ncm.cbSize, &ncm, 0); LOGFONT lfDlgFont = ncm.lfMessageFont; m_DlgFont.CreateFontIndirect(&lfDlgFont); // Set the dialog and all its controls to use the system message box font SetFont(m_DlgFont, TRUE); SendMessageToDescendants(WM_SETFONT, (WPARAM)m_DlgFont.m_hFont, MAKELPARAM(FALSE, 0), TRUE); 

Si no está utilizando MFC, le recomiendo implementar su propia versión recursiva de SendMessageToDescendants . Hace que el código de inicialización sea mucho más simple.