Tôi đã cố gắng vô hiệu hóa nhận thức DPI trên một ứng dụng ClickOnce.
Tôi nhanh chóng phát hiện ra, không thể chỉ định nó trong tệp kê khai, bởi vì ClickOnce không hỗ trợ asm.v3 trong tệp kê khai.SetProcessDpiAwareness không có hiệu lực
Tùy chọn tiếp theo tôi tìm thấy đang gọi chức năng Windows mới SetProcessDpiAwareness.
Theo this hướng dẫn,
Call SetProcessDpiAwareness before you create the application window.
Và this hướng dẫn,
you must call SetProcessDpiAwareness prior to any Win32API call
Bạn cần phải gọi hàm khá sớm. Vì vậy, để kiểm tra, tôi đã tạo ra một ứng dụng WPF hoàn toàn trống, và thực hiện điều này toàn bộ lớp App của tôi:
[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 hộp thư hiển thị nội dung này:
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
Tại sao là ứng dụng vẫn thiết lập tới DPI_Aware? Cuộc gọi này có đủ sớm không?
Ứng dụng thực sự trải nghiệm quy mô DPI.
Khi tôi sử dụng định nghĩa manifest:
<application xmlns="urn:schemas-microsoft-com:asm.v3">
<windowsSettings>
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">false</dpiAware>
</windowsSettings>
</application>
Nó trở Process_DPI_Unaware.
EDIT 1:
Bây giờ grabbing Marshal.GetLastWin32Error() trực tiếp sau khi các phương pháp PInvoke, điều này bây giờ thực sự trả về một lỗi.
Ah! Tất nhiên! Vui lòng xem mã đã chỉnh sửa của tôi, trả về "Đặt lỗi DPI: System.ComponentModel.Win32Exception (0x80004005): Truy cập bị từ chối" –
Xem bản chỉnh sửa của tôi để biết cách tiếp cận khác. – Aybe
Điều đó hoạt động hoàn hảo! Cảm ơn! –