Este artículo proviene de un motor de traducción automática.
Windows con C++
Escriba aplicaciones con configuración elevada de ppp para Windows 8.1
Windows 8 introdujo un nuevo modelo de programación de aplicaciones de Windows, basado en la ejecución de Windows (WinRT), que permite a los usuarios cambiar dinámicamente el tamaño de los elementos de la pantalla con un entorno de PC. Puedes ver lo que parece esta opción en la configuración del PC en figura 1. En mi escritorio, las opciones son por defecto y Larger. En mi Surface Pro, las opciones son más pequeño y por defecto. Realmente depende del dispositivo y, en particular, la resolución vertical de la muestra adjunta. Más importante, aplicaciones Windows Store reciben un evento siempre que esta opción se cambia y por lo tanto puede actualizar dinámicamente su código de representación para reflejar el factor de escalamiento actual.
Figura 1 configuración de PC Windows 8.1 afectando a aplicaciones Windows Store
El escritorio de Windows 8, sin embargo, permaneció estático. Aplicaciones de escritorio continuaron a ser reparado por una configuración de PPP del sistema, cualquier cambio a la que sólo tenga efecto después de que el usuario firme hacia fuera y de nuevo, efectivamente obligando a todas las aplicaciones para apagar y reiniciar. Puedes ver esta opción, que está todavía disponible en Windows 8.1, en figura 2, con sus opciones más granulares más pequeño, mediano, más grande y Extra grande. Me recuerda a un viaje a la tienda de café local. Aquí, también, las opciones que pueden estar disponibles dependen de la muestra adjunta. Mi Surface Pro, por ejemplo, sólo incluye más pequeño, mediano y más grande.
Figura 2 Pre-Windows 8.1 configuración de PC que afecta a las aplicaciones de escritorio
No hace falta decirlo, esto dividido personalidad — como muchas cosas en Windows 8 — puede ser bastante confuso para el desarrollador, sin mencionar el usuario. Mientras que Windows 8.1 realmente no aborda la confusión de alguna manera significativa, que finalmente permite aplicaciones de escritorio tratar igualmente DPI escala dinámicamente, así el usuario ya no se ve obligado a cerrar todo y trae una nueva sesión de inicio de sesión. Pero Windows 8.1 va mucho más lejos y le da nueva vida a las configuraciones de varios monitores.
Mientras que la ventana de figura 2parece bastante similar a lo que estaba disponible en Windows 8, que ahora luce una pequeña casilla de verificación que se agregó en el punto 8.1 de Windows. Aunque se registra figura 2, por defecto está desactivado. El título de la casilla de verificación, "déjame elegir un nivel de escalamiento para todas mis pantallas," alude a la capacidad de otra que es nueva en el punto 8.1 de Windows: la capacidad de diferentes monitores a diferentes factores de escala. El título de la casilla de verificación es un poco confuso, como despejar esta casilla de verificación sigue ofreciendo valor a los usuarios que sólo tienen un único monitor. En ese caso, todavía ofrece al usuario la opción de cambiar dinámicamente el factor de escalamiento. Realmente esta opción representa un modo legado o compatibilidad para el comportamiento DPI. Así que si tienes varios monitores — o más importante, sin importar cuántos monitorea los usuarios normalmente pueden utilizar — vas a querer venir a los apretones con estas nuevas opciones. Se afectan sus aplicaciones ya sea que te guste o no. Borra esta casilla de verificación revela la ventana figura 3. Otra vez, ahora es el valor por defecto en Windows 8.1.
Figura 3 Configuración de PC Windows 8.1 que afectan la dinámica y escala para el escritorio por Monitor
Si piensas en ello, no hay ninguna diferencia entre figura 2 y figura 3. El primero utiliza cuatro botones y este último utiliza un deslizador con cuatro posiciones posibles. La única diferencia real es que los cambios el deslizador surten efecto inmediatamente, o al menos tan pronto como Pulse el botón aplicar. Es más la misma experiencia, por lo menos para el usuario, como la opción de escala para las aplicaciones Windows Store. Cambios a la selección del botón de radio, sin embargo, sólo surtirán efecto la próxima vez que el usuario firma adentro.
Los cuatro valores posibles, para el control deslizante o botones de radio, corresponden a la OMPD cuatro factores de escala y se ilustran en la figura 4. Como desarrollador, te advierto que no leer demasiado en los valores específicos de DPI. Deben reflejar la densidad resolución o pixel de la pantalla, pero en realidad muchos factores influyen en el valor DPI — como el factor de forma y distancia a la pantalla, así el valor eficaz de DPI terminas usando tiene poco que ver con una pulgada real. Estas cuatro opciones también representan el espectro completo de posibilidades, pero lo que puede ofrecer una PC particular depende de la resolución vertical de sus exhibiciones.
Figura 4 sistema factores de escala
PPP | Percentage |
96 | 100 |
120 | 125 |
144 | 150 |
192 | 200 |
Esto se ilustra en la figura 5. Estos límites están diseñados para impedir que elementos de la IU se recorta la parte inferior de la pantalla. Si la pantalla tiene menos de 900 líneas de resolución vertical, entonces no tendrá ninguna opción y será del 100% factor de escala es. A medida que aumenta la resolución vertical de la pantalla, usted está presentado con más opciones hasta llegar a 1.440 líneas de resolución vertical, momento en el cual experimenta todas cuatro opciones posibles. Estas opciones no, sin embargo, afectan el escalado en todos los monitores igualmente. Esto es de donde viene el concepto de per-monitor DPI escala. No es enteramente evidente a primera vista porque el OS tienen en cuenta tanto la resolución vertical como el DPI nativa para la pantalla física.
Figura 5 escala a relativa de las opciones de resolución Vertical
Resolution | Opciones de escala |
… – 900 | 100% |
900 – 1079 | 100% – 125% |
1080 – 1439 | 100% – 125% – 150% |
1440 – ... | 100% – 125% – 150% – 200% |
Como desarrollador de aplicaciones de escritorio, es importante tener en cuenta que ahora hay dos factores de escala que pueden estar en juego. Hay el factor de escala del sistema DPI y luego hay un factor de escala de DPI por monitor. El factor de escala del sistema DPI corresponde a uno de los valores de figura 4— con la excepción de dispositivos tales como Windows Phone — y se mantiene constante durante la duración de la sesión. El sistema de DPI valor se basa en el botón de radio inicial se muestra en la figura 2o la posición del control deslizante se muestra en la figura 3.
Para recuperar el sistema de valor DPI, empiezas por conseguir el contexto de dispositivo de escritorio. Sí, esto se reduce a la antigua API GDI , pero que no tiene nada que ver con la representación de GDI y es sólo una nota histórica. En primer lugar, para obtener un identificador que representa el contexto de dispositivo de escritorio, se llama a la función GetDC con un nullptr en lugar de un identificador de ventana. Este valor especial indica que quieres el contexto de dispositivo para el escritorio como un todo en lugar de una ventana particular:
auto dc = GetDC(nullptr);
Naturalmente, debe recordar liberar esta manija cuando termines:
ReleaseDC(nullptr, dc);
El primer parámetro es el identificador para la ventana a que se refiere el contexto de dispositivo. Una vez más, un valor nullptr representa el escritorio. Ahora, teniendo en cuenta el contexto de dispositivo, puede utilizar la función GetDeviceCaps para recuperar el sistema de DPI factor de escalamiento para x e y de las hachas de la siguiente manera:
auto x = GetDeviceCaps(dc, LOGPIXELSX);
auto y = GetDeviceCaps(dc, LOGPIXELSY);
Tener un valor diferente para x e y las fechas de las hachas de la edad oscura cuando las impresoras ofrecen rutinariamente escala diferentes factores horizontalmente y verticalmente. Nunca he venido a través de una pantalla que ofrece píxeles no cuadrados, pero he oído que existe en algunas industrias que han desarrollado las tarjetas gráficas especiales. LOGPIXELSX y LOGPIXELSY representan el número de píxeles por pulgada lógica a lo largo de la anchura y la altura del escritorio. Una vez más, esto es una lógica de pulgada y no debe reflejar la realidad. Además, estos son los valores del sistema DPI, significa que son iguales para todos los monitores que abarcan el escritorio independientemente de cómo relativamente grandes o lo pequeños que sean. Ahí radica el problema.
Si se conecta tu tablet Dell lugar 8 Pro con su pantalla de 8 pulgadas en una gran variedad de monitores Dell UltraSharp 30 pulgadas, vas a tener que tomar una difícil decisión. Rutinariamente de enchufe a dos o tres monitores vastamente diferentes tarjeta gráfica de mi escritorio. Un factor de escala de todo el sistema DPI no basta. Lo que se necesita es que cada monitor tener un factor de escala de DPI ideal para su resolución o tamaño relativo. Esto es exactamente lo que Windows 8.1 ofrece con su DPI por monitor escalamiento apoyo.
8.1 Windows ofrece tres diferentes niveles de conciencia DPI. Esto es obvio cuando te ves en la ventana de Process Explorer, se muestra en la figura 6. Puedes ver que algunas aplicaciones desconocen totalmente DPI-, como en el caso de los comandos. Mayoría de las aplicaciones escritas para Windows 7 y Windows 8 es sistema de DPI-consciente, o por lo menos pretende ser. Los ejemplos incluyen la calculadora y Microsoft Outlook. Por monitor DPI conciencia es el tercero y óptimo nivel de conciencia. Ejemplos en figura 6 incluyen Internet Explorer y la Microsoft Word. Curiosamente, no en realidad por monitor DPI-consciente en el momento, pero he desactivado visualización para Word evitar la borrosidad. Esto tiene el efecto de anular la conciencia DPI de proceso para que el administrador de ventanas de escritorio no escala de la ventana. Esto se hizo con una opción de compatibilidad.
Figura 6 proceso Explorer muestra supuesta conciencia DPI
El punto principal es que mejor asegúrate de que tus aplicaciones por monitor DPI-conscientes y por consiguiente la escala. ¿Cómo puedes hacer esto? Sigue leyendo.
Diferentes aplicaciones hacen varias afirmaciones acerca de su nivel de conciencia DPI y la ventana de escritorio Gerente — el servicio encargado de componer las ventanas de aplicación diferentes juntos — determina cómo diferentes ventanas de las aplicación basadas en sus reclamaciones individuales DPI tal que todas las ventanas presentan un nivel consistente de la escala. Si una aplicación pretende ser conscientes del monitor por DPI, el administrador de ventanas de escritorio no escala la ventana en absoluto y asume que la aplicación sabe lo que está haciendo. Si una aplicación es sistema de DPI-consciente, el administrador de ventanas de escritorio escalará la ventana basada en la suposición de que se rindió al factor de escalamiento de DPI sistema devuelto por la función GetDeviceCaps que he mencionado anteriormente. Y si una aplicación es DPI-consciente, el administrador de ventanas de escritorio asume la ventana fue rendida a la tradicional 96 ppp y por consiguiente lo escalas.
Antes de que yo considero realmente escribir un comporten bien, por-monitor, DPI-aplicación, analizaré lo que se necesita para hacer tal afirmación. Windows Vista introdujo la función SetProcessDPIAware para marcar el proceso de llamada como consciente de DPI. Esta función sin argumentos llevó y simplemente se convirtió en la conciencia de DPI, por así decirlo. Esto fue antes de la conciencia al monitor, así que esto era un estado binario simple. Tampoco que eres consciente de DPI o no. Windows 8.1 introdujo una nueva función llamada SetProcessDpiAwareness que proporciona más control sobre este nivel de conciencia:
VERIFY_(S_OK, SetProcessDpiAwareness(PROCESS_PER_MONITOR_DPI_AWARE));
Esto establece conciencia DPI del proceso a nivel determinado. Constantes se encuentran disponibles para cubrir los tres posibles estados: DPI-conscientes, sistema de DPI-consciente y por monitores DPI-consciente. También hay una función de GetProcessDpiAwareness correspondiente a este valor para un determinado proceso de consulta. Pero utilizando código para establecer el nivel de conciencia tiene una serie de inconvenientes. Tienes que tener cuidado de llamar a estas funciones desde el principio en vida de su aplicación. A veces esto no es práctico y causa una serie de cuestiones al mezclar archivos ejecutables y DLLs. Se pidió una solución mejor.
Las aplicaciones pueden incrustar o distribuir un archivo de manifiesto — junto con sus archivos binarios — que contiene sugerencias para la cáscara o Windows loader para usar en la determinación de cómo preparar el proceso de aplicación antes de cualquier código comienza a funcionar. El shell de Windows utiliza esto para una variedad de propósitos, incluyendo características de seguridad, información de dependencias de la Asamblea y, sí, afirma DPI-conciencia.
Estos archivos de manifiesto son sólo archivos de texto. Ellos están incrustados dentro del ejecutable como un recurso tradicional de Win32 o simplemente enviaron junto con el archivo ejecutable. Usted puede, por ejemplo, tomar una ojeada en el archivo de manifiesto para la palabra mediante la herramienta manifiesta que se incluye con el Windows SDK usando el siguiente comando:
mt -inputresource:"C:\ ...
\WINWORD.EXE" -out:manifest.xml
Yo he cicatrizar la ruta completa para ahorrar espacio. Si todo sale bien, serás recompensado con un documento XML en el directorio actual. Puedes ver lo que parece figura 7. En medio de algún otro modo información relacionada sobre el ejecutable de la palabra es el elemento dpiAware y su valor de verdad.
Figura 7 el archivo de manifiesto Microsoft Word
Si una aplicación no tiene un archivo de manifiesto y no utiliza el enfoque programático de ajuste del nivel de su conciencia, entonces se asume que para DPI-ignorar. Si una aplicación tiene un archivo de manifiesto pero no contiene el elemento dpiAware, luego otra vez se asume DPI-ignorar. En Windows 7, la presencia del elemento dpiAware es suficiente para el sistema asumir que es consciente de DPI. No importa qué valor contiene este elemento o si ni siquiera tiene un valor. 8 La ventana es un poco más específica. Se espera un valor a partir de T, en el supuesto de que dice "True". Caso no importa.
Así trata con DPI-conscientes y sistema de DPI-aplicaciones. ¿Qué pasa con las aplicaciones per-monitor DPI-consciente? Bueno, cuando esta función se desarrolló primero, fue elegido un nuevo valor para el elemento dpiAware: Por Monitor. El deseo de dejar que los desarrolladores de aplicaciones a producir un binario único capaz de apuntar tanto Windows 7 y Windows 8 con soporte para sistema DPI conciencia, así como conocimiento DPI por monitor en Windows 8, condujo a un nuevo valor a elegir: Verdadero/PM. Esto permite que Windows 7 y Windows 8 para aceptar el binario como sistema de DPI-consciente, y Windows 8.1 lo acepta como por monitor DPI-consciente. Por supuesto, podrá utilizar por Monitor si sólo necesitas soporte Windows 8.1.
Por desgracia, Visual C++ 2013 aún no es compatible con este nuevo valor, pero hay una manera de hacer que suceda. La herramienta se manifiestan que es parte de la construcción de proyecto de Visual C++ tiene una opción para combinar en archivos de manifiesto adicionales. Todo lo que necesitas hacer es crear un archivo de texto con el elemento correcto dpiAware y valor y combinarlo en su construcción. El código siguiente muestra el XML que necesitas:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1"
manifestVersion="1.0">
<application xmlns="urn:schemas-microsoft-com:asm.v3">
<windowsSettings>
<dpiAware xmlns=
"https://schemas.microsoft.com/SMI/2005/WindowsSettings">
True/PM</dpiAware>
</windowsSettings>
</application>
</assembly>
Una vez que haya creado el archivo de manifiesto, simplemente puedes actualizar la configuración de su proyecto, como se ilustra en figura 8. El manifiesto se define como un archivo de manifiesto adicional y la conciencia DPI se establece en ninguno.
Opciones de la herramienta manifiesta figura 8
Cuando se trata de representar la ventana de su aplicación, necesita para asegurarse de que tiene el factor de escala derecho DPI. Si te ves después de una aplicación obsoleta con profundas raíces en gráficos GDI y controles de usuario, entonces es probable que vas a experimentar un montón de desafíos al tratar de hacerlo por-monitor DPI-consciente. Estos son los mismos desafíos que enfrentan los equipos de Windows y Office de Microsoft. Pero si has estado siguiendo mi columna, sabes que Direct2D es el camino a seguir. Direct2D se encarga de todas su DPI escala necesidades y presenta un sistema de coordenadas lógico independiente de los píxeles físicos y el factor de escala de DPI. Por supuesto, para que Direct2D poder hacerlo de manera eficaz, tienes que decir qué valores DPI para un determinado render target.
Tradicionalmente, Direct2D aplicaciones simplemente habían obtenido los valores DPI de la fábrica de Direct2D, que a su vez simplemente llamado GetDeviceCaps, conectore antes. Pero esto ya no es suficiente. Como te he enseñado, ahora pueden cambiar los valores DPI sobre la marcha, y el valor suministrado por GetDeviceCaps sólo es útil si estás tratando de encajar en la prestación de un sistema de DPI-aplicación.
En su lugar, justo después de que has creado tu Direct2D render target, necesitas consultar el valor DPI para el monitor más cercano a su ventana:
auto monitor = MonitorFromWindow(window, MONITOR_DEFAULTTONEAREST);
Dada esta manija de monitor, puede llamar a la función GetDpiForMonitor para recuperar los valores DPI para este monitor específico:
auto x = unsigned {};
auto y = unsigned {};
VERIFY_(S_OK, GetDpiForMonitor(monitor, MDT_EFFECTIVE_DPI, &x, &y));
El valor eficaz de DPI para un monitor dado no necesariamente corresponde exactamente a opciones que se presentan en figura 4. Otra vez depende de una serie de factores, incluida la resolución, el DPI física de la pantalla y la supuesta distancia a la superficie de la pantalla. Finalmente, se puede llamar método SetDpi del objetivo render Direct2D y Direct2D se encargará de escalar adecuadamente su contenido según sea necesario.
Mencioné que esto puede suceder de forma dinámica. La aplicación puede ejecutarse y de repente el usuario cambia la escala con la ventana que se muestra en la figura 3 o arrastra tu ventana a otro monitor con un factor de escala diferente de DPI. En esos casos, el shell de Windows enviará las ventanas de aplicación por monitores DPI-consciente una nueva ventana de mensaje llamado WM_DPICHANGED.
Dentro de su controlador de mensajes, usted puede llamar una vez más el MonitorFromWindow y funciones GetDpiForMonitor para obtener los valores DPI efectivos para el monitor actual y luego simplemente actualizar su Direct2D render target con su método SetDpi otra vez. Alternativamente, WPARAM del mensaje paquetes valores DPI x e y para que esto se convierte en una simple cuestión de extraer las palabras de orden baja y alta:
auto x = LOWORD(wparam);
auto y = HIWORD(wparam);
Sin embargo, LPARAM del mensaje WM_DPICHANGED es indispensable. Proporciona una nueva posición sugerida y tamaño de la ventana basada en el nuevo factor de escala que está ahora en vigor. Esto asegura que mientras Direct2D se encarga de escalar el contenido, también puede escalar el tamaño real de su ventana en el escritorio y colocarlo correctamente. LPARAM del mensaje es simplemente un puntero a una estructura rectangular:
auto rect = *reinterpret_cast<RECT *>(lparam);
Simplemente puede llamar la función SetWindowPos para actualizar la posición y el tamaño de la ventana:
VERIFY(SetWindowPos(window,
0, // No relative window
rect.left,
rect.top,
rect.right - rect.left,
rect.bottom - rect.top,
SWP_NOACTIVATE | SWP_NOZORDER));
Y eso es todo lo que necesita. Si usted ha invertido en Direct2D, estás a pocos pasos por monitor DPI-consciente. Algunas aplicaciones han dado el salto, su aplicación es obligado destacar! Si tienes una aplicación existente de Windows Presentation Foundation (WPF), también hay una muestra disponible en bit.ly/IPDN3p que muestra cómo integrar estos mismos principios descritos en este artículo en su base de código WPF.
Figura 9 proporciona un ejemplo de una aplicación por monitores DPI-consciente, automáticamente escalado tanto su contenido y su tamaño de la ventana basados en los mensajes WM_DPICHANGED. El emoticon indica qué monitor se encuentra situada actualmente en la ventana. Para obtener un ejemplo más interactivo, por favor revise mi curso de Pluralsight en bit.ly/1fgTifi, donde también puede obtener el código de ejemplo para esta aplicación.
Figura 9 por Monitor DPI-aplicación
Kenny Kerr es un programador de computadoras con sede en Canadá, así como un autor de Pluralsight y un MVP de Microsoft. Blog en kennykerr.ca y lo puedes seguir en Twitter en twitter.com/kennykerr.
Gracias al siguiente experto técnico por su ayuda en la revisión de este artículo: James Clarke (Microsoft)