c++ - titulo - ¿Cómo se escala la barra de título en una aplicación para ganar con reconocimiento de DPI?
iconos de la barra de titulo (4)
Estoy haciendo que mi aplicación tenga en cuenta los ppp por monitor al configurar <dpiAware>True/PM</dpiAware>
en el archivo de manifiesto. Puedo verificar con el explorador de procesos que esto realmente funciona o llamando a GetProcessDpiAwareness.
Todo esto funciona bien y puedo escalar cualquier cosa en el área del cliente en mi código. Sin embargo, mi único problema es que si arrastro mi aplicación desde un monitor de ppp del sistema a un monitor de ppp que no es del sistema, la barra de título y cualquier menú del sistema serían demasiado grandes o demasiado pequeños. Este no es el caso de la mayoría de las aplicaciones integradas (por ejemplo, calc, navegador de borde, etc.), por lo que debe haber una distancia para escalarlo correctamente. ¿Alguien cómo los desarrolladores en MS hicieron esto?
La captura de pantalla de abajo debería explicar mejor mi problema. También tenga en cuenta que el relleno entre los botones de cierre, mínimo y máximo es diferente cuando se escala (96 ppp).
Aplicación de muestra Estoy adjuntando una aplicación muy simple que reconoce ppp por monitor.
¿Alguien cómo los desarrolladores en MS hicieron esto?
Esto tiene una respuesta bastante decepcionante. Al usar WinCheat de Alin Constantin e inspeccionar la ventana de nivel superior de la Calculadora, veo un tamaño de ventana de 320x576 y un tamaño de cliente que también es de 320x576.
En otras palabras, Microsoft evita por completo el problema al suprimir el área que no es de cliente de la ventana, poniendo todo en el área de cliente en su lugar. Hacer que esto funcione bien para usted puede involucrar un dibujo personalizado de la barra de título.
Algo que vale la pena notar es que la Calculadora y, por ejemplo, el Explorador de Windows no usan el mismo color para las barras de título. La calculadora haciendo un dibujo personalizado de la barra de título lo explicaría perfectamente.
La documentation dice:
Tenga en cuenta que Windows no escala el área de no cliente de una aplicación por monitor-DPI, y aparecerá proporcionalmente más pequeña en una pantalla de alta DPI.
Las aplicaciones de Microsoft que vincula para hacer frente a esto eliminando el área de no clientes y haciendo que el área de clientes cubra toda la ventana.
La actualización de aniversario de Windows 10 (v1607) ha agregado una nueva API a la que debe llamar para habilitar el escalamiento de DPI de las áreas que no son clientes: EnableNonClientDpiScaling
. Se debe llamar a esta función cuando se recibe WM_NCCREATE
. El mensaje se envía a la devolución de llamada del procedimiento de la ventana durante la creación de la ventana.
Ejemplo:
case WM_NCCREATE:
{
if (!EnableNonClientDpiScaling(hWnd))
{
// Error handling
return FALSE;
}
return DefWindowProcW(...);
}
Si el contexto de DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2
de DPI de la aplicación es DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2
, se debe omitir la EnableNonClientDpiScaling
, ya que no tendrá ningún efecto, aunque la función seguirá regresando con éxito.
De EnableNonClientDpiScaling :
El escalado que no es de cliente para ventanas de nivel superior no está habilitado de forma predeterminada. Debe llamar a esta API para habilitarla para cada ventana de nivel superior individual para la cual desea que la escala de área de no cliente automáticamente. Una vez que lo haces, no hay manera de desactivarlo. Habilitar el escalado no del cliente significa que todas las áreas dibujadas por el sistema para la ventana se escalarán automáticamente en respuesta a los cambios de DPI en la ventana. Eso incluye áreas como la barra de título, las barras de desplazamiento y la barra de menús. Desea llamar a
EnableNonClientDpiScaling
cuando desee que el sistema operativo se encargue de representar estas áreas automáticamente en el tamaño correcto según la API del monitor.
Consulte esta publicación del blog para obtener información adicional sobre los cambios de escala de DPI en Windows 10 AU.
ACTUALIZAR:
Es suficiente agregar una nueva declaración <dpiAwarness>
para manifestar y resolver todo este lío. El ejemplo está here .
Restos de investigaciones anteriores (obsoletos):
Más investigaciones sobre el tema.
Configuración del sistema: dos monitores, uno con 96 ppp, otro con 267 ppp (Microsoft Surface 4).
La ventana de prueba se mueve al monitor secundario de 96 ppp:
Aquí está la representación (mal, IMO) con <dpiAware>true/pm</dpiAware>
en el manifiesto:
Tenga en cuenta el gran tamaño de la barra de título y el tamaño incorrecto de los iconos de ventana.
Y aquí está la representación correcta utilizando <dpiAware>true</dpiAware>
Y sospecho que la documentación de MSDN es claramente engañosa sobre los valores de PROCESS_DPI_AWARENESS . No veo ninguna diferencia en los mensajes y estilos entre <dpiAware>true</dpiAware>
y <dpiAware>true/pm</dpiAware>
. El último solo hace que el título sea más grande. En ambos casos, la aplicación recibe el mensaje WM_DPICHANGED mientras se mueve entre monitores con diferentes DPI.
Suspiro.