Ho cercato di disabilitare la consapevolezza DPI su un'applicazione ClickOnce.
Ho scoperto rapidamente, non è possibile specificarlo nel manifest, perché ClickOnce non supporta asm.v3 nel file manifest.SetProcessDpiAreazione non ha effetto
L'opzione successiva che ho trovato era chiamare la nuova funzione di Windows SetProcessDpiAwareness.
Secondo this tutorial,
Call SetProcessDpiAwareness before you create the application window.
E this tutorial,
you must call SetProcessDpiAwareness prior to any Win32API call
Bisogna chiamare la funzione molto presto. Così, per testare, ho creato un'applicazione del tutto vuoto WPF, e fatto di questo la mia intera classe App:
[DllImport("SHCore.dll", SetLastError = true)]
private static extern bool SetProcessDpiAwareness(PROCESS_DPI_AWARENESS awareness);
[DllImport("SHCore.dll", SetLastError = true)]
private static extern void GetProcessDpiAwareness(IntPtr hprocess, out PROCESS_DPI_AWARENESS awareness);
private enum PROCESS_DPI_AWARENESS
{
Process_DPI_Unaware = 0,
Process_System_DPI_Aware = 1,
Process_Per_Monitor_DPI_Aware = 2
}
static App()
{
var result = SetProcessDpiAwareness(PROCESS_DPI_AWARENESS.Process_DPI_Unaware);
var setDpiError = Marshal.GetLastWin32Error();
MessageBox.Show("Dpi set: " + result.ToString());
PROCESS_DPI_AWARENESS awareness;
GetProcessDpiAwareness(Process.GetCurrentProcess().Handle, out awareness);
var getDpiError = Marshal.GetLastWin32Error();
MessageBox.Show(awareness.ToString());
MessageBox.Show("Set DPI error: " + new Win32Exception(setDpiError).ToString());
MessageBox.Show("Get DPI error: " + new Win32Exception(getDpiError).ToString());
}
Le 3 finestre di messaggio mostrano questo contenuto:
Dpi set: True
Process_System_DPI_Aware
Set DPI error: System.ComponentModel.Win32Exception (0x80004005): Access is denied
System.ComponentModel.Win32Exception (0x80004005): The operation completed successfully
Perché è l'applicazione ancora impostato a DPI_Aware? Questa chiamata non è abbastanza presto?
L'applicazione presenta effettivamente il ridimensionamento DPI.
Quando uso la definizione manifesta:
<application xmlns="urn:schemas-microsoft-com:asm.v3">
<windowsSettings>
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">false</dpiAware>
</windowsSettings>
</application>
Si fa ritorno Process_DPI_Unaware.
EDIT 1:
Ora afferrando Marshal.GetLastWin32Error() subito dopo metodi PInvoke, questo ora effettivamente restituisce un errore.
Ah! Ovviamente! Si prega di consultare il mio codice modificato, restituisce "Imposta errore DPI: System.ComponentModel.Win32Exception (0x80004005): accesso negato" –
Vedere la mia modifica per un altro approccio. – Aybe
Che ha funzionato perfettamente! Grazie! –