Question

J'essaie de déterminer comment détecter si l'utilisateur modifie la taille de police Windows de police normale à très grande, la taille de la police est sélectionnée en exécutant les étapes suivantes sur un ordinateur Windows XP:

  1. Cliquez avec le bouton droit sur le bureau et sélectionnez Propriétés.
  2. Cliquez sur l'onglet Apparence.
  3. Sélectionnez la taille de la police: Normal / Grandes polices / Très grandes polices

D'après ce que j'ai compris, la modification de la taille de la police entraîne une modification de la résolution, voici donc ce que j'ai déjà essayé.

Mon objectif:

Je souhaite détecter lorsque la taille de police Windows est passée de polices normales à grandes ou très grandes et effectuer certaines actions en fonction de ce changement de taille. Je suppose que lorsque la taille de police Windows change, le DPI change également (en particulier lorsque la taille est Extra Large Fonts

Ce que j'ai essayé jusqu'à présent:

Je reçois plusieurs messages, notamment: WM_SETTINGCHANGE, WM_NCCALCSIZE, WM_NCPAINT, etc., mais aucun de ces messages n'est spécifique à la situation dans laquelle la taille de la police change. En d'autres termes, lorsque je reçois le message WM_SETTINGSCHANGE, je souhaite savoir quoi. changé.

En théorie, lorsque je définis le paramètre OnSettingChange et que Windows l’appelle, la section lpsz doit me dire quelle est la section en cours de modification. Cela fonctionne bien, puis je vérifie la section donnée en appelant SystemParametersInfo et je passe dans l’action SPI_GETNONCLIENTMETRICS. Je passe en revue le débogueur et je m'assure de regarder les données dans le message NONCLIENTMETRICS renvoyé pour tout changement de police, mais aucun ne se produit.

Même si cela ne fonctionnait pas, je devrais quand même pouvoir vérifier le DPI lorsque les paramètres changent. Les autres détails ne me dérangeraient vraiment pas. Chaque fois que je recevais le message WM_SETTINGTINGCHANGE, je vérifiais simplement le DPI et effectuais les actions qui m'intéressaient, mais je ne pouvais pas obtenir le DPI du système non plus.

J'ai essayé d'obtenir le DPI en appelant la méthode GetSystemMetrics, également pour chaque contrôleur de domaine:

Dekstop DC - > GetDeviceCaps LOGPIXELSX / LOGPIXELSY Fenêtre DC- > GetDeviceCaps LOGPIXELSX / LOGPIXELSY DC actuel > GetDeviceCaps LOGPIXELSX / LOGPIXELSY

Même si je change le DPI dans la fenêtre des propriétés graphiques, ces valeurs ne renvoient rien de différent, elles affichent toujours 96.

Quelqu'un pourrait-il m'aider à comprendre cela s'il vous plaît? Que devrais-je rechercher? Où devrais-je regarder?

afx_msg void CMainFrame::OnSettingChange(UINT uFlags, LPCTSTR lpszSection)
{
    int windowDPI = 0;
    int deviceDPI = 0;
    int systemDPI = 0;
    int desktopDPI = 0;
    int dpi_00_X = 0;
    int dpi_01_X = 0;
    int dpi_02_X = 0;
    int dpi_03_X = 0;

    CDC* windowDC = CWnd::GetWindowDC(); // try with window DC
    HDC desktop = ::GetDC(NULL); // try with desktop DC
    CDC* device = CWnd::GetDC(); // try with current DC
    HDC hDC = *device; // try with HDC
    if( windowDC )
    {
        windowDPI = windowDC->GetDeviceCaps(LOGPIXELSY); 
        // always 96 regardless if I change the Font 
        // Size to Extra Large Fonts or keep it at Normal

        dpi_00_X = windowDC->GetDeviceCaps(LOGPIXELSX); // 96
    }

    if( desktop )
    {
        desktopDPI = ::GetDeviceCaps(desktop, LOGPIXELSY); // 96
        dpi_01_X = ::GetDeviceCaps(desktop, LOGPIXELSX); // 96
    }

    if( device )
    {
        deviceDPI = device->GetDeviceCaps(LOGPIXELSY); // 96
        dpi_02_X = device->GetDeviceCaps(LOGPIXELSX); // 96
    }

    systemDPI = ::GetDeviceCaps(hDC, LOGPIXELSY); // 96
    dpi_03_X = ::GetDeviceCaps(hDC, LOGPIXELSX); // 96

    CWnd::ReleaseDC(device);
    CWnd::ReleaseDC(windowDC);
    ::ReleaseDC(NULL, desktop);
    ::ReleaseDC(NULL, hDC);

    CWnd::OnWinSettingChange(uFlags, lpszSection);
}

Le DPI renvoie toujours 96, mais les modifications apportées aux paramètres NE prennent effet que lorsque je modifie la taille de la police en Très grandes polices ou si je modifie le DPI en 120 (à partir des propriétés graphiques).

Était-ce utile?

La solution

[MODIFIER après avoir relu] Je suis presque sûr que le passage à "Grandes polices" ne provoque pas de changement de DPI, mais un paramètre de thème. Vous devriez pouvoir vérifier en appliquant les "Grandes polices". changez, puis ouvrez les propriétés d'affichage avancées où réside le paramètre DPI, il aurait dû rester à 96 dpi.


Le changement DPI est supposé nécessiter un redémarrage. Peut-être que le paramètre n'a pas été propagé à un endroit où GetDeviceCaps peut le récupérer?

Essayez peut-être de modifier un paramètre (ne nécessitant pas de redémarrage) (résolution, par exemple), puis voyez si vous pouvez détecter le changement. Si vous le pouvez, votre réponse est probablement que vous ne pouvez pas détecter le changement de DPI avant le redémarrage.

Autres conseils

Lorsque vous appelez GetDeviceCaps () sur le contrôleur de domaine Desktop, utilisez-vous peut-être un contrôleur de domaine pouvant être mis en cache par MFC et contenant par conséquent des informations obsolètes? Effectuez-vous l'appel GetDeviceCaps () de manière synchrone à partir de votre gestionnaire OnSettingsChange? Je pouvais voir comment l'une ou l'autre de ces choses, ou les deux, pourraient vous donner une version obsolète de DPI.

Raymond Chen a écrit à ce sujet et son La solution ressemblait à ceci (Notez que j'ai ajouté :: operators pour éviter d'appeler les wrappers MFC des API):

int GetScreenDPI()
{
  HDC hdcScreen = ::GetDC(NULL);
  int iDPI = -1; // assume failure
  if (hdcScreen) {
    iDPI = ::GetDeviceCaps(hdcScreen, LOGPIXELSX);
    ::ReleaseDC(NULL, hdcScreen);
  }
  return iDPI;
}

J'ai l'impression que WM_THEMECHANGED prendra soin de vous. Il ne fait aucune allusion à ce qui a changé, cependant. Vous devrez utiliser OpenThemeData et mettre en cache les paramètres initiaux, puis comparer chaque fois que vous recevez le message.

Vous n'avez probablement pas besoin de vous soucier de ce qui a changé, ne pouvez-vous pas avoir une routine de mise en page polyvalente qui ajuste votre formulaire / boîte de dialogue / quoi que ce soit en prenant tout en compte et en partant de zéro?

Quel problème essayez-vous de résoudre?

Voir http://msdn.microsoft.com /en-us/library/ms701681(VS.85).aspx , cela est expliqué ici (citation: "Si vous n'annulez pas la mise à l'échelle dpi, cet appel renvoie la valeur par défaut de 96 dpi.")

Je ne pense pas que le DPI d'affichage change lorsque la taille de la police change. Windows envoie probablement les messages WM_PAINT et WM_NCPAINT à toutes les fenêtres ouvertes, et ils se redessinent à l'aide de la police système (maintenant grande) actuelle.

Regardez ces valeurs dans le registre:

Thème Windows XP HKCU \ Software \ Microsoft \ Windows \ CurrentVersion \ ThemeManager \ SizeName Valeurs possibles: NormalSize, LargeFonts et ExtraLargeFonts Ces valeurs sont indépendantes de la langue .

Thème Windows Classic HKCU \ Panneau de configuration \ Apparence \ Actuel Valeurs possibles: Windows Classic, Windows Classic (grand), Windows Classic (très grand), Windows Standard, Windows Standard (grand), Windows Standard (très grand) Notez que ces valeurs dépendent de langue .

Windows Vista ne prend pas en charge cette fonctionnalité. Si nous voulons une police plus grande, changez simplement le paramètre DPI. Dans ce cas, GetDeviceCaps devrait fonctionner.

J'espère que cela vous aidera.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top