Partager via


Mixed-Mode mise à l’échelle ppp et API prenant en charge les PPP

Prise en charge de la sensibilisation aux ppp Sub-Process

SetThreadDpiAwarenessContext permet d’utiliser différents modes de mise à l’échelle PPP au sein d’un même processus. Avant la mise à jour anniversaire Windows 10, une détection ppp d’une fenêtre était liée au mode de prise en charge de la résolution à l’échelle du processus (ppp non pris en charge, prise en charge de la résolution système ou Per-Monitor prise en charge de la résolution). Mais maintenant, avec SetThreadDpiAwarenessContext, les fenêtres de niveau supérieur peuvent avoir un mode de sensibilisation PPP différent de celui du mode de sensibilisation ppp à l’échelle du processus. Cela affecte également les fenêtres enfants, car elles auront toujours le même mode de sensibilisation PPP que leur fenêtre parente.

L’utilisation de SetThreadDpiAwarenessContext permet aux développeurs de décider où ils souhaitent concentrer leurs efforts de développement lors de la définition d’un comportement spécifique aux ppp pour les applications de bureau. Par exemple, la fenêtre de niveau supérieur principale d’une application peut être mise à l’échelle par moniteur, tandis que les fenêtres de niveau supérieur secondaires peuvent être mises à l’échelle via une mise à l’échelle bitmap par le système d’exploitation.

Contexte de sensibilisation ppp

Avant la disponibilité de SetThreadDpiAwarenessContext , la prise en charge ppp d’un processus était définie dans le manifeste du fichier binaire de l’application ou via un appel à SetProcessDpiAwareness lors de l’initialisation du processus. Avec SetThreadDpiAwarenessContext, chaque thread peut avoir un contexte de sensibilisation ppp individuel qui peut être différent de celui du mode de sensibilisation ppp à l’échelle du processus. Le contexte de sensibilisation PPP d’un thread est représenté avec le type DPI_AWARENESS_CONTEXT et se comporte de la manière suivante :

  • Un thread peut avoir son contexte de reconnaissance PPP modifié à tout moment.
  • Tous les appels d’API effectués après la modification du contexte s’exécutent dans le contexte PPP correspondant (et peuvent être virtualisés).
  • Lorsqu’une fenêtre est créée, sa reconnaissance PPP est définie comme la reconnaissance PPP du thread appelant à ce moment-là.
  • Lorsque la procédure de fenêtre d’une fenêtre est appelée, le thread est automatiquement basculé vers le contexte de sensibilisation PPP utilisé lors de la création de la fenêtre.

Un scénario courant pour l’utilisation de SetThreadDpiAwarenessContext est le suivant : commencez par un thread qui s’exécute avec un seul contexte (par exemple , DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE) basculez temporairement vers un autre contexte (DPI_AWARENESS_CONTEXT_UNAWARE), créez une fenêtre, puis rétablissez immédiatement le contexte de thread à son état précédent. La fenêtre créée aura un contexte PPP de DPI_AWARENESS_CONTEXT_UNAWARE, tandis que le contexte du thread appelant sera restauré sur DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE avec un appel ultérieur à SetThreadDpiAwarenessContext. Dans ce scénario, la fenêtre associée au thread appelant s’exécuterait avec un contexte par moniteur (et ne serait donc pas étendue par le système d’exploitation) tandis que la fenêtre nouvellement créée ne serait pas prise en charge par ppp (et serait donc automatiquement étendue à une bitmap sur un ensemble d’affichage à une mise à l’échelle à >100 %).

La figure 1 illustre la façon dont le thread de processus main s’exécute avec DPI_AWARENESS_CONTEXT_PER_MONITOR, bascule son contexte en DPI_AWARENESS_CONTEXT_UNAWARE et crée une fenêtre. La fenêtre nouvellement créée s’exécute ensuite avec un contexte de sensibilisation PPP de DPI_AWARENESS_CONTEXT_UNAWARE chaque fois qu’un message lui est envoyé ou que des appels d’API sont effectués à partir de celui-ci. Immédiatement après la création de la fenêtre, le thread main est restauré dans son contexte précédent de DPI_AWARENESS_CONTEXT_PER_MONITOR.

diagramme montrant la prise de conscience des ppp par moniteur en action

En plus de la prise en charge de différents modes de reconnaissance ppp au sein d’un processus unique offert par SetThreadDpiAwarenessContext , les fonctionnalités spécifiques aux PPP suivantes ont été ajoutées pour les applications de bureau :

EnableNonClientDpiScaling

Notes

Le mode de sensibilisation Par moniteur V2 PPP active automatiquement cette fonctionnalité, et l’appel de EnableNonClientDpiScaling est donc inutile dans les applications qui l’utilisent.

L’appel de EnableNonClientDpiScaling à partir d’un gestionnaire de WM_NCCREATE de fenêtre entraîne la mise à l’échelle automatique de la zone non cliente d’une fenêtre de niveau supérieur pour ppp. Si la fenêtre de niveau supérieur prend en charge l’ppp par moniteur (que ce soit parce que le processus lui-même prend en charge la résolution par moniteur ou parce que la fenêtre a été créée dans un thread prenant en charge l’ppp par moniteur), la barre de légende, les barres de défilement, les menus et les barres de menus de ces fenêtres sont mis à l’échelle ppp chaque fois que la ppp de la fenêtre change.

Notez que les zones non clientes d’une fenêtre enfant, telles que les barres de défilement non client d’un contrôle d’édition enfant, ne sont pas automatiquement mises à l’échelle lorsque cette API est utilisée.

Notes

EnableNonClientDpiScaling doit être appelé à partir du gestionnaire de WM_NCCREATE .

API *ForDpi
  • Plusieurs API fréquemment utilisées, telles que GetSystemMetrics , n’ont aucun contexte d’un HWND et n’ont donc aucun moyen de déduire la prise de conscience ppp appropriée pour leurs valeurs de retour. L’appel de ces API à partir d’un thread qui s’exécute dans un autre mode ou contexte de sensibilisation PPP peut retourner des valeurs qui ne sont pas mises à l’échelle pour le contexte du thread appelant. GetSystemMetricForDpi, SystemParametersInfoForDpi et AdjustWindowRectExForDpi exécutent les mêmes fonctionnalités que leurs homologues ppp non conscients, mais prennent une ppp comme argument et déduisent la reconnaissance ppp du contexte du thread actuel.

  • GetSystemMetricForDpi et SystemParametersInfoForDpi retournent les valeurs de métriques système mises à l’échelle ppp et les valeurs de paramètres système conformément à cette équation :

    GetSystemMetrics(...) @ dpi == GetSystemMetricsForDpi(..., dpi)

    Par conséquent, l’appel de GetSystemMetrics (ou SystemParametersInfoForDpi), lors de l’exécution sur un appareil avec une certaine valeur PPP système, retourne la même valeur que leurs variantes prenant en charge la résolution des ppp (GetSystemMetricsForDpi et SystemParametersInfoForDpi), en fonction de la même valeur PPP que l’entrée.

  • AdjustWindowRectExForDpi prend un HWND et calcule la taille requise d’un rectangle de fenêtre de manière sensible aux ppp.

GetDpiForWindow
GetDpiForWindow retourne le ppp associé au HWND fourni. La réponse dépend du mode de sensibilisation ppp du HWND :
Mode de reconnaissance ppp de HWND Valeur retournée
Ignorer 96
Système Résolution du système
Per-Monitor Ppp de l’affichage sur lequel se trouve principalement la fenêtre de niveau supérieur associée
(Si une fenêtre enfant est fournie, la PPP de la fenêtre parente de niveau supérieur correspondante est retournée)
GetDpiForSystem

L’appel de GetDpiForSystem est plus efficace que d’appeler GetDC et GetDeviceCaps pour obtenir l’ppp système.

Tout composant qui pourrait s’exécuter dans une application qui utilise la prise de conscience ppp du sous-processus ne doit pas supposer que le ppp système est statique pendant le cycle de vie du processus. Par exemple, si un thread qui s’exécute sous DPI_AWARENESS_CONTEXT_UNAWARE contexte de sensibilisation interroge le DPI système, la réponse sera 96. Toutefois, si ce même thread bascule vers DPI_AWARENESS_CONTEXT_SYSTEM contexte de sensibilisation et interroge à nouveau le DPI système, la réponse peut être différente. Pour éviter l’utilisation d’une valeur de résolution système mise en cache (et éventuellement périmée), utilisez GetDpiForSystem pour récupérer la pppure système par rapport au mode de reconnaissance ppp du thread appelant.