簡體   English   中英

檢索輔助監視器的DPI的正確方法是什么?

[英]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.dllGetDpiForMonitor方法。 問題是沒有盡早調用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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM