Automazione interfaccia utente e ridimensionamento dello schermo

Nota

Questa documentazione è destinata agli sviluppatori .NET Framework che desiderano utilizzare le classi di Automazione interfaccia utente gestite definite nello spazio dei nomi System.Windows.Automation. Per informazioni aggiornate su UI Automation, vedere API di automazione di Windows: UI Automation.

A partire da Windows Vista, Windows consente agli utenti di modificare l'impostazione dei punti per pollice (dpi) in modo che la maggior parte degli elementi dell'interfaccia utente sullo schermo appaia più grande. Anche se questa funzionalità è stata a lungo disponibile in Windows, nelle versioni precedenti il ridimensionamento doveva essere implementato dalle applicazioni. A partire da Windows Vista, Desktop Window Manager esegue il ridimensionamento predefinito per tutte le applicazioni che non gestiscono il proprio ridimensionamento. Per le applicazioni client di automazione interfaccia utente è necessario tenere conto di questa funzionalità.

Ridimensionamento in Windows Vista

L'impostazione dpi predefinita è 96, ovvero 96 pixel occupano una larghezza o un'altezza di un pollice nozionale. La misura esatta di un pollice dipende dalle dimensioni e dalla risoluzione fisica del monitor. Ad esempio, su un monitor con una larghezza di 12 pollici e una risoluzione orizzontale di 1280 pixel, una riga orizzontale di 96 pixel si estende per circa 9/10 di un pollice.

La modifica dell'impostazione dpi non equivale alla modifica della risoluzione dello schermo. Con la scalabilità dpi, il numero di pixel fisici sullo schermo rimane invariato. Tuttavia, il ridimensionamento viene applicato alle dimensioni e alla posizione degli elementi dell'interfaccia utente. È possibile eseguire il ridimensionamento automaticamente con Gestione finestre desktop per il desktop e per le applicazioni che non richiedono tale funzionalità in modo esplicito.

In effetti, quando l'utente imposta il fattore di scala su 120 dpi, un pollice verticale o orizzontale sullo schermo diventa più grande del 25%. Tutte le dimensioni vengono ridimensionate di conseguenza. L'offset di una finestra dell'applicazione dai bordi superiore e sinistro dello schermo aumenta del 25%. Se il ridimensionamento dell'applicazione è abilitato e l'applicazione non è compatibile con dpi, le dimensioni della finestra aumentano nella stessa proporzione, insieme agli offset e alle dimensioni di tutti gli elementi dell'interfaccia utente contenuti.

Nota

Per impostazione predefinita, DWM non esegue il ridimensionamento per le applicazioni non compatibili con dpi quando l'utente imposta dpi su 120, ma lo esegue quando il valore DPI è impostato su un valore personalizzato pari o superiore a 144. È tuttavia possibile ignorare questo comportamento predefinito.

Il ridimensionamento dello schermo crea nuove sfide per le applicazioni che dipendono dalle coordinate dello schermo. Lo schermo contiene ora due sistemi di coordinate: fisico e logico. Le coordinate fisiche di un punto sono l'offset effettivo in pixel dalla parte superiore sinistra dell'origine. Le coordinate logiche sono gli offset così come si presenterebbero se i pixel fossero ridimensionati.

Si supponga di progettare una finestra di dialogo con un pulsante in corrispondenza delle coordinate (100, 48). Quando questa finestra di dialogo viene visualizzata con il valore predefinito di 96 dpi, il pulsante si trova in corrispondenza delle coordinate fisiche (100, 48). A 120 dpi, si trova a coordinate fisiche di (125, 60). Ma le coordinate logiche sono uguali a qualsiasi impostazione dpi: (100, 48).

Le coordinate logiche sono importanti perché rendono coerente il comportamento del sistema operativo e delle applicazioni indipendentemente dall'impostazione dpi. Ad esempio, la proprietà Cursor.Position restituisce in genere le coordinate logiche. Se si sposta il cursore su un elemento in una finestra di dialogo, le stesse coordinate vengono restituite indipendentemente dall'impostazione dpi. Se si disegna un controllo in corrispondenza di (100, 100), viene disegnato in tali coordinate logiche e occupa la stessa posizione relativa in qualsiasi impostazione dpi.

Ridimensionamento nei client di automazione interfaccia utente

L'API di automazione interfaccia utente non usa coordinate logiche. I metodi e le proprietà seguenti restituiscono coordinate fisiche o le accettano come parametri.

Per impostazione predefinita, un'applicazione client di automazione interfaccia utente in esecuzione in un ambiente diverso da 96 dpi non sarà in grado di ottenere risultati corretti da questi metodi e proprietà. Ad esempio, poiché la posizione del cursore è definita in coordinate logiche, il client non può semplicemente passare tali coordinate al metodo FromPoint per ottenere l'elemento sotto il cursore. Inoltre, l'applicazione non sarà in grado di posizionare correttamente le finestre al di fuori dell'area client.

La soluzione è costituita da due parti.

  1. Innanzitutto, rendere compatibile con dpi dell'applicazione client. A tale scopo, chiamare la funzione Win32 SetProcessDPIAware all'avvio. In codice gestito, la dichiarazione seguente rende disponibile questa funzione.

    [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
    

    Questa funzione rende l'intero processo compatibile con dpi, ovvero tutte le finestre che appartengono al processo non vengono ridimensionate. In Highlighter sample, ad esempio, le quattro finestre che costituiscono il rettangolo di evidenziazione si trovano in corrispondenza delle coordinate fisiche ottenute dall'automazione interfaccia utente, non le coordinate logiche. Se l'esempio non fosse compatibile con dpi, l'evidenziazione verrà disegnata in corrispondenza delle coordinate logiche sul desktop, con conseguente posizionamento errato in un ambiente diverso da 96 dpi.

  2. Per ottenere le coordinate del cursore, chiamare la funzione Win32 GetPhysicalCursorPos. Nell'esempio riportato di seguito viene illustrato come dichiarare e usare questa funzione.

    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
    

Attenzione

Non usare Cursor.Position. Il comportamento di questa proprietà al di fuori delle finestre client in un ambiente non ridimensionato non è definito.

Se l'applicazione esegue comunicazioni dirette tra processi con applicazioni non compatibili con dpi, è possibile eseguire la conversione tra coordinate logiche e fisiche usando le funzioni Win32 PhysicalToLogicalPoint e LogicalToPhysicalPoint.

Vedi anche