Я пытался отключить понимание DPI в приложении ClickOnce.
Я быстро обнаружил, что невозможно указать его в манифесте, потому что ClickOnce не поддерживает asm.v3 в файле манифеста.SetProcessDpiAwareness не имеет эффекта
Следующий параметр, который я нашел, вызывал новую функцию Windows SetProcessDpiAwareness.
this Согласно учебнику,
Call SetProcessDpiAwareness before you create the application window.
И this учебника,
you must call SetProcessDpiAwareness prior to any Win32API call
Вы должны вызвать функцию довольно рано. Так, чтобы проверить, я создал совершенно пустое приложение WPF, и сделал это весь мой класс 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());
}
3 окна сообщений показать это содержание:
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
Почему приложение по-прежнему установлен в DPI_Aware? Этот звонок не достаточно рано?
Приложение действительно обладает масштабированием DPI.
Когда я использую манифест определение:
<application xmlns="urn:schemas-microsoft-com:asm.v3">
<windowsSettings>
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">false</dpiAware>
</windowsSettings>
</application>
Он вернется Process_DPI_Unaware.
EDIT 1:
Теперь захватывая Marshal.GetLastWin32Error() непосредственно после того, как методы PInvoke, это теперь фактически возвращает ошибку.
Ah! Конечно! См. Мой отредактированный код, возвращает «Установить ошибку DPI: System.ComponentModel.Win32Exception (0x80004005): Доступ запрещен« –
См. Мое редактирование для другого подхода. – Aybe
Это работало безупречно! Благодаря! –