Pergunta

Eu estou tentando determinar como eu pode detectar quando o usuário altera o tamanho do Windows Font de Normal para fontes grandes extra, o tamanho da fonte é selecionada por executar as seguintes etapas em uma máquina Windows XP:

  1. Clique com o botão direito do mouse na área de trabalho e selecione Propriedades.
  2. Clique na guia Aparência.
  3. Selecione o tamanho da fonte: Normal / fontes grandes / grandes fontes extra

O meu entendimento é que a mudança resultados tamanho da fonte em uma mudança DPI, então aqui está o que eu tentei até agora.


My Goal:

Eu quero detectar quando o Tamanho Windows Font mudou de normal para grandes ou extra fontes grandes e tomar algumas ações com base nessa alteração tamanho da fonte. Suponho que quando o Size do Windows Font alterações, o DPI também vai mudar (especialmente quando o tamanho é fontes grandes extra


O que eu tentei até agora:

Eu recebo várias mensagens, incluindo: WM_SETTINGCHANGE, WM_NCCALCSIZE, WM_NCPAINT, etc ... mas nenhuma dessas mensagens são exclusivas para a situação quando as mudanças de tamanho de fonte, em outras palavras, quando eu receber a mensagem WM_SETTINGSCHANGE Eu quero saber o que alterado.

Em teoria, quando eu definir o OnSettingChange e Windows chama, o lpszSection deveria me dizer o que a seção de mudança é, e que funciona bem, mas então eu verifique a seção dada chamando SystemParametersInfo e eu passar nos SPI_GETNONCLIENTMETRICS ação, e Eu passo através do depurador e eu ter certeza de que eu assisto os dados nos NONCLIENTMETRICS devolvido por qualquer mudanças de fontes, mas nenhum ocorrer.

Mesmo que não funcionou, eu ainda deve ser capaz de verificar o DPI quando a alterar as configurações. Eu realmente não se preocupam com os outros detalhes, toda vez que recebo a mensagem WM_SETTINGCHANGE, gostaria apenas de verificar o DPI e executar as ações que eu estou interessado em fazer, mas eu não sou capaz de conseguir o sistema de DPI também.

Eu tentei obter o DPI, invocando os GetSystemMetrics método, também para cada DC:

Dekstop DC-> GetDeviceCaps LOGPIXELSX / LOGPIXELSY Janela DC-> GetDeviceCaps LOGPIXELSX / LOGPIXELSY Atual DC-> GetDeviceCaps LOGPIXELSX / LOGPIXELSY

Mesmo se eu mudar o DPI na Propriedades janela gráfica esses valores não retornam nada diferente, eles sempre mostram 96.

Alguém poderia me ajudar a descobrir isso por favor? O que devo estar procurando? Onde eu deveria estar olhando?

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

O DPI sempre retorna 96, mas as alterações nas configurações do Efeito tomada quando eu mudar o tamanho da fonte para fontes grandes extra ou se eu mudar o DPI a 120 (a partir das propriedades gráficas).

Foi útil?

Solução

[EDIT após a re-leitura] Tenho quase certeza de que mudar para "fontes grandes" não causar uma mudança DPI, mas sim é um cenário tema. Você deve ser capaz de verificar, aplicando a "fontes grandes" mudanças e, em seguida, abrir as propriedades avançadas de exibição, onde as vidas configuração de dpi, deveria ter permanecido em 96dpi.


mudança DPI é suposto que requerem uma reinicialização. Talvez a definição não tem propagado a um lugar onde GetDeviceCaps pode recuperá-lo?

Talvez tente mudar uma configuração sem exigindo reinicialização (resolução talvez) e, em seguida, veja se você pode detectar a mudança. Se você puder, a sua resposta é provavelmente que você não pode detectar a mudança DPI até após a reinicialização.

Outras dicas

Quando você chamar GetDeviceCaps () na área de trabalho DC, talvez você está usando um DC que pode ser armazenada em cache pelo MFC e, portanto, contém informações out-of-date? Você está fazendo as GetDeviceCaps () chamada síncrona de dentro de seu manipulador OnSettingsChange? Eu podia ver como uma ou ambas essas coisas você pode obter um fora da versão data de DPI.

Raymond Chen escreveu sobre este e sua solução olhou como este (Observe que eu adicionei :: operadores para evitar chamar os invólucros MFC das APIs):

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

Eu tenho um palpite WM_THEMECHANGED vai cuidar de você. Ele não tem qualquer insinuando sobre o que mudou, no entanto. Você terá que usar OpenThemeData e cache de configurações iniciais, e depois comparar cada vez que você receber a mensagem.

Você provavelmente não precisa se preocupar o que mudou, porém, você não pode ter uma rotina esquema de uso geral que ajusta seu formulário / diálogo / whatever, tendo tudo em conta e assume começando do zero?

Que problema você está tentando resolver?

http://msdn.microsoft.com /en-us/library/ms701681(VS.85).aspx , isso é explicado lá (citação: "Se você não cancelar dpi escala, esta chamada retorna o valor padrão de 96 dpi.")

Eu não acho que a exibição DPI muda quando o tamanho da fonte muda. Windows está provavelmente apenas o envio de mensagens WM_PAINT e WM_NCPAINT para todas as janelas abertas, e eles estão redesenhando-se usando o atual (agora grande) fonte do sistema.

Olhe para estes valores no Registro:

Windows XP Tema HKCU \ Software \ Microsoft \ Windows \ CurrentVersion \ ThemeManager \ SizeName Valores possíveis: normalsize, LargeFonts e ExtraLargeFonts Estes valores são linguagem independente .

Windows Classic Tema HKCU \ Control Panel \ Appearance \ Current Valores possíveis: Clássico do Windows, o Windows Clássico (grande), Windows Clássico (extra grande), padrão do Windows, o Windows padrão (grande), padrão do Windows (extra grande) Note-se que estes valores são dependentes do idioma .

Windows Vista não suporta este recurso. Se queremos uma fonte maior, basta alterar a configuração de dpi. Nesse caso, GetDeviceCaps deve funcionar.

Espero que isso ajude.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top