DPI 설정 (예 : 150 %)이 높은 컴퓨터에서 올바르게 실행되도록 앱을 구성하는 방법은 무엇입니까?


101

C #으로 간단한 Winforms 응용 프로그램을 만들었습니다. DPI 설정 (예 : 150 %)이 높은 컴퓨터에서 응용 프로그램을 실행하면 응용 프로그램이 확장됩니다. 여태까지는 그런대로 잘됐다! 그러나 더 큰 글꼴 크기로 글꼴을 렌더링하는 대신 모든 텍스트도 확대됩니다. 물론 이것은 매우 흐릿한 텍스트로 이어집니다 (버튼 등과 같은 모든 컨트롤에서).

창에서 텍스트를 올바르게 렌더링해야하지 않습니까? 예를 들어 내 응용 프로그램의 제목 표시 줄이 선명하고 깨끗하게 렌더링됩니다.

답변:


131

100 % (또는 "XP 스타일 DPI 크기 조정"확인란을 선택한 상태에서 125 %)를 지나면 기본적으로 Windows가 UI 크기 조정을 수행합니다. 앱에서 출력을 비트 맵으로 렌더링하고 해당 비트 맵을 화면에 그리면됩니다. 해당 비트 맵의 ​​크기를 조정하면 필연적으로 텍스트가 흐릿하게 보입니다. "DPI 가상화"라는 기능으로 고해상도 모니터에서 오래된 프로그램을 계속 사용할 수 있습니다.

<dpiAware>매니페스트에 요소를 추가하여 더 높은 DPI 설정을 처리 할 수 ​​있음을 명시 적으로 알려야합니다 . MSDN 페이지 는 여기에 있지만 UAC 설정을 생략하고 있으므로 완전하지 않습니다. 프로젝트 + 새 항목 추가, "응용 프로그램 매니페스트 파일"을 선택합니다. 매니페스트 텍스트를 편집하거나 복사 / 붙여 넣기 :

<?xml version="1.0" encoding="utf-8"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3" >
    <assemblyIdentity version="1.0.0.0" name="MyApplication.app"/>
    <trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
        <security>
            <requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
                <requestedExecutionLevel level="asInvoker" uiAccess="false" />
            </requestedPrivileges>
        </security>
    </trustInfo>
    <asmv3:application>
        <asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
            <dpiAware>true</dpiAware>
        </asmv3:windowsSettings>
    </asmv3:application>
</assembly>

Main () 메서드에서 SetProcessDPIAware ()를 고정 할 수도 있습니다. 예를 들어 ClickOnce로 배포하는 경우 필요합니다.

    [STAThread]
    static void Main() {
        if (Environment.OSVersion.Version.Major >= 6) SetProcessDPIAware();
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new Form1());             // Edit as needed
    }

    [System.Runtime.InteropServices.DllImport("user32.dll")]
    private static extern bool SetProcessDPIAware();

업데이트, VS2015 업데이트 1 이상을 사용하면 이러한 일반적인 요구가 마침내 조금 더 쉬워집니다. 추가 된 매니페스트에는 이미 관련 지시문이 있습니다. 주석 만 제거하면됩니다.


이 게시물을 다시 찾을 수 있도록 검색 키워드 : dpiAware


감사합니다. 솔루션이 제대로 작동합니다. 남은 유일한 문제는 모든 이미지가 이제 원래 크기에 있다는 것입니다. GUI에 "레티 나"아이콘을 추가하는 방법을 찾아야 할 것 같습니다 ...
Boris

@HansPassant 나는 흐릿한 글꼴과 동일한 문제가 있으며이 솔루션을 적용한 후 컨트롤이 확장되지 않고 맞지 않습니다. 둘 다 작동하게하는 방법?
gajo357

2
이 Win8 광기를 조사하는 사람에게는 SetProcessDPIAware더 이상 사용되지 않으며 제대로 작동하지 않아 (적어도 Win8.1에서는 그렇지 않음) 다른 컨트롤에서 예측할 수없는 확장이 발생합니다. 대신 매니페스트 접근 방식을 사용하는 것이 좋습니다.
Jason Williams

5
Hmya, Windows 8.1은 모니터 별 DPI를 획득했습니다. 나는 그것이 필요하다는 것을 몰랐습니다.
Hans Passant 2014-08-27

1
배포에 ClickOnce를 사용하려는 경우 매니페스트에서 dpiAware 옵션을 사용할 수 없으며 대신 SetProcessDPIAware ()를 사용합니다.
Matías 2015 년

17

응용 프로그램은 두 가지 모드로 개발할 수 있습니다.

첫 번째는 애플리케이션이 DPI를 인식하지 못하도록 선언하는 것입니다 (아무것도 선언하지 않으면 기본값이됩니다). 이 경우 운영 체제는 예상되는 96 DPI로 응용 프로그램을 렌더링 한 다음 이전에 논의한 비트 맵 크기 조정을 수행합니다. 결과는 흐릿하게 보이지만 레이아웃이 올바른 응용 프로그램이됩니다.

두 번째 옵션은 응용 프로그램을 DPI 인식으로 선언하는 것입니다. 이 경우 OS는 크기 조정을 수행하지 않으며 응용 프로그램이 화면의 원래 DPI에 따라 렌더링되도록합니다. 모니터 별 DPI 환경의 경우 응용 프로그램이 모든 화면 중 가장 높은 DPI로 렌더링 된 다음이 비트 맵이 각 모니터에 적합한 크기로 축소됩니다. 축소는 확장보다 더 나은보기 경험을 제공하지만 여전히 약간의 흐릿함을 느낄 수 있습니다.

이를 방지하려면 애플리케이션을 모니터 별 DPI 인식으로 선언해야합니다. 그런 다음 애플리케이션이 다른 모니터로 드래그되는시기를 감지하고 현재 모니터의 DPI에 따라 렌더링해야합니다.

DPI 인식 선언은 매니페스트 파일에서 수행됩니다.

다음 링크 스택 오버플로를 참조하십시오.


사용자가 복원 된 크기 의 창을 가지고 있고 일부가 다른 모니터에 표시되도록 이동하면 어떻게 될까요? 모든 것을 두 번 렌더링하고 모니터 경계를 경계 상자로 사용해야합니까? winforms 라이브러리가 얼마나 많은 것을 다룹니까?
Cee McSharpface

4

.NET Framework 4.7 및 Windows 10 Creators Update (1703) 이상을 사용하여 Windows Form 애플리케이션에 대한 높은 DPI 지원을 구성하려면 다음 작업을 수행해야합니다.

Windows 10과의 호환성을 선언합니다.

이렇게하려면 manifest파일에 다음을 추가 하십시오.

<compatibility xmlns="urn:schemas-microsoft.com:compatibility.v1">
  <application>
    <!-- Windows 10 compatibility -->
    <supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" />
  </application>
</compatibility>

app.config파일 에서 모니터 별 DPI 인식을 활성화 합니다.

Windows Forms 에는 .NET Framework 4.7부터 추가 된 새로운 기능 및 사용자 지정을 지원 하는 새로운 System.Windows.Forms.ApplicationConfigurationSection 요소가 도입 되었습니다. 높은 DPI를 지원하는 새로운 기능을 활용하려면 애플리케이션 구성 파일에 다음을 추가하십시오.

<System.Windows.Forms.ApplicationConfigurationSection>
  <add key="DpiAwareness" value="PerMonitorV2" />
</System.Windows.Forms.ApplicationConfigurationSection>

중대한

이전 버전의 .NET Framework에서는 매니페스트를 사용하여 높은 DPI 지원을 추가했습니다. 이 접근 방식은 app.config 파일에 정의 된 설정을 재정의하므로 더 이상 권장되지 않습니다.

정적 EnableVisualStyles 메서드를 호출합니다.

이것은 애플리케이션 진입 점의 첫 번째 메서드 호출이어야합니다. 예를 들면 :

static void Main()
{
    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);
    Application.Run(new Form1());   
}

이것의 장점은 Windows Forms 응용 프로그램이 시작된 후 사용자가 DPI 또는 배율을 변경하는 동적 DPI 시나리오를 지원한다는 것입니다.

출처 : Windows Forms에서 높은 DPI 지원


3

이 제안 중 어느 것도 나를 위해 일하지 않았지만 Form.Font = new...에서 ...를 제거한 후 어떤 일이 발생 Form.Design.cs했습니다. 형식이 제대로 크기 조정되기 시작했습니다. 글꼴이 생성자에 정의되어 있는지 여부에 관계없이 작동합니다. 왜? 다른 누군가가 설명 할 수있을 것입니다. 저는 제가 변경 한 사항에 대해 이야기 할 수 있고 제가 작업중인 양식의 근본 원인이라는 것을 파악하는 데 몇 분이 걸렸습니다. 도움이되기를 바랍니다.


2

Visual Studio 2017 이상부터 매니페스트 파일을 추가하고이 섹션의 주석 처리를 제거하면됩니다.

<application xmlns="urn:schemas-microsoft-com:asm.v3">
    <windowsSettings>
        <dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true</dpiAware>
    </windowsSettings>
</application>
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.