Erreur de coordonnée lors de l’utilisation de GetWindowRect dans différents DPI

Je souhaite capturer les coordonnées des composants de mon programme MFC.

Maintenant, je peux parfaitement le faire en utilisant GetWindowRect . Toutefois, lorsque je règle mon dpi Windows à 150% (120 dpi), GetWindowRect des coordonnées différentes.

Par conséquent, j’étudie une méthode permettant de convertir les nouvelles coordonnées en coordonnées par défaut (96 dpi).

Finalement, j’ai trouvé une erreur lorsque j’ai essayé:

 Rect.top = Rect.top * (DEFAULT_DPIY / CURRENT_DPIY); Rect.left = Rect.left * (DEFAULT_DPIX / CURRENT_DPIX); 

La valeur convertie est très proche, mais pas égale.

Existe-t-il une méthode pour le convertir sans erreur?

Votre programme est soumis à la virtualisation DPI. La bonne façon de régler ce problème est de sensibiliser votre programme à la DPI élevée, mais cela peut impliquer plus de changements que vous ne le souhaitez.

Si vous ne souhaitez pas vous soucier de la haute résolution, vous pouvez au moins améliorer votre calcul. Votre code utilise une division entière. Mais cela va être inexact. Afin de minimiser cette imprécision, vous devez effectuer la division après la multiplication:

 Rect.top = (Rect.top * DEFAULT_DPIY) / CURRENT_DPIY; Rect.left = (Rect.left * DEFAULT_DPIX) / CURRENT_DPIX; 

Bien sûr, les parenthèses pourraient être omises ici sans en changer le sens, mais je pense qu’il est agréable d’être explicite sur l’ordre des opérations dans ce cas.

Une autre option serait d’utiliser MulDiv :

 Rect.top = MulDiv(Rect.top, DEFAULT_DPIY, CURRENT_DPIY); Rect.left = MulDiv(Rect.left, DEFAULT_DPIX, CURRENT_DPIX);