![](/img/trans.png)
[英]Is there a way to retrieve a device's DPI without using GDI+/WinForms “Graphics” class?
[英]What's the correct way to retrieve the DPI of secondary monitors?
問題
在Windows 8.1(及更新版本)上,DPI設置是每個監視器。 我可以在系統設置中清楚地看到我的主顯示器(筆記本電腦)設置為125%dpi,而我的備用顯示器設置為100%dpi。 我的應用程序完全用C#編寫,我嘗試的每個API調用都會導致輔助監視器的DPI不正確。 請記住,我在我的進程初始化中調用此方法,並在清單中指定了DPI:
(shcore.dll)
SetProcessDpiAwareness(PROCESS_DPI_AWARENESS::PROCESS_PER_MONITOR_DPI_AWARE);
嘗試
(shcore.dll)
GetDpiForMonitor(hMonitor, MONITOR_DPI_TYPE::MDT_EFFECTIVE_DPI, &dpiX, &dpiY)
(結果120,無論hMonitor句柄如何)
(user32.dll)
IntPtr dC = CreateDC(...);
double logX = (double)GetDeviceCaps(dC, LOGPIXELSX);
double logY = (double)GetDeviceCaps(dC, LOGPIXELSY);
(結果120,與CreateDC的設備名稱無關)
監視器布局
令我嚴重困惑的另一件事是,第一台顯示器位於rect {0,0,1920,1080}
但第二台顯示器位於{2400,0,2400,1350}
,這實際上使桌面大小為{4800x1350}
和虛擬桌面大小{3840x1080}
,但我無法解釋的顯示器之間缺少像素,我不明白。
Screen 1 Screen 2
Actual Pixels: 1920x1080 2400x1350
Virtual Pixels: 1536x864 1920x1080
Top-Left Coord: 0x0 2400x0
Actual DPI: 120 (125%) 96 (100%)
Returned DPI: 120 (125%) 120 (125%)
我可以確認顯示器與DPI不同的另一種方法是將任何DPI識別應用程序的中心點拖過監視器之間的邊界,這將導致窗口將其大小更改為在顯示器之間保持一致(WPF默認情況下這樣做)。
我已經和這一天打架了一天,在發布問題后不到一個小時我找到了答案。 如果有人在將來遇到這個問題,我會在這里留下問題。
正如我在上面嘗試的那樣,獲取備用監視器DPI的正確方法是shcore.dll
的GetDpiForMonitor
方法。 問題是沒有盡早調用SetProcessDpiAwareness
來改變windows / wpf應用程序。 我通過創建一個新的控制台應用程序和一個新的wpf應用程序並用最少的代碼重現它來測試它。 控制台應用程序返回正確的值,而wpf應用程序返回不正確的值。
解決方案是將以下內容添加到清單文件中:
<application xmlns="urn:schemas-microsoft-com:asm.v3">
<windowsSettings>
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">True/PM</dpiAware>
</windowsSettings>
</application>
這里的關鍵是dpiAware標簽的值,它是True/PM
而不是True
,這就是它的不同之處。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.