Próbowałem wyłączyć sygnalizację DPI w aplikacji ClickOnce.
Szybko się dowiedziałem, nie można tego określić w manifeście, ponieważ ClickOnce nie obsługuje pliku asm.v3 w pliku manifestu.SetProcessDpiAwareness nie ma efektu
Następną opcją, którą znalazłem było wywołanie nowej funkcji Windows SetProcessDpiAwareness.
Według this samouczku
Call SetProcessDpiAwareness before you create the application window.
I this poradnik,
you must call SetProcessDpiAwareness prior to any Win32API call
Trzeba wywołać funkcję dość wcześnie. Tak więc, aby sprawdzić, jakie stworzył zupełnie pusty aplikacji WPF i uczynił to całą moją klasę aplikacji:
[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());
}
The 3 skrzynkach pokazać zawartość:
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
Dlaczego aplikacja nadal ustawiony do DPI_Aware? Czy to wezwanie nie jest wystarczająco wczesne?
Aplikacja rzeczywiście wykonuje skalowanie DPI.
Kiedy używam oczywistego definicję:
<application xmlns="urn:schemas-microsoft-com:asm.v3">
<windowsSettings>
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">false</dpiAware>
</windowsSettings>
</application>
To nie powrócić Process_DPI_Unaware.
EDIT 1:
Teraz chwytając Marshal.GetLastWin32Error() bezpośrednio po metodach pinvoke, to teraz faktycznie zwraca błąd.
Ah! Oczywiście! Proszę zobaczyć mój edytowany kod, zwraca "Ustaw błąd DPI: System.ComponentModel.Win32Exception (0x80004005): Odmowa dostępu" –
Zobacz moją edycję innego podejścia. – Aybe
To działało bez zarzutu! Dzięki! –