Qual fonte é o padrão para controles de checkbox de diálogo MFC?

A figura abaixo (ampliada, então é melhor você ver as diferenças) mostra as diferenças de fonte entre os controles de edição criados dinamicamente (os dois exemplos superiores) e os controles de edição criados no Editor de diálogo (o exemplo inferior). Como posso fazer com que a fonte dos meus controles do CEdit criados dinamicamente pareçam com o padrão (o menor exemplo)?

insira a descrição da imagem aqui

Eu criei os controles de CEdit como seguindo:

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(mId)); obj->SetFont(&mFont); // mFont was created in the Dialog Constructor // with mFont.CreatePointFont(80, _T("MS Shell Dlg")); 

Obrigado pela ajuda!

O primeiro exemplo é usar a fonte System ( SYSTEM_FONT ), conforme recuperada com a function GetStockObject , que é uma fonte de bitmap que não foi usada desde os dias do Windows 3. Mais informações estão disponíveis no blog de Raymond Chen e no blog de Michael Kaplan .

O segundo exemplo é usar a fonte “MS Shell Dlg” , assim como você pediu. Isso realmente mapeia para uma fonte chamada “Microsoft Sans Serif” ou “MS Sans Serif”, a fonte da interface do usuário nos dias de Windows 95 e 98. Isso também é conhecido como DEFAULT_GUI_FONT , que na verdade costumava ser um nome preciso para ele, mas, infelizmente, não é mais preciso.

A partir do Windows 2000 (e continuado no XP), o Tahoma foi usado como fonte de interface do usuário padrão. Isto é o que você está vendo no terceiro exemplo: Tahoma 8 pt. Infelizmente, mesmo nesses sistemas operacionais, “MS Shell Dlg” não retorna Tahoma – ele ainda retorna MS Sans Serif, e é por isso que parece errado.

Assim, você poderia simplesmente especificar Tahoma como a fonte da GUI, mas isso não seria realmente correto, porque iria quebrar versões mais antigas do sistema operacional onde Tahoma não está instalado ou suportado, ou em versões de idioma estrangeiro do sistema operacional, onde uma fonte diferente é usada por necessidade. Em vez disso, você deve especificar o sinalizador DS_SHELLFONT , sobre o qual Raymond fala aqui .

E tudo estava bem e bem até que o Windows Vista saiu. E no Windows Vista, os poderes da Microsoft decidiram que a Tahoma estava ficando um pouco extensa e que o Windows estava pronto para outra atualização de fonte da interface do usuário . Eles desenvolveram sua própria fonte especial chamada Segoe UI , supostamente projetada para melhor legibilidade na canvas. E em uma pequena reviravolta especial, eles decidiram que o tamanho padrão agora deveria ser 9 pt , em vez de 8 pt, como usado por todas as versões anteriores do sistema operacional, independentemente da face da fonte. E você provavelmente pensaria que tanto “MS Shell Dlg”, “MS Shell Dlg2”, ou DS_SHELLFONT (ou todos os três) lhe dariam essa nova fonte Segoe UI, mas você estaria errado.

Uh oh. Agora as coisas ficam complicadas … O Vista não apenas usa uma fonte diferente do XP que não é facilmente acessível com um identificador de tamanho único, mas também usa um tamanho diferente, mudando a aparência da checkbox de diálogo naqueles. sistemas, se você conseguir que ele seja exibido. Em muitos, muitos lugares, a equipe de shell do Windows pareceu simplesmente chutar o desafio – Tahoma 8 pt é usado em todo o lugar , mesmo com o tema Aero habilitado, quando deveria estar usando o Segoe UI 9 pt. Esse tipo de coisa realmente faz com que a interface do usuário pareça não polida, e foi o assunto de muitas críticas nos primeiros dias do Vista. Agora, parece que a maioria das pessoas esqueceu, mas a interface não começou a parecer menos dispersa e inconsistente.

E você não é a equipe de shell do Windows: você não pode se dar bem com isso em seu próprio aplicativo. As principais regras para a experiência do usuário do Windows Vista também indicam explicitamente que você deve sempre:

  • Use o Segoe UI, a nova fonte do sistema Windows Vista.
  • Respeite as configurações do usuário sempre fazendo referência à fonte, aos tamanhos e às colors do sistema usando as APIs de temas do Windows. Não use valores fixos para fonts, tamanhos ou colors.

Para ser honesto, ainda não ouvi uma boa solução para esse problema. E eu suspeito que, quando eu fizer isso, ninguém precisará mais suportar o Windows XP (embora a maioria das pessoas ainda não esteja lá). Mas aqui está o que eu faço: eu extraio a fonte padrão do sistema em tempo de execução usando a function SystemParametersInfo . Felizmente, a fonte da checkbox de mensagens do sistema ( lfMessageFont ) é a face e o tamanho corretos da fonte, independentemente da versão atual do Windows e do tema escolhido pelo usuário.

Meu código para inicializar janelas ou diálogos geralmente é parecido com isto ( SystemInfo::IsVistaOrLater é uma function auxiliar que eu escrevi; a implementação é a óbvia):

 // 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 ainda mais fácil no MFC, com o prático método SendMessageToDescendants
( m_DlgFont é um object CFont definido para a class):

 // 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); 

Se você não estiver usando o MFC, é altamente recomendável implementar sua própria versão recursiva de SendMessageToDescendants . Isso torna o código de boot muito mais simples.