Condividi tramite


Mixed-Mode API con scalabilità DPI e riconoscimento DPI

Sub-Process supporto di consapevolezza DPI

SetThreadDpiAwarenessContext consente l'uso di diverse modalità di ridimensionamento DPI all'interno di un singolo processo. Prima dell'aggiornamento Windows 10 anniversario, è stata associata la consapevolezza dpi della finestra alla modalità di consapevolezza DPI a livello di processo (DPI non consapevole, con riconoscimento dpi di sistema o Per-Monitor dpi consapevoli). Ma ora, con SetThreadDpiAwarenessContext, le finestre di primo livello possono avere una modalità di consapevolezza DPI diversa da quella della modalità di consapevolezza DPI a livello di processo. Ciò influisce anche sulle finestre figlio, perché avranno sempre la stessa modalità di consapevolezza DPI della finestra padre.

L'uso di SetThreadDpiAwarenessContext consente agli sviluppatori di decidere dove concentrarsi sugli sforzi di sviluppo durante la definizione del comportamento specifico di DPI per le applicazioni desktop. Ad esempio, la finestra principale di un'applicazione può essere ridimensionata in base al monitoraggio, mentre le finestre secondarie di primo livello possono essere ridimensionate tramite il ridimensionamento bitmap dal sistema operativo.

Contesto di consapevolezza DPI

Prima della disponibilità di SetThreadDpiAwarenessContext la consapevolezza DPI di un processo è stata definita nel manifesto del file binario dell'applicazione o tramite una chiamata a SetProcessDpiAwareness durante l'inizializzazione del processo. Con SetThreadDpiAwarenessContext, ogni thread può avere un singolo contesto di consapevolezza DPI che può essere diverso da quello della modalità di consapevolezza DPI a livello di processo. Il contesto di consapevolezza DPI di un thread è rappresentato con il tipo di DPI_AWARENESS_CONTEXT e si comporta nei modi seguenti:

  • Un thread può avere il contesto di consapevolezza DPI modificato in qualsiasi momento.
  • Tutte le chiamate API eseguite dopo la modifica del contesto verranno eseguite nel contesto DPI corrispondente e possono essere virtualizzate.
  • Quando viene creata una finestra, la consapevolezza dpi è definita come consapevolezza DPI del thread chiamante in quel momento.
  • Quando viene chiamata la procedura della finestra per una finestra, il thread viene spostato automaticamente nel contesto di consapevolezza DPI in uso quando è stata creata la finestra.

Uno scenario comune per l'uso di SetThreadDpiAwarenessContext è il seguente: Iniziare con un thread in esecuzione con un contesto (ad esempio DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE) passare temporaneamente a un contesto diverso (DPI_AWARENESS_CONTEXT_UNAWARE), creare una finestra e quindi passare immediatamente al contesto del thread allo stato precedente. La finestra creata avrà un contesto DPI di DPI_AWARENESS_CONTEXT_UNAWARE, mentre il contesto del thread chiamante verrà ripristinato in DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE con una chiamata successiva a SetThreadDpiAwarenessContext. In questo scenario, la finestra associata al thread chiamante verrà eseguita con un contesto per monitor (e quindi non è bitmap-stretched dal sistema operativo) mentre la finestra appena creata non sarebbe a conoscenza di DPI (e quindi sarebbe automaticamente bitmap estesa su un set di visualizzazione impostato su >scalabilità 100%).

La figura 1 illustra come viene eseguito il thread di processo principale con DPI_AWARENESS_CONTEXT_PER_MONITOR, sposta il relativo contesto in DPI_AWARENESS_CONTEXT_UNAWARE e crea una nuova finestra. La finestra appena creata viene quindi eseguita con un contesto di consapevolezza DPI di DPI_AWARENESS_CONTEXT_UNAWARE ogni volta che viene inviato un messaggio o le chiamate API vengono eseguite da esso. Subito dopo aver creato la nuova finestra, il thread principale viene ripristinato nel contesto precedente di DPI_AWARENESS_CONTEXT_PER_MONITOR.

diagramma che mostra la consapevolezza dpi per monitoraggio in azione

Oltre al supporto per diverse modalità di consapevolezza DPI all'interno di un singolo processo che SetThreadDpiAwarenessContext offre, è stata aggiunta la funzionalità specifica dpi seguente per le applicazioni desktop:

EnableNonClientDpiScaling

Nota

La modalità di riconoscimento DPI V2 per Monitoraggio abilita automaticamente questa funzionalità e chiama EnableNonClientDpiScaling non è quindi necessaria nelle applicazioni che lo usano.

La chiamata a EnableNonClientDpiScaling dall'interno di un gestore WM_NCCREATE finestra comporterà il ridimensionamento automatico dell'area non client di una finestra di primo livello per DPI. Se la finestra di primo livello è in grado di rilevare DPI per monitor (se il processo stesso è compatibile con DPI per monitor o perché la finestra è stata creata all'interno di un thread con riconoscimento DPI per monitoraggio), la barra didascalia, le barre di scorrimento, le barre di scorrimento, i menu e le barre dei menu di queste finestre verranno ridimensionate ogni volta che cambia la DPI della finestra.

Si noti che le aree non client di una finestra figlio, ad esempio le barre di scorrimento non client di un controllo di modifica figlio, non verranno ridimensionate automaticamente quando questa API viene usata.

Nota

EnableNonClientDpiScaling deve essere chiamato dal gestore WM_NCCREATE .

API *ForDpi
  • Diverse API usate di frequente, ad esempio GetSystemMetrics , non hanno alcun contesto di un HWND e pertanto non hanno modo di dedurre la consapevolezza dpi appropriata per i valori restituiti. La chiamata di queste API da un thread in esecuzione in modalità di consapevolezza DPI diversa o un contesto può restituire valori non ridimensionati per il contesto del thread chiamante. GetSystemMetricForDpi, SystemParametersInfoForDpi e AdjustWindowRectExForDpi eseguirà le stesse funzionalità delle controparti DPI non consapevoli, ma accettare una DPI come argomento e dedurre la consapevolezza dpi dal contesto del thread corrente.

  • GetSystemMetricForDpi e SystemParametersInfoForDpi restituiranno i valori delle metriche di sistema con scalabilità DPI e i valori dei parametri di sistema in base a questa equazione:

    GetSystemMetrics(...) @ dpi == GetSystemMetricsForDpi(..., dpi)

    Pertanto, chiamando GetSystemMetrics (o SystemParametersInfoForDpi), durante l'esecuzione in un dispositivo con un determinato valore DPI restituirà lo stesso valore che le varianti con riconoscimento DPI (GetSystemMetricsForDpi e SystemParametersInfoForDpi) restituiranno lo stesso valore DPI dell'input.

  • RegolaWindowRectExForDpi accetta un HWND e calcola le dimensioni necessarie di un rettangolo di finestra in modo sensibile a DPI.

GetDpiForWindow
GetDpiForWindow restituirà la DPI associata al valore HWND fornito. La risposta dipenderà dalla modalità di consapevolezza DPI del HWND:
Modalità di consapevolezza DPI di HWND Valore restituito
Ignari 96
Sistema DPI di sistema
Per-Monitor DPI della visualizzazione in cui si trova principalmente la finestra di primo livello associata
Se viene fornita una finestra figlio, verrà restituito il valore DPI della finestra padre di primo livello corrispondente.
GetDpiForSystem

La chiamata a GetDpiForSystem è più efficiente rispetto alla chiamata a GetDC e GetDeviceCaps per ottenere la DPI di sistema.

Qualsiasi componente che potrebbe essere in esecuzione in un'applicazione che usa la consapevolezza dpi del sotto-processo non deve presumere che il valore DPI di sistema sia statico durante il ciclo di vita del processo. Ad esempio, se un thread in esecuzione in DPI_AWARENESS_CONTEXT_UNAWARE contesto di consapevolezza esegue query sul dpi di sistema, la risposta sarà 96. Tuttavia, se lo stesso thread passa a DPI_AWARENESS_CONTEXT_SYSTEM contesto di consapevolezza e esegue nuovamente una query sulla DPI di sistema, la risposta potrebbe essere diversa. Per evitare l'uso di un valore DPI di sistema memorizzato nella cache (e possibilmente non aggiornato), usare GetDpiForSystem per recuperare la dpi di sistema rispetto alla modalità di consapevolezza DPI del thread chiamante.