2016-11-19 139 views
1

我的一些客戶希望能夠手動縮放我的應用程序(當Windows dpi設置爲96時),所以我必須實現縮放。不幸的是,這些客戶無法將Windows DPI設置爲其他值,並讓WIndows擴展我的應用程序,因爲他們使用的一些非常重要的應用程序在分辨率爲<> 96 DPI時表現不佳。Delphi自己的縮放和Windows縮放之間的高DPI切換

我設法讓我的Delphi 10.1應用程序的規模在200%的情況下仍然很好,但因子越高,一些比例就越「變得不那麼好看」。許多第三方組件需要特殊的縮放處理,即使這樣也不能100%準確地進行縮放。雖然窗口縮放的應用程序在高分辨率下看起來有點模糊,但所有比例都是100%準確的,而且應用程序看起來更專業。

所以我問自己是否有可能創建一個設置,允許告訴Windows將縮放比作爲默認設置,並且只有當客戶需要與當前Windows縮放比例不同的縮放比例時纔可以自行縮放。此設置位於在應用程序啓動時讀取的可執行文件的Windows清單中。有沒有辦法在運行時更改它(應用程序的早期啓動)?用不同清單創建兩個可執行文件當然不是好的解決方案。

感謝所有幫助

+0

您提到的設置是「」嗎?如果是這樣,請參見[SetProcessDpiAwareness](https://msdn.microsoft.com/en-us/library/dn302122(v = vs.85).aspx)中的註釋。 –

+0

謝謝,我會盡力的! – MichaSchumann

+1

爲什麼我的問題被拒絕? – MichaSchumann

回答

6

感謝Sertac Akyuz我找到了解決我的問題。在包含縮放代碼的單元的初始化部分中,我可以在DPI感知和非DPI感知之間切換。

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> 
<dependency> 
    <dependentAssembly> 
    <assemblyIdentity 
     type="win32" 
     name="Microsoft.Windows.Common-Controls" 
     version="6.0.0.0" 
     publicKeyToken="6595b64144ccf1df" 
     language="*" 
     processorArchitecture="*"/> 
    </dependentAssembly> 
</dependency> 
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3"> 
    <security> 
    <requestedPrivileges> 
     <requestedExecutionLevel 
     level="asInvoker" 
     uiAccess="false"/> 
     </requestedPrivileges> 
    </security> 
</trustInfo> 
</assembly> 

這是實際的代碼轉換:不要在應用程序清單,可以通過這樣提供一個定製清單來實現此設置(使用控制裝修,並與當前用戶的權限運行)是非常重要的根據註冊表項:

// Set DPI Awareness depending on a registry setting 
with TRegIniFile.create('SOFTWARE\' + SRegName) do 
begin 
    setting := readInteger('SETTINGS', 'scale', 0); 
    Free; 
end; 
handle := LoadLibrary('shcore.dll'); 
if handle <> 0 then 
begin 
    setProcessDPIAwareness := GetProcAddress(handle, 'SetProcessDpiAwareness'); 
    if Assigned(setProcessDPIAwareness) then 
    begin 
    if setting < 2 then 
     // setting <2 means no scaling vs Windows 
     setProcessDPIAwareness(0) 
    else 
     // setting 2: 120%, 3: 140% vs. Windows 
     // The actual used scaling factor multiplies by windows DPI/96 
     setProcessDPIAwareness(1); 
    end; 
    FreeLibrary(handle); 
    // Get windows scaling as Screen.PixelsPerInch was read before swiching DPI awareness 
    // Our scaling routines now work with WinDPI instead of Screen.PixelsPerInch 
    WinDPI:= Screen.MonitorFromWindow(application.handle).PixelsPerInch; 
end; 

這個片段的最後一行檢索當前監視器的當前DPI爲screen.pixelsperinch好像之前被初始化,並始終返回96作爲非DPI感知的應用程序。我在隨後的所有縮放計算中使用winDPI的值,並且它非常完美。

+0

經過一遍又一遍的思考後,我得出結論:我的方法比必要的複雜得多。如果用戶請求,我認爲我可以將應用程序設置爲不識別dpi,並將其放在頂部。這樣可以避免在Surface或我的Lenovo 900s等設備上出現高比例因子,如果我按比例縮放140%,並且設備需要其他200%,導致280%的e。 G。表面親。 – MichaSchumann

+0

我的解決方案可能有助於某人搜索在運行時識別非dpi識別和dpi識別的可能性。 I(= blockhead)忽略了將Windows縮放比例(非dpi分辨率)和我自己的縮放比例(例如用於輕微可見的受損人羣)的可能性。它現在運行良好,比例很好,因爲我的最大比例爲140%。 – MichaSchumann