web-dev-qa-db-fra.com

Quelle police est la police par défaut pour les commandes de dialogue MFC?

L'image ci-dessous (agrandie pour mieux voir les différences) montre les différences de police entre les contrôles d'édition créés dynamiquement (les deux exemples supérieurs) et les contrôles d'édition créés à partir de l'éditeur de boîte de dialogue (l'exemple inférieur). Comment puis-je faire en sorte que la police de mes contrôles CEdit créés dynamiquement ressemble à celle par défaut (l'exemple du bas)?

enter image description here

J'ai créé les contrôles CEdit comme suit:

obj->CreateEx(WS_EX_CLIENTEDGE, _T("EDIT"), _T(""),
              WS_CHILD | WS_VISIBLE | WS_TABSTOP,
              rect.left, rect.top, rect.Width(), rect.Height(),
              GetSafeHwnd(), reinterpret_cast<HMENU>(mId));

obj->SetFont(&mFont); // mFont was created in the Dialog Constructor
                      // with mFont.CreatePointFont(80, _T("MS Shell Dlg"));

Merci de votre aide!

40
Christian Ammer

Le premier exemple utilise la police système (SYSTEM_FONT), comme récupéré avec la fonction GetStockObject , qui est une police bitmap qui n'a pas été utilisée depuis l'époque de Windows 3. Plus d'informations sont disponibles sur Raymond Blog de Chen , et blog de Michael Kaplan .

Le deuxième exemple utilise la police "MS Shell Dlg" , comme vous l'avez demandé. Cela correspond en fait à une police appelée "Microsoft Sans Serif" ou "MS Sans Serif", la police d'interface utilisateur à l'époque de Windows 95 et 98. Ceci est également connu sous le nom de DEFAULT_GUI_FONT, qui était en effet un nom exact pour lui, mais hélas, il n'est plus exact.

À partir de Windows 2000 (et continué sous XP), Tahoma a été utilisé comme police d'interface utilisateur par défaut. C'est ce que vous voyez dans le troisième exemple: Tahoma 8 pt. Malheureusement, même sur ces systèmes d'exploitation, "MS Shell Dlg" ne renvoie pas Tahoma - il renvoie toujours MS Sans Serif, c'est pourquoi il semble incorrect.

Donc, vous pouvez simplement spécifier Tahoma comme police GUI, mais ce ne serait pas vraiment correct, car cela se briserait dans les anciennes versions du système d'exploitation où Tahoma n'est pas installé ou pris en charge, ou sur les versions en langue étrangère du système d'exploitation, où une police différente est utilisée par nécessité. Au lieu de cela, vous êtes censé spécifier le DS_SHELLFONT flag, qui Raymond en parle ici .

Et tout allait bien jusqu'à ce que Windows Vista soit sorti. Et dans Windows Vista, les pouvoirs en place chez Microsoft ont décidé que Tahoma devenait un peu long et que Windows était dû pour ne autre mise à niveau de la police de l'interface utilisateur . Ils ont développé leur propre police spéciale appelée Segoe UI , censée être conçue pour une lisibilité optimale à l'écran. Et dans une petite torsion spéciale, ils ont décidé que la taille par défaut devrait maintenant être 9 pt , au lieu de 8 pt comme utilisé par toutes les versions précédentes du système d'exploitation , quelle que soit la police. Et vous penseriez probablement que "MS Shell Dlg", "MS Shell Dlg2" ou DS_SHELLFONT (ou les trois) vous procurerait cette nouvelle police d'interface utilisateur Segoe, mais vous auriez tort.

Euh oh. Maintenant, les choses deviennent délicates ... Non seulement Vista utilise une police différente de XP qui n'est pas facilement accessible avec un identifiant unique, mais il utilise également un autre taille , changeant la façon dont votre boîte de dialogue se penchera sur ces systèmes, si vous pouvez l’afficher. Dans de nombreux endroits, l’équipe Windows Shell est apparue pour simplement lancer le défi - Tahoma 8 pt est utilisé partout , même avec le thème Aero activé, quand il est censé utiliser Segoe UI 9 pt. Ce type de Cela fait vraiment que l'interface utilisateur n'est pas polie, et elle a fait l'objet de nombreuses piqûres au début de Vista. Maintenant, il semble que la plupart des gens l'aient oublié, mais l'interface utilisateur n'a pas commencé à paraître moins dispersée et incohérente.

Et vous n'êtes pas l'équipe Windows Shell: vous ne pouvez pas vous en sortir avec votre propre application. Les règles principales pour l'expérience utilisateur de Windows Vista indiquent même explicitement que vous devez toujours:

  • Utilisez Segoe UI, la nouvelle police système de Windows Vista.
  • Respectez les paramètres de l'utilisateur en faisant toujours référence à la police, aux tailles et aux couleurs du système à l'aide des API de thème Windows. N'utilisez pas de valeurs fixes pour les polices, les tailles ou les couleurs.

Pour être honnête, je n'ai pas encore vraiment entendu de bonne solution à ce problème. Et je soupçonne qu'au moment où je le ferai, personne n'aura plus besoin de prendre en charge Windows XP) (bien que la plupart des gens ne le soient pas tout à fait yet ). Mais voici ce que je fais: j'extrais la police système par défaut lors de l'exécution en utilisant la fonction SystemParametersInfo . Heureusement, le système la police de la boîte de message (lfMessageFont) correspond à la taille et à la taille de police appropriées, quelle que soit la version actuelle de Windows et le thème choisi par l'utilisateur.

Mon code pour initialiser des fenêtres ou des boîtes de dialogue ressemble généralement à ceci (SystemInfo::IsVistaOrLater est une fonction d'aide que j'ai écrite; l'implémentation est évidente):

// Get the system message box font
NONCLIENTMETRICS ncm;
ncm.cbSize = sizeof(ncm);

// If we're compiling with the Vista SDK or later, the NONCLIENTMETRICS struct
// will be the wrong size for previous versions, so we need to adjust it.
#if(_MSC_VER >= 1500 && WINVER >= 0x0600)
if (!SystemInfo::IsVistaOrLater())
{
    // In versions of Windows prior to Vista, the iPaddedBorderWidth member
    // is not present, so we need to subtract its size from cbSize.
    ncm.cbSize -= sizeof(ncm.iPaddedBorderWidth);
}
#endif

SystemParametersInfo(SPI_GETNONCLIENTMETRICS, ncm.cbSize, &ncm, 0);
HFONT hDlgFont = CreateFontIndirect(&(ncm.lfMessageFont));

// Set the dialog to use the system message box font
SetFont(m_DlgFont, TRUE);
SendMessage(hWnd, WM_SETFONT, (WPARAM)hDlgFont, MAKELPARAM(FALSE, 0));

Ou encore plus facile dans MFC, avec la méthode pratique SendMessageToDescendants
(m_DlgFont est un objet CFont défini pour la classe):

// Get the system message box font
NONCLIENTMETRICS ncm;
ncm.cbSize = sizeof(ncm);
SystemParametersInfo(SPI_GETNONCLIENTMETRICS, ncm.cbSize, &ncm, 0);
LOGFONT lfDlgFont = ncm.lfMessageFont;
m_DlgFont.CreateFontIndirect(&lfDlgFont);

// Set the dialog and all its controls to use the system message box font
SetFont(m_DlgFont, TRUE);
SendMessageToDescendants(WM_SETFONT, (WPARAM)m_DlgFont.m_hFont, MAKELPARAM(FALSE, 0), TRUE);

Si vous n'utilisez pas MFC, je vous recommande fortement d'implémenter votre propre version récursive de SendMessageToDescendants. Cela rend le code d'initialisation un lot plus simple.

84
Cody Gray