Noções básicas sobre problemas de dimensionamento de tela
O Windows Vista e versões posteriores do sistema operacional permitem que os usuários alterem a configuração de pontos por polegada (dpi) para que a maioria dos elementos de interface do usuário na tela pareça maior. Em versões anteriores do Windows, o dimensionamento precisava ser implementado por aplicativos. No Windows Vista e posterior, o DWM (Gerenciador de Janelas da Área de Trabalho) executa o dimensionamento padrão para todos os aplicativos que não lidam com seu próprio dimensionamento. Os aplicativos cliente do Microsoft Automação da Interface do Usuário devem levar esse recurso em conta.
Este tópico contém as seguintes seções:
- Dimensionamento no Windows Vista e posterior
- Escala nos clientes da Automação da Interface do Usuário
Dimensionamento no Windows Vista e posterior
A configuração de dpi padrão é 96, o que significa que 96 pixels ocupam uma largura ou altura de uma polegada nocional. A medida exata de uma "polegada" depende do tamanho e da resolução física do monitor. Por exemplo, em um monitor de 12 polegadas de largura, com uma resolução horizontal de 1280 pixels, uma linha horizontal de 96 pixels se estende por cerca de 9/10 de polegada.
Alterar a configuração de dpi não é o mesmo que alterar a resolução da tela. Com a escala de dpi, o número de pixels físicos na tela permanece o mesmo. No entanto, a escala é aplicada ao tamanho e ao local dos elementos da interface do usuário. Esse dimensionamento pode ser executado automaticamente pelo DWM para a área de trabalho e para aplicativos que não solicitam explicitamente que não sejam dimensionados.
Na verdade, quando o usuário define o fator de escala como 120 dpi, uma polegada vertical ou horizontal na tela fica 25% maior. Todas as dimensões são adequadamente alteradas. O deslocamento de uma janela do aplicativo da borda superior e da borda esquerda da tela aumenta em 25%. Se a escala do aplicativo estiver habilitada e ele não tiver reconhecimento de dpi, o tamanho da janela aumentará na mesma proporção, juntamente com os deslocamentos e tamanhos de todos os elementos da interface do usuário que ela contém.
Observação
Por padrão, o DWM não executa o dimensionamento para aplicativos sem reconhecimento de dpi quando o usuário define o dpi como 120, mas executa o dimensionamento quando o dpi é definido como um valor personalizado de 144 ou superior. No entanto, o usuário pode substituir o comportamento padrão.
A escala da tela traz novos desafios para aplicativos que se importam com as coordenadas da tela. A tela agora contém dois sistemas de coordenadas: físico e lógico. As coordenadas físicas de um ponto são o deslocamento real em pixels do canto superior esquerdo do ponto de origem. As coordenadas lógicas são os deslocamentos possíveis se os pixels em si fossem dimensionados.
Suponhamos que você crie uma caixa de diálogo com um botão nas coordenadas (100, 48). Quando essa caixa de diálogo for exibida no dpi padrão de 96, o botão estará localizado nas coordenadas físicas de (100, 48). Em 120 dpi, ele estará localizado nas coordenadas físicas de (125, 60). Mas, as coordenadas lógicas são as mesmas em qualquer configuração de dpi: (100, 48).
As coordenadas lógicas são importantes, pois tornam o comportamento do sistema operacional e dos aplicativos consistente, independentemente da configuração de dpi. Por exemplo, normalmente, a função GetCursorPos retorna as coordenadas lógicas. Se você mover o cursor sobre um elemento em uma caixa de diálogo, as mesmas coordenadas serão retornadas, independentemente da configuração de dpi. Se você desenhar um controle em (100, 100), ele será desenhado para essas coordenadas lógicas e ocupará a mesma posição relativa em qualquer configuração de dpi.
Escala nos clientes da Automação da Interface do Usuário
A API de Automação da Interface do Usuário não usa coordenadas lógicas. Os métodos e as propriedades a seguir retornam coordenadas físicas ou tomam coordenadas físicas como parâmetros.
- IUIAutomation::ElementFromPoint
- IUIAutomation::ElementFromPointBuildCache
- IUIAutomationElement::GetClickablePoint
- IUIAutomationElement::CurrentBoundingRectangle
- IUIAutomationElement::CachedBoundingRectangle
- IRawElementProviderFragment::BoundingRectangle
Por padrão, Automação da Interface do Usuário aplicativos em execução em um ambiente que não está definido como 96 dpi não obterão os resultados corretos desses métodos e propriedades. Por exemplo, como a posição do cursor está em coordenadas lógicas, o cliente não pode passar essas coordenadas para IUIAutomation::ElementFromPoint para obter o elemento que está sob o cursor. Além disso, o aplicativo não poderá colocar corretamente as janelas fora da área do cliente.
A solução tem duas partes.
Primeiramente, o aplicativo cliente deve ter reconhecimento de dpi. Para fazer isso, chame a função SetProcessDPIAware na inicialização. Essa função faz com que todo o processo tenha reconhecimento de dpi, o que significa que todas as janelas que pertencem ao processo estão fora de escala.
Em segundo lugar, para obter coordenadas de cursor, chame a função GetPhysicalCursorPos .