Partilhar via


Automação da interface do usuário e dimensionamento de tela

Observação

Esta documentação destina-se a desenvolvedores do .NET Framework que desejam usar as classes de automação da interface do usuário gerenciadas definidas no namespace System.Windows.Automation. Para obter as informações mais recentes sobre a automação da interface de utilizador, consulte API de automação do Windows: Automação da Interface de Utilizador.

A partir do Windows Vista, o Windows permite que os usuários alterem a configuração de pontos por polegada (dpi) para que a maioria dos elementos da interface do usuário (UI) na tela pareça maior. Embora esse recurso esteja disponível há muito tempo no Windows, em versões anteriores o dimensionamento tinha que ser implementado por aplicativos. A partir do Windows Vista, o Desktop Window Manager executa o dimensionamento padrão para todos os aplicativos que não lidam com seu próprio dimensionamento. Os aplicativos cliente de automação da interface do usuário devem levar esse recurso em consideração.

Dimensionamento no Windows Vista

A configuração 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 cerca de 9/10 de polegada.

Alterar a configuração de dpi não é o mesmo que alterar a resolução da tela. Com o dimensionamento de dpi, o número de pixels físicos na tela permanece o mesmo. No entanto, o dimensionamento é aplicado ao tamanho e ao local dos elementos da interface do usuário. Esse dimensionamento pode ser executado automaticamente pelo Desktop Window Manager (DWM) para a área de trabalho e para aplicativos que não pedem explicitamente para não serem dimensionados.

Com efeito, quando o utilizador define o fator de escala para 120 dpi, uma polegada vertical ou horizontal no ecrã torna-se maior em 25 por cento. Todas as dimensões são dimensionadas de acordo. O deslocamento de uma janela de aplicativo das bordas superior e esquerda da tela aumenta em 25%. Se o dimensionamento do aplicativo estiver habilitado e o aplicativo não reconhecer o 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 o executa quando o dpi é definido como um valor personalizado de 144 ou superior. No entanto, o usuário pode substituir o comportamento padrão.

O dimensionamento de tela cria novos desafios para aplicativos que estão preocupados de alguma forma 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 a partir do canto superior esquerdo da origem. As coordenadas lógicas são os desfasamentos que ocorreriam se os próprios píxeis fossem redimensionados.

Suponha que você crie uma caixa de diálogo com um botão nas coordenadas (100, 48). Quando essa caixa de diálogo é exibida no padrão de 96 dpi, o botão está localizado nas coordenadas físicas de (100, 48). A 120 dpi, está localizado em coordenadas físicas de (125, 60). Mas as coordenadas lógicas são as mesmas em qualquer configuração dpi: (100, 48).

As coordenadas lógicas são importantes, porque tornam o comportamento do sistema operacional e dos aplicativos consistentes, independentemente da configuração de dpi. Por exemplo, Cursor.Position normalmente 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 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.

Dimensionamento em clientes de 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 propriedades a seguir retornam coordenadas físicas ou as tomam como parâmetros.

Por padrão, um aplicativo cliente de Automação da Interface do Usuário em execução em um ambiente que não seja de 96 dpi não poderá obter 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 simplesmente passar essas coordenadas para FromPoint obter o elemento que está sob o cursor. Além disso, o aplicativo não será capaz de colocar corretamente as janelas fora de sua área de cliente.

A solução está dividida em duas partes.

  1. Primeiro, torne o aplicativo cliente dpi-aware. Para fazer isso, chame a função SetProcessDPIAware Win32 na inicialização. No código gerenciado, a declaração a seguir disponibiliza essa função.

    [System.Runtime.InteropServices.DllImport("user32.dll")]
    internal static extern bool SetProcessDPIAware();
    
    <System.Runtime.InteropServices.DllImport("user32.dll")> _
    Friend Shared Function SetProcessDPIAware() As Boolean
    End Function
    

    Esta função torna todo o processo com reconhecimento de DPI, o que significa que todas as janelas que pertencem ao processo não sofrem escala. No exemplo de marcador, por exemplo, as quatro janelas que compõem o retângulo de realce estão localizadas nas coordenadas físicas obtidas da automação da interface do usuário, não nas coordenadas lógicas. Se a amostra não estivesse ciente de dpi, o destaque seria desenhado nas coordenadas lógicas na área de trabalho, o que resultaria em posicionamento incorreto em um ambiente não-96-dpi.

  2. Para obter as coordenadas do cursor, chame a função GetPhysicalCursorPosWin32 . O exemplo a seguir mostra como declarar e usar essa função.

    public struct CursorPoint
    {
        public int X;
        public int Y;
    }
    
    [System.Runtime.InteropServices.DllImport("user32.dll")]
    internal static extern bool GetPhysicalCursorPos(ref CursorPoint lpPoint);
    
    private bool ShowUsage()
    {
        CursorPoint cursorPos = new CursorPoint();
        try
        {
            return GetPhysicalCursorPos(ref cursorPos);
        }
        catch (EntryPointNotFoundException) // Not Windows Vista
        {
            return false;
        }
    }
    
    Structure CursorPoint
        Public X As Integer
        Public Y As Integer
    End Structure
    
    <System.Runtime.InteropServices.DllImport("user32.dll")> _
    Friend Shared Function GetPhysicalCursorPos(ByRef lpPoint As CursorPoint) As Boolean
    End Function
    
    Private Function ShowUsage() As Boolean
    
        Dim cursorPos As New CursorPoint()
        Try
            Return GetPhysicalCursorPos(cursorPos)
        Catch e As EntryPointNotFoundException ' Not Windows Vista
            Return False
        End Try
    
    End Function
    

Atenção

Não utilizar Cursor.Position. O comportamento dessa propriedade fora das janelas do cliente em um ambiente dimensionado é indefinido.

Se o seu aplicativo executa comunicação direta entre processos com aplicativos sem reconhecimento de dpi, pode ter de converter entre coordenadas lógicas e físicas, usando as funções Win32 PhysicalToLogicalPoint e LogicalToPhysicalPoint.

Ver também