11 votes

GetSystemMetrics() renvoie une valeur erronée pour SM_CXSCREEN

J'ai rencontré un problème intéressant. Au moins sous Vista, getSystemMetrics(SM_CXSCREEN) renvoie une valeur incorrecte lorsque les paramètres DPI du bureau ne sont pas définis à 100%. Par exemple, j'ai essayé 150% dans un écran 1366x768 et getSystemMetrics() renvoie 911 au lieu de 1366 (et 1366 / 1.5 ~ 911)

Selon le MSDN, getSystemMetrics(SM_CXSCREEN) renvoie des pixels, je pensais donc que cette valeur ne serait pas affectée par les paramètres DPI - mais c'est le cas. Existe-t-il donc un moyen plus sûr de connaître la véritable résolution de l'écran, non mise à l'échelle ?

11voto

Hans Passant Points 475940

Un programme doit indiquer au système d'exploitation qu'il tient compte de la DPI pour obtenir la résolution réelle lorsque vous dépassez 125 %. La meilleure façon de le faire est d'utiliser un manifeste, comme expliqué dans ce document. Article de la bibliothèque MSDN .

6voto

Asad Khan Points 21

Pour que votre application soit consciente des dpi, créez un fichier manifeste et mettez-y le texte suivant.

<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3" >
  <asmv3:application>
    <asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
      <dpiAware>true</dpiAware>
    </asmv3:windowsSettings>
  </asmv3:application>
</assembly>

2voto

Toby Sharp Points 321

Avant d'obtenir la mesure correcte des pixels à l'aide de fonctions comme GetSystemMetrics ou GetClientRect, votre application doit déclarer au système d'exploitation qu'elle connaît la DPI et qu'elle ne va donc pas tout gâcher.

Plusieurs changements ont été apportés à la façon dont cette recommandation est faite. Consultez les documents MSDN pour plus de détails.

À partir de Windows 10 :

::SetThreadDpiAwarenessContext(DPI_AWARENESS_CONTEXT_SYSTEM_AWARE);

Ou à partir de Windows 8.1 :

::SetProcessDpiAwareness(DPI_AWARENESS_CONTEXT_SYSTEM_AWARE);

Ou à partir de Vista :

::SetProcessDPIAware();

Après avoir appelé cette fonction, la fonction GetSystemMetrics etc. devrait renvoyer à votre application les valeurs correctes en pixels.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X