2016-11-19 19 views
1

일부 고객은 내 응용 프로그램을 수동으로 확장 할 수 있기를 원합니다. Windows dpi가 96로 설정되었을 때 스케일링을 구현해야했습니다. 불행히도이 고객들은 Windows DPI를 다른 값으로 설정하지 않고 WIndows에서 내 응용 프로그램을 확장 할 수 없습니다. 왜냐하면 사용하는 매우 중요한 응용 프로그램 중 일부는 해상도가 <> 96 DPI 인 경우 동작하지 않기 때문입니다.델파이 자신의 스케일링과 윈도우 스케일링 사이의 높은 DPI 전환

필자도 Delphi 10.1 응용 프로그램을 200 %까지 확장 할 수 있었지만 그 비율이 높을수록 "보기 좋지 않은"비율이 더 많아졌습니다. 많은 타사 구성 요소에는 크기 조정을위한 특수 처리가 필요하며 심지어 100 % 정확하지 않습니다. Windows로 확장 된 응용 프로그램은 고해상도에서 약간 흐리게 보이지만 모든 비율은 100 % 정확하며 응용 프로그램이 훨씬 더 전문적으로 보입니다.

그래서 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> 

:이 같은 사용자 정의 매니페스트를 공급함으로써 달성 될 수있는 응용 프로그램 매니페스트에서 설정이 (사용 제어 장식 및 현재 사용자의 권한으로 실행)하지 않는 것이 중요합니다 레지스트리 키에 따라 : screen.pixelsperinch 전에 초기화 할 것으로 보인다 항상 비 dpi로 인식 응용 프로그램으로 96을 반환 않는

// 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를 검색합니다. 나는 모든 후속 스케일링 계산에서 winDPI의 가치를 사용하며 완벽하게 작동합니다.

+0

다시 한 번 생각한 후에 필자의 접근 방식이 필요한 것보다 훨씬 복잡하다는 결론에 도달했습니다. 사용자가 요청하면 앱을 비 dpi 인식으로 설정하고 상단으로 확장 할 수 있다고 생각합니다. 이렇게하면 표면 또는 140 %로 스케일링하면 Lenovo 900s와 같은 디바이스에서 높은 스케일링 계수를 피할 수 있고 디바이스는 다른 200 %를 필요로하여 e에서 280 %가됩니다. 지. 표면 프로. – MichaSchumann

+0

내 솔루션은 런타임에 비 dpi 인식과 dpi 인식 사이를 전환 할 가능성을 찾는 데 도움이 될 수 있습니다. I (= blockhead)는 Windows 스케일링 (비 dpi 인식)과 내 스케일링 (예 : 가벼운 시각 장애인 용)을 결합 할 수있는 가능성을 간과했습니다. 내 최대 배율이 140 %이므로 잘 작동하며 비율도 괜찮습니다. – MichaSchumann