2010-04-13 13 views
8

Ho riscontrato un problema interessante. Almeno in Vista, getSystemMetrics (SM_CXSCREEN) restituisce un valore errato quando le impostazioni DPI del desktop non sono impostate al 100%. Ad esempio, ho provato il 150% in uno schermo 1366x768 e getSystemMetrics() restituisce 911 anziché 1366 (e 1366/1.5 ~ 911)GetSystemMetrics() restituisce un valore errato per SM_CXSCREEN

In base a MSDN, getSystemMetrics (SM_CXSCREEN) restituisce i pixel, quindi ho pensato che questo valore non avrebbe essere influenzato dalle impostazioni DPI - ma lo è. Quindi c'è un modo più sicuro per scoprire la vera risoluzione dello schermo non graduata?

+0

Da che tipo di applicazione si chiama questo? Ho appena provato a chiamare quell'API da C e l'ho eseguito su Vista Business con impostazioni DPI diverse e risoluzioni diverse e ha riportato i pixel correttamente in ogni istanza. È un'immagine vmware, quindi forse questo fa la differenza. –

+0

È un'app C++ normale e semplice. Nessun framework standard, solo WinMain. – ggambett

risposta

10

Un programma deve comunicare al sistema operativo che è in grado di rilevare la risoluzione effettiva quando si supera il 125%. È meglio farlo con un manifest, come spiegato in questo MSDN Library article.

+0

Questo l'ha fatto. Grazie! – ggambett

5

Per rendere l'applicazione consapevole di dpi make e manifest file e inserire il seguente testo in esso.

<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3" > 
    <asmv3:application> 
    <asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings"> 
     <dpiAware>true</dpiAware> 
    </asmv3:windowsSettings> 
    </asmv3:application> 
</assembly> 
1

Prima di ottenere le metriche di pixel corretti dalle funzioni come GetSystemMetrics, o GetClientRect, la vostra applicazione deve dichiarare al sistema operativo che si conosce DPI e quindi non avvitare tutto.

Sono state apportate diverse modifiche a come è consigliabile. Vedi i documenti MSDN per maggiori dettagli.

da Windows 10 in poi:

::SetThreadDpiAwarenessContext(DPI_AWARENESS_CONTEXT_SYSTEM_AWARE); 

O da Windows 8.1 in poi:

::SetProcessDpiAwareness(DPI_AWARENESS_CONTEXT_SYSTEM_AWARE); 

O da Vista in poi:

::SetProcessDPIAware(); 

Dopo aver richiamato questo, i GetSystemMetrics funzione etc. dovrebbe restituire i valori corretti alla tua app in pixel.

+0

Si consiglia sempre di utilizzare manifest per impostare la consapevolezza DPI del processo. Esistono tre tipi di consapevolezza DPI: 1) inconsapevole (si pensa che il mondo sia sempre a 96 DPI) 2) consapevole del sistema (si capisce DPI ma si pensa che il mondo sia sempre il DPI del sistema e non cambierà mai) 3) consapevole del monitor (si capisce DPI e può cambiare mentre è in esecuzione) SetProcessDPIAware() rende consapevole l'intero sistema di elaborazione SetProcessDpiAwareness (...) consente di specificare la modalità di consapevolezza del processo SetThreadDpiAwarenessContext (. ..) abilita la consapevolezza DPI sub-process – peterfelts

Problemi correlati