Desenvolvimento de aplicativos de área de trabalho de alta DPI no Windows

Esse conteúdo é direcionado para desenvolvedores que estão procurando atualizar aplicativos da área de trabalho para lidar com alterações de fator de escala de exibição (pontos por polegada ou DPI) dinamicamente, permitindo que seus aplicativos sejam nítidos em qualquer exibição em que sejam renderizados.

Para começar, se você estiver criando um novo aplicativo Windows do zero, é altamente recomendável que você crie um aplicativo UWP (Plataforma Universal do Windows). Os aplicativos UWP são dimensionados automaticamente e dinamicamente para cada exibição em que estão sendo executados.

Aplicativos de área de trabalho usando tecnologias de programação Windows mais antigas (programação bruta do Win32, Windows Forms, WPF (Estrutura de Apresentação Windows), etc.) não é possível lidar automaticamente com o dimensionamento de DPI sem trabalho adicional do desenvolvedor. Sem esse trabalho, os aplicativos aparecerão desfocados ou de tamanho incorreto em muitos cenários de uso comuns. Este documento fornece contexto e informações sobre o que está envolvido na atualização de um aplicativo da área de trabalho para renderizar corretamente.

DPI do Fator & de Escala de Exibição

À medida que a tecnologia de exibição progrediu, os fabricantes de painéis de exibição empacotaram um número crescente de pixels em cada unidade de espaço físico em seus painéis. Isso fez com que os pontos por polegada (DPI) dos painéis de exibição modernos fossem muito maiores do que historicamente. No passado, a maioria das exibições tinha 96 pixels por polegada linear de espaço físico (96 DPI); em 2017, as exibições com quase 300 DPI ou superior estão prontamente disponíveis.

A maioria das estruturas de interface do usuário da área de trabalho herdada tem suposições internas de que a DPI de exibição não será alterada durante o tempo de vida do processo. Essa suposição não é mais verdadeira, com DPIs de exibição normalmente mudando várias vezes durante o tempo de vida de um processo de aplicativo. Alguns cenários comuns em que o fator de escala de exibição/DPI é alterado:

  • Configurações de vários monitores em que cada exibição tem um fator de escala diferente e o aplicativo é movido de uma exibição para outra (como uma exibição de 4K e 1080p)
  • Encaixando e desencaixando um laptop DPI alto com uma exibição externa de baixa DPI (ou vice-versa)
  • Conectando-se via Área de Trabalho Remota de um laptop/tablet DPI alto a um dispositivo de baixa DPI (ou vice-versa)
  • Fazer com que as configurações de fator de escala de exibição sejam alteradas enquanto os aplicativos estão em execução

Nesses cenários, os aplicativos UWP são redesenhados automaticamente para o novo DPI. Por padrão, e sem trabalho adicional do desenvolvedor, os aplicativos da área de trabalho não. Aplicativos de área de trabalho que não fazem esse trabalho extra para responder a alterações de DPI podem parecer desfocados ou de tamanho incorreto para o usuário.

Modo de Reconhecimento de DPI

Os aplicativos da área de trabalho devem informar Windows se dão suporte ao dimensionamento de DPI. Por padrão, o sistema considera os aplicativos de área de trabalho DPI sem conhecimento e o bitmap alonga suas janelas. Ao definir um dos seguintes modos de conscientização de DPI disponíveis, os aplicativos podem informar explicitamente Windows como desejam lidar com o dimensionamento de DPI:

DPI sem conhecimento

Aplicativos sem conhecimento de DPI são renderizados com um valor de DPI fixo de 96 (100%). Sempre que esses aplicativos forem executados em uma tela com uma escala de exibição maior que 96 DPI, Windows estenderá o bitmap do aplicativo para o tamanho físico esperado. Isso faz com que o aplicativo apareça desfocado.

Reconhecimento de DPI do Sistema

Os aplicativos de área de trabalho que têm reconhecimento de DPI do sistema normalmente recebem o DPI do monitor conectado primário a partir do momento da entrada do usuário. Durante a inicialização, eles dispõem sua interface do usuário adequadamente (controles de dimensionamento, escolhendo tamanhos de fonte, ativos de carregamento etc.) usando esse valor de DPI do Sistema. Assim, os aplicativos com reconhecimento de DPI do sistema não são dimensionados por DPI (bitmap estendido) por Windows em exibições renderizadas nesse único DPI. Quando o aplicativo é movido para uma exibição com um fator de escala diferente ou se o fator de escala de exibição mudar de outra forma, Windows dimensionará as janelas do aplicativo, fazendo com que elas pareçam desfocadas. Efetivamente, os aplicativos de área de trabalho com reconhecimento de DPI do Sistema só são renderizados de forma nítida em um único fator de escala de exibição, ficando desfocados sempre que o DPI for alterado.

Reconhecimento de DPI de Per-Monitor e Per-Monitor (V2)

É recomendável que os aplicativos da área de trabalho sejam atualizados para usar o modo de reconhecimento de DPI por monitor, permitindo que eles sejam renderizados imediatamente corretamente sempre que o DPI for alterado. Quando um aplicativo relata a Windows que deseja executar nesse modo, Windows não fará o bitmap esticar o aplicativo quando o DPI for alterado, em vez de enviar WM_DPICHANGED para a janela do aplicativo. Em seguida, é responsabilidade total do aplicativo lidar com o redimensionamento para a nova DPI. A maioria das estruturas de interface do usuário usadas por aplicativos da área de trabalho (Windows controles comuns (comctl32), Windows Forms, Windows Presentation Framework etc.) não dão suporte ao dimensionamento automático de DPI, exigindo que os desenvolvedores redimensionem e reposicionem o conteúdo de suas próprias janelas.

Há duas versões de Per-Monitor reconhecimento de que um aplicativo pode se registrar como: versão 1 e versão 2 (PMv2). Registrar um processo como em execução no modo de conscientização PMv2 resulta em:

  1. O aplicativo que está sendo notificado quando a DPI é alterada (os HWNDs de nível superior e filho)
  2. O aplicativo que está vendo os pixels brutos de cada exibição
  3. O aplicativo nunca está sendo dimensionado por bitmap por Windows
  4. Área não cliente automática (legenda da janela, barras de rolagem etc.) Dimensionamento de DPI Windows
  5. As caixas de diálogo Win32 (do CreateDialog) são dimensionadas automaticamente por Windows
  6. Ativos de bitmap desenhados por tema em controles comuns (caixas de seleção, planos de fundo de botão etc.) sendo renderizados automaticamente no fator de escala de DPI apropriado

Ao serem executados no modo de reconhecimento do Per-Monitor v2, os aplicativos são notificados quando sua DPI é alterada. Se um aplicativo não se redimensionar para a nova DPI, a interface do usuário do aplicativo aparecerá muito pequena ou muito grande (dependendo da diferença nos valores de DPI anteriores e novos).

Observação

Per-Monitor reconhecimento de V1 (PMv1) é muito limitado. É recomendável que os aplicativos usem PMv2.

A tabela a seguir mostra como os aplicativos serão renderizados em cenários diferentes:

Modo de Reconhecimento de DPI versão Windows introduzida Exibição de DPI do aplicativo Comportamento na alteração do DPI
Inconscientes N/D Todas as exibições são 96 DPI Alongamento de bitmap (desfocado)
Sistema Vista Todas as exibições têm a mesma DPI (o DPI da exibição primária no momento em que a sessão do usuário atual foi iniciada) Alongamento de bitmap (desfocado)
Per-Monitor 8.1 O DPI da exibição na qual a janela do aplicativo está localizada principalmente
  • HWND de nível superior é notificado de alteração de DPI
  • Nenhuma escala de DPI de nenhum elemento de interface do usuário.

Per-Monitor V2 Atualização do Windows 10 para Criadores (1703) O DPI da exibição na qual a janela do aplicativo está localizada principalmente
  • HWNDs de nível superior e filho são notificados de alteração de DPI

Dimensionamento automático de DPI de:
  • Área não cliente
  • Bitmaps desenhados por tema em controles comuns (comctl32 V6)
  • Caixas de diálogo (CreateDialog)

Reconhecimento de DPI por monitor (V1)

Per-Monitor modo de reconhecimento de DPI V1 (PMv1) foi introduzido com Windows 8.1. Esse modo de conscientização de DPI é muito limitado e oferece apenas a funcionalidade listada abaixo. É recomendável que os aplicativos da área de trabalho usem Per-Monitor modo de reconhecimento v2, com suporte no Windows 10 1703 ou superior.

O suporte inicial para reconhecimento por monitor só oferecia aos aplicativos o seguinte:

  1. HWNDs de nível superior são notificados de uma alteração de DPI e fornecidos um novo tamanho sugerido
  2. Windows não aumentará o bitmap da interface do usuário do aplicativo
  3. O aplicativo vê todas as exibições em pixels físicos (consulte virtualização)

No Windows 10 1607 ou superior, os aplicativos PMv1 também podem chamar EnableNonClientDpiScaling durante WM_NCCREATE para solicitar que Windows dimensione corretamente a área não cliente da janela.

Suporte ao dimensionamento de DPI por monitor pela UI Framework/Technology

A tabela abaixo mostra o nível de suporte de reconhecimento de DPI por monitor oferecido por várias estruturas de interface do usuário Windows a partir de Windows 10 1703:

Estrutura/Tecnologia Suporte Versão do SO Dimensionamento de DPI manipulado por Leitura Adicional
Plataforma Universal do Windows (UWP) Completo 1607 Estrutura de interface do usuário UWP (Plataforma Universal do Windows)
Raw Win32/Common Controls V6 (comctl32.dll)
  • Mensagens de notificação de alteração de DPI enviadas para todos os HWNDs
  • Os ativos desenhados pelo tema são renderizados corretamente em controles comuns
  • Dimensionamento automático de DPI para caixas de diálogo
1703 Aplicativo exemplo de GitHub
Windows Forms Dimensionamento limitado de DPI por monitor para alguns controles 1703 Estrutura de interface do usuário Alto suporte a DPI no Windows Forms
Windows Presentation Framework (WPF) Os aplicativos nativos do WPF dimensionarão o WPF hospedado em outras estruturas e outras estruturas hospedadas no WPF não serão dimensionadas automaticamente 1607 Estrutura de interface do usuário exemplo de GitHub
GDI Nenhum N/D Aplicativo Consulte o dimensionamento de GDI High-DPI
GDI+ Nenhum N/D Aplicativo Consulte o dimensionamento de GDI High-DPI
MFC Nenhum N/D Aplicativo N/D

Atualizando aplicativos existentes

Para atualizar um aplicativo de área de trabalho existente para lidar corretamente com o dimensionamento de DPI, ele precisa ser atualizado de modo que, no mínimo, as partes importantes de sua interface do usuário sejam atualizadas para responder às alterações de DPI.

A maioria dos aplicativos da área de trabalho é executada no modo de reconhecimento de DPI do sistema. Os aplicativos com reconhecimento de DPI do sistema normalmente são dimensionados para o DPI da exibição primária (a exibição em que a bandeja do sistema estava localizada no momento em que a sessão Windows foi iniciada). Quando a DPI for alterada, Windows o bitmap estenderá a interface do usuário desses aplicativos, o que geralmente resulta na desfocada. Ao atualizar um aplicativo com reconhecimento de DPI do Sistema para se tornar ciente de DPI por monitor, o código que manipula o layout da interface do usuário precisa ser atualizado de modo que ele seja executado não apenas durante a inicialização do aplicativo, mas também sempre que uma notificação de alteração de DPI (WM_DPICHANGED no caso do Win32) for recebida. Normalmente, isso envolve revisitar quaisquer suposições no código de que a interface do usuário só precisa ser dimensionada uma vez.

Além disso, no caso da programação win32, muitas APIs Win32 não têm nenhum contexto de DPI ou exibição, portanto, elas só retornarão valores relativos à DPI do Sistema. Pode ser útil usar o código para procurar algumas dessas APIs e substituí-las por variantes com reconhecimento de DPI. Algumas das APIs comuns que têm variantes com reconhecimento de DPI são:

Versão de DPI única Per-Monitor versão
Getsystemmetrics GetSystemMetricsForDpi
AdjustWindowRectEx AdjustWindowRectExForDpi
Systemparametersinfo SystemParametersInfoForDpi
GetDpiForMonitor GetDpiForWindow

Também é uma boa ideia pesquisar tamanhos codificados em código em sua base de código que assumem uma DPI constante, substituindo-os pelo código que explica corretamente o dimensionamento de DPI. Abaixo está um exemplo que incorpora todas essas sugestões:

Exemplo:

O exemplo a seguir mostra um caso Win32 simplificado de criação de um HWND filho. A chamada para CreateWindow pressupõe que o aplicativo está em execução em 96 DPI e nem o tamanho nem a posição do botão estarão corretos em DPIs mais altas:

case WM_CREATE: 
{ 
    // Add a button 
    HWND hWndChild = CreateWindow(L"BUTTON", L"Click Me",  
        WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON,  
        50,  
        50,  
        100,  
        50,  
        hWnd, (HMENU)NULL, NULL, NULL); 
} 

O código atualizado abaixo mostra:

  1. O código de criação de janela DPI que dimensiona a posição e o tamanho do HWND filho para o DPI de sua janela pai
  2. Respondendo à alteração de DPI reposicionando e redimensionando o HWND filho
  3. Tamanhos codificados em código removidos e substituídos por código que responde a alterações de DPI
#define INITIALX_96DPI 50 
#define INITIALY_96DPI 50 
#define INITIALWIDTH_96DPI 100 
#define INITIALHEIGHT_96DPI 50 
 
 
// DPI scale the position and size of the button control 
void UpdateButtonLayoutForDpi(HWND hWnd) 
{ 
    int iDpi = GetDpiForWindow(hWnd); 
    int dpiScaledX = MulDiv(INITIALX_96DPI, iDpi, 96); 
    int dpiScaledY = MulDiv(INITIALY_96DPI, iDpi, 96); 
    int dpiScaledWidth = MulDiv(INITIALWIDTH_96DPI, iDpi, 96); 
    int dpiScaledHeight = MulDiv(INITIALHEIGHT_96DPI, iDpi, 96); 
    SetWindowPos(hWnd, hWnd, dpiScaledX, dpiScaledY, dpiScaledWidth, dpiScaledHeight, SWP_NOZORDER | SWP_NOACTIVATE); 
} 
 
... 
 
case WM_CREATE: 
{ 
    // Add a button 
    HWND hWndChild = CreateWindow(L"BUTTON", L"Click Me",  
        WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON, 
        0, 
        0, 
        0, 
        0, 
        hWnd, (HMENU)NULL, NULL, NULL); 
    if (hWndChild != NULL) 
    { 
        UpdateButtonLayoutForDpi(hWndChild); 
    } 
} 
break; 
 
case WM_DPICHANGED: 
{ 
    // Find the button and resize it 
    HWND hWndButton = FindWindowEx(hWnd, NULL, NULL, NULL); 
    if (hWndButton != NULL) 
    { 
        UpdateButtonLayoutForDpi(hWndButton); 
    } 
} 
break; 

Ao atualizar um aplicativo com reconhecimento de DPI do sistema, algumas etapas comuns a seguir são:

  1. Marque o processo como reconhecimento de DPI por monitor (V2) usando um manifesto do aplicativo (ou outro método, dependendo das estruturas de interface do usuário usadas).
  2. Torne a lógica de layout da interface do usuário reutilizável e mova-a para fora do código de inicialização do aplicativo, de modo que possa ser reutilizado quando ocorrer uma alteração de DPI (WM_DPICHANGED no caso da programação de Windows (Win32).
  3. Invalidar qualquer código que pressupõe que dados confidenciais a DPI (DPI/fontes/tamanhos/etc.) nunca precisem ser atualizados. É uma prática muito comum armazenar em cache tamanhos de fonte e valores de DPI na inicialização do processo. Ao atualizar um aplicativo para se tornar ciente da DPI por monitor, os dados confidenciais de DPI devem ser reavaliados sempre que uma nova DPI for encontrada.
  4. Quando ocorrer uma alteração de DPI, recarregue (ou re-rasterize) todos os ativos de bitmap para o novo DPI ou, opcionalmente, o bitmap estique os ativos atualmente carregados para o tamanho correto.
  5. Grep para APIs que não estão Per-Monitor reconhecimento de DPI e as substituem por Per-Monitor APIs com reconhecimento de DPI (quando aplicável). Exemplo: substitua GetSystemMetrics por GetSystemMetricsForDpi.
  6. Teste seu aplicativo em um sistema de várias exibições/várias DPI.
  7. Para quaisquer janelas de nível superior em seu aplicativo que você não consiga atualizar para a escala de DPI corretamente, use o dimensionamento de DPI de modo misto (descrito abaixo) para permitir o alongamento de bitmap dessas janelas de nível superior pelo sistema.

Mixed-Mode dimensionamento de DPI (dimensionamento de DPI de subprocesso)

Ao atualizar um aplicativo para dar suporte à conscientização de DPI por monitor, às vezes, pode se tornar impraticável ou impossível atualizar todas as janelas do aplicativo de uma só vez. Isso pode ser simplesmente devido ao tempo e ao esforço necessários para atualizar e testar toda a interface do usuário ou porque você não possui todo o código da interface do usuário que precisa executar (se seu aplicativo talvez carregue a interface do usuário de terceiros). Nessas situações, Windows oferece uma maneira de facilitar o mundo da conscientização por monitor, permitindo que você execute algumas de suas janelas de aplicativo (somente de nível superior) no modo de reconhecimento de DPI original enquanto você concentra seu tempo e energia atualizando as partes mais importantes da interface do usuário.

Veja abaixo uma ilustração de como isso pode ser: você atualiza a interface do usuário do aplicativo principal ("Janela Principal" na ilustração) para ser executada com reconhecimento de DPI por monitor enquanto executa outras janelas no modo existente ("Janela Secundária").

differences in dpi scaling between awareness modes

Antes da atualização de aniversário do Windows 10 (1607), o modo de reconhecimento de DPI de um processo era uma propriedade em todo o processo. A partir do Windows 10 Atualização de Aniversário, essa propriedade agora pode ser definida por janela de nível superior. (As janelas filho devem continuar a corresponder ao tamanho de dimensionamento de seus pais.) Uma janela de nível superior é definida como uma janela sem pai. Normalmente, essa é uma janela "regular" com botões minimizar, maximizar e fechar. O cenário para o qual a conscientização da DPI de subprocesso destina-se é ter a interface do usuário secundária dimensionada por Windows (bitmap estendido) enquanto você concentra seu tempo e recursos na atualização da interface do usuário primária.

Para habilitar a conscientização de DPI de subprocesso, chame SetThreadDpiAwarenessContext antes e depois de qualquer chamada de criação de janela. A janela criada será associada à consciência de DPI que você definiu por meio de SetThreadDpiAwarenessContext. Use a segunda chamada para restaurar a conscientização da DPI do thread atual.

Ao usar o dimensionamento de DPI de subprocesso permite que você confie em Windows fazer parte do dimensionamento de DPI para seu aplicativo, isso pode aumentar a complexidade do aplicativo. É importante que você entenda as desvantagens dessa abordagem e da natureza das complexidades que ela introduz. Para obter mais informações sobre a conscientização de DPI de subprocesso, consulte o dimensionamento de DPI de modo misto e APIs com reconhecimento de DPI.

Testando suas alterações

Depois de atualizar seu aplicativo para se tornar ciente da DPI por monitor, é importante validar seu aplicativo responde corretamente às alterações de DPI em um ambiente de DPI misturada. Alguns detalhes a serem testados incluem:

  1. Mover janelas de aplicativo para frente e para trás entre exibições de valores diferentes de DPI
  2. Iniciando seu aplicativo em exibições de diferentes valores de DPI
  3. Alterando o fator de escala do monitor enquanto o aplicativo está em execução
  4. Alterando a exibição que você usa como exibição primária, saindo do Windows e, em seguida, retendo o aplicativo depois de entrar novamente. Isso é particularmente útil na localização de código que usa tamanhos/dimensões codificados em código.

Armadilhas comuns (Win32)

Não usar o retângulo sugerido fornecido em WM_DPICHANGED

Quando Windows envia uma mensagem WM_DPICHANGED à janela do aplicativo, essa mensagem inclui um retângulo sugerido que você deve usar para redimensionar sua janela. É fundamental que seu aplicativo use esse retângulo para se redimensionar, como isso fará:

  1. Verifique se o cursor do mouse permanecerá na mesma posição relativa na Janela ao arrastar entre as exibições
  2. Impedir que a janela do aplicativo entre em um ciclo de alteração de dpi recursivo em que uma alteração de DPI dispara uma alteração de DPI subsequente, que dispara mais uma alteração de DPI.

Se você tiver requisitos específicos do aplicativo que o impedem de usar o retângulo sugerido que Windows fornece na mensagem WM_DPICHANGED, consulte WM_GETDPISCALEDSIZE. Essa mensagem pode ser usada para dar a Windows um tamanho desejado que você gostaria de usar depois que a alteração de DPI tiver ocorrido, evitando ainda os problemas descritos acima.

Falta de documentação sobre virtualização

Quando um HWND ou processo está em execução como DPI sem conhecimento ou reconhecimento de DPI do sistema, ele pode ser bitmap estendido por Windows. Quando isso acontece, Windows dimensiona e converte informações confidenciais de DPI de algumas APIs no espaço de coordenadas do thread de chamada. Por exemplo, se um thread sem conhecimento de DPI consultar o tamanho da tela durante a execução em uma exibição de DPI alta, Windows virtualizará a resposta fornecida ao aplicativo como se a tela estivesse em 96 unidades de DPI. Como alternativa, quando um thread com reconhecimento de DPI do Sistema está interagindo com uma exibição em uma DPI diferente do que estava em uso quando a sessão do usuário atual foi iniciada, Windows dimensionará algumas chamadas de API para o espaço de coordenadas que o HWND estaria usando se estivesse em execução em seu fator de escala de DPI original.

Quando você atualiza o aplicativo da área de trabalho para a escala de DPI corretamente, pode ser difícil saber quais chamadas à API podem retornar valores virtualizados com base no contexto do thread; No momento, essas informações não estão documentadas suficientemente pela Microsoft. Lembre-se de que, se você chamar qualquer API do sistema de um contexto de thread com reconhecimento de DPI ou de DPI do sistema, o valor retornado poderá ser virtualizado. Dessa forma, verifique se o thread está em execução no contexto de DPI esperado ao interagir com a tela ou janelas individuais. Ao alterar temporariamente o contexto de DPI de um thread usando SetThreadDpiAwarenessContext, certifique-se de restaurar o contexto antigo quando terminar para evitar causar comportamento incorreto em outro lugar do aplicativo.

Muitas APIs Windows não têm um contexto de DPI

Muitas APIs Windows herdadas não incluem um contexto DPI ou HWND como parte de sua interface. Como resultado, os desenvolvedores geralmente precisam fazer um trabalho adicional para lidar com o dimensionamento de qualquer informação confidencial de DPI, como tamanhos, pontos ou ícones. Por exemplo, os desenvolvedores que usam LoadIcon devem ou bitmap ícones de stretch loaded ou usar APIs alternativas para carregar ícones de tamanho correto para o DPI apropriado, como LoadImage.

Redefinição forçada da conscientização da DPI em todo o processo

Em geral, o modo de reconhecimento de DPI do processo não pode ser alterado após a inicialização do processo. Windows poderá, no entanto, alterar à força o modo de reconhecimento de DPI do processo se você tentar quebrar o requisito de que todos os HWNDs em uma árvore de janela tenham o mesmo modo de reconhecimento de DPI. Em todas as versões do Windows, a partir do Windows 10 1703, não é possível ter HWNDs diferentes em uma árvore HWND executada em diferentes modos de reconhecimento de DPI. Se você tentar criar uma relação filho-pai que interrompa essa regra, a consciência da DPI de todo o processo poderá ser redefinida. Isso pode ser disparado por:

  1. Uma chamada CreateWindow em que a janela pai passada é de um modo de reconhecimento de DPI diferente do thread de chamada.
  2. Uma chamada SetParent em que as duas janelas estão associadas a diferentes modos de reconhecimento de DPI.

A tabela a seguir mostra o que acontece se você tentar violar esta regra:

Operação Windows 8.1 Windows 10 (1607 e anterior) Windows 10 (1703 e posterior)
CreateWindow (In-Proc) N/D Herda filho (modo misto) Herda filho (modo misto)
CreateWindow (Cross-Proc) Redefinição forçada (do processo do chamador) Herda filho (modo misto) Redefinição forçada (do processo do chamador)
SetParent (In-Proc) N/D Redefinição forçada (do processo atual) Falha (ERROR_INVALID_STATE)
SetParent (Cross-Proc) Redefinição forçada (do processo da janela filho) Redefinição forçada (do processo da janela filho) Redefinição forçada (do processo da janela filho)

Referência de API de Alta DPI

Dimensionamento de DPI de modo misto e APIs com reconhecimento de DPI.