Windows 8.1 a introduit la possibilité d'avoir différents paramètres PPP pour les différents moniteurs. Cette fonctionnalité est appelée "par-moniteur de haute résolution d'appui." Il persiste et a été raffiné dans Windows 10.
Si une demande n'est pas opt-in (c'est à dire, est soit DPI n'est pas au courant ou haute résolution au courant), il sera automatiquement mis à l'échelle par DWM pour la bonne DPI. La plupart des applications de l'automne dans l'une de ces deux catégories, y compris la plupart des utilitaires fournis avec Windows (par exemple, le bloc-notes). Sur mon système de test, la haute résolution du moniteur est réglée à 150% de l'échelle (144 DPI), tandis que le moniteur normal est défini pour le système de DPI (sur une échelle de 100%, de 96 PPP). Par conséquent, lorsque vous ouvrez l'une de ces applications sur la haute résolution de l'écran (ou faites-la glisser là-bas), la virtualisation des coups de pied dans, loupe tout, mais aussi ce qui la rend incroyablement floue.
Sur l'autre main, si une application indique explicitement qu'il prend en charge par le moniteur de haute résolution, alors pas de virtualisation est effectuée et que le développeur est responsable de la mise à l'échelle. Microsoft a une explication assez complète ici*, mais pour le bénéfice d'une auto-contenue question, je vais résumer. Tout d'abord, vous indiquer la prise en charge par le paramètre <dpiAware>True/PM</dpiAware>
dans le manifeste. Cette opte vous en recevant WM_DPICHANGED
messages, qui vous indique à la fois le nouveau réglage DPI et d'une proposition de nouveau la taille et la position de votre fenêtre. Il vous permet également d'appeler le GetDpiForMonitor fonction et d'obtenir la réelle DPI, sans être menti pour des raisons de compatibilité. Kenny Kerr a également écrit un didacticiel complet.
J'ai obtenu tout ce passe à merveille dans un peu de C++ application de test. Il ya beaucoup de passe-partout et la plupart du temps les paramètres du projet, donc je ne vois pas beaucoup de point en publiant un exemple complet d'ici. Si vous voulez le tester, soit de suivre Kenny instructions de ce tutoriel sur la MSDN, ou télécharger le SDK officiel de l'échantillon. Maintenant, le texte dans la zone client semble bon (à cause de mon traitement de WM_DPICHANGED
), mais parce que la virtualisation n'est plus assurée, il n'y a pas de mise à l'échelle de la zone non client. Le résultat est que le titre/la barre de légende et de la barre de menus sont de la bonne taille, ils ne sont plus sur la haute résolution de l'écran:
La question est donc, comment puis-je obtenir la non-zone client de la fenêtre à l'échelle de la nouvelle DPI?
Il n'a pas d'importance si vous créez votre propre classe de fenêtre ou utiliser une boîte de dialogue-ils ont un comportement identique à cet égard.
Il a été suggéré qu'il n'y est pas de réponse-que votre seul choix est de coutume de dessiner l'ensemble de la fenêtre, y compris les non-clients de la zone. Tout cela est certainement possible, et en effet ce UWP applications (celles précédemment connu sous le Métro), comme le Windows 10 Calculatrice, ce n'est pas une option viable pour les applications de bureau qui utilisent beaucoup de non-client de widgets et de l'espoir à regarder natif.
A côté de cela, il est manifestement fausse. Personnalisé tiré les barres de titre ne peut être la seule façon d'obtenir le bon comportement, depuis l'environnement Windows, qui équipe l'a fait. L'humble boîte de dialogue Exécuter, se comporte exactement comme prévu, correctement redimensionnement à la fois les clients et non-clients, comme vous le faites-le glisser entre les moniteurs avec différents inhalateurs de poudre sèche:
Enquête avec Spy++ confirme c'est juste une méga-standard Win32 dialogue-rien de compliqué. Tous les contrôles sont standard kit de développement Win32 SDK contrôles. Ce n'est pas un UWP application, ni ont-ils coutume dessinés à la barre de titre-qu'il a toujours le WS_CAPTION
style. Elle est lancée par l'explorer.exe processus, qui est marqué par le moniteur de haute résolution conscient (vérifié avec l'Explorateur de Processus et GetProcessDpiAwareness). Ce blog confirme que les deux la boîte de dialogue Exécuter et l'Invite de Commande ont été réécrits dans Windows 10 à l'échelle correctement (voir "interfaces de Commande et al."). Qu'est-ce que la boîte de dialogue Exécuter le faire pour redimensionner la barre de titre?
La Commune de Dialogue de l'Élément de l'API, responsable de de nouveaux Ouvrir et Enregistrer des boîtes de dialogue, s'adapte correctement lors du lancement d'un processus qui est par-moniteur de haute résolution conscient, comme vous pouvez le voir en cliquant sur le bouton "Parcourir" dans la boîte de dialogue Exécuter. Même chose pour la boîte de Dialogue de Tâche de l'API, de la création de l'étrange situation où une application lance une boîte de dialogue avec un autre-taille de la barre de titre. (L'héritage de l'API MessageBox n'a pas été mis à jour, cependant, et présente le même comportement que mon test app.)
Si la coque de l'équipe est de le faire, il doit être possible. Je ne peux pas imaginer que l'équipe responsable de la conception/mise en œuvre par le moniteur de DPI soutien négligé de fournir un moyen raisonnable pour les développeurs à produire des applications compatibles. Cela nécessite le support de développeur, ou qu'ils soient cassés out-of-the-box. Même les applications WPF sont brisés de Microsoft Par le Moniteur de Courant WPF Exemple de projet ne parvient pas à l'échelle de la zone non client, résultant dans une barre de titre qui est la bonne taille. Je ne suis pas beaucoup de théories du complot, mais ça sent un marketing déplacer pour décourager bureau de développement d'applications. Si oui, et il n'y a pas de manière officielle, je vais accepter les réponses qui s'appuient sur les sans-papiers comportement.
En parlant de sans-papiers, le comportement, la journalisation des messages de fenêtre lorsque la boîte de dialogue Exécuter est glissé entre les moniteurs avec différents paramètres PPP montre qu'il reçoit un sans-papiers message, 0x02E1
. C'est assez intéressant parce que ce message ID est exactement un de plus que le documentée WM_DPICHANGED
message (0x02E0
). Mon appli de test n'est jamais ce message, bien que, quel que soit son DPI-sensibilisation des paramètres. (Curieusement, à proximité de l'inspection révèle que Windows légèrement augmente la taille de la réduire/agrandir/fermer les glyphes sur la barre de titre de la fenêtre se déplace sur la haute résolution moniteur. Ils ne sont pas encore aussi grand que ils sont, quand ils sont virtualisés, mais ils sont un peu plus grands que les glyphes qu'il utilise pour la non mis à l'échelle du système des DPI applications).
Jusqu'à présent, mon idée a été de gérer l' WM_NCCALCSIZE
message pour ajuster la taille de la zone non client. En utilisant l' SWP_FRAMECHANGED
drapeau avec l' SetWindowPos
de la fonction, je peux forcer la fenêtre de redimensionner et de les redessiner sa non-espace client en réponse à l' WM_DPICHANGED
. Cela fonctionne bien pour réduire la hauteur de la barre de titre, ou même le supprimer tout à fait, mais il ne le fera jamais plus grand. La légende semble de pointe à la hauteur déterminée par le système de DPI. Même si elle a travaillé, ce ne serait pas la solution idéale, car il ne serait pas aider avec le système dessinés à la barre de menus ou barres de défilement...mais au moins, ça serait un début. D'autres idées?
* Je sais que cet article dit "on Remarque que la zone non client de l'une par moniteur–PPP au courant de l'application n'est pas mis à l'échelle par Windows, et apparaît proportionnellement plus petits sur une haute résolution d'affichage." Voir ci-dessus pour expliquer pourquoi c'est (1) mauvais et (2) insatisfaisant. Je suis à la recherche d'une solution autre que la coutume de dessin de la zone non client.