2015-01-16 3 views
8

제어판에서 설정 한 해상도와 내 와이드 스크린 노트북의 Screen.Bounds 출력 사이에 흥미로운 차이가 있습니다. 화면은 15.5입니다 "하고 제어판을 통해 설정 한 해상도는 1920 × 1080이다. 그러나 나는이 같은 일부 코드를 실행하면.화면 해상도가 Screen.Bounds가 일치하지 않습니다.

Screen[] screens = Screen.AllScreens; 
foreach (Screen scr in screens) 
{ 
    Console.WriteLine("Width: " + scr.Bounds.Width + ", Height: " + scr.Bounds.Width); 
} 

출력은 1536x864되는 내 해상도가. 좀 둘러보고했을 표시하고 나는 그것을 생각 DPI 문제와 관련이있을 수 있으며 디스플레이 설정을 볼 때 슬라이더 (Windows 8.1)가 중간에 있고 "모든 디스플레이에 하나의 크기 조정 레벨을 선택하게하십시오"라는 확인란이 선택 취소되어 있습니다 . 나는 현재의 DPI 설정을 얻기 위해이 작은 코드를 실행했습니다.

float dpiX, dpiY; 
Graphics graphics = new System.Windows.Forms.Form().CreateGraphics(); 
Console.WriteLine("DPI: " + graphics.DpiX); 

100 % DPI의 setti은 나의 이해로하는 96.0입니다 반환되는 DPI를 ng (아무런 확대 나 그게 뭐든간에). 내가보기에 이상하게 여겨지는 것은 Screen에 의해 반환 된 경계가 내 실제 해상도의 정확히 80 %이기 때문에 내 DPI가 100 (또는 125 %)으로 설정되어 있다고 생각하지만 실제로는 그렇지 않습니다. 보조 모니터가 제어판을 통한 해상도와 동일한 경계를 가지기 때문에이 문제는 노트북 화면에서만 발생합니다. 이는 내 DPI 설정이 디스플레이를 서로 독립적으로 설정하지 않기 때문에 (확인란이 선택됨)? 약간의 배경 지식으로 현재 화면을 가져 와서 reddit에서 그림을 가져 와서 서로 독립적으로 화면에 맞출 수있는 도구를 쓰고 있습니다. 따라서 어떤 솔루션을 사용하든 각 디스플레이의 해상도를 올바르게 가져야합니다.

+0

첫 번째 코드 예제에서'scr.Bounds..Primary'는 실제로'scr.Bounds.Height'이어야한다고 생각하십니까? –

+0

"모든 디스플레이에 하나의 스케일링 레벨을 선택하게하십시오"가 ** 선택 해제되어 ** 확실한 경우 각 스크린마다 다른 DPI가 설정되어 있습니까? –

+0

@StevenRands가 예제를 수정했으며 그 경우라고 생각 하겠지만,이 상자를 선택하지 않으면 두 화면의 DPI가 여전히 96.0입니다. DPI를받는 방식에 뭔가 잘못하고 있습니까? –

답변

3

귀하의 응용 프로그램이 DPI를 인식하고 있음을 운영 체제에 알려야한다고 생각합니다. 그렇지 않으면 OS는 모든 것이 잘되는 것으로 가장하여 OS가 크기 조정을 처리한다는 것을 관찰합니다.

DPI 인식 응용 프로그램 작성에 대한 정보는 여기에서 확인할 수 있습니다. http://msdn.microsoft.com/cs-cz/library/dd464646.aspx 물론 응용 프로그램이 인지 확인하려면 DPI 인식을 선택하십시오. 그렇지 않은 경우 기본값을 그대로 사용하는 것이 좋습니다. 그것은 좋지는 않지만 적어도 작동 할 것입니다.

Windows 8.1의 주된 차이점은 다른 모니터에 다른 DPI를 가질 수 있으며 모니터 DPI API를 쿼리 할 수 ​​있다는 것입니다. .NET (특히 WPF)은 기본적으로 DPI 인식을 자동으로 처리하지만 시스템 DPI 만 기반으로합니다. 모니터의 DPI 설정이 다르면 비 DPI 인식 (정확하게 말해서 시스템 DPI 인식이지만 궁극적으로 Windows에서 응용 프로그램 그래픽을 가상화하게됩니다)으로 작동합니다. 두 번째 디스플레이를 분리하면 응용 프로그램이 단독 디스플레이에서 예상대로 작동 할 것입니다 (적어도 DPI를 설정 한 후에는 그 값이 무엇이든간에).

+0

감사합니다. 도움이됩니다. 두 모니터의 DPI를 동시에 얻을 수있는 방법이 있는지 알고 있습니까? 주어진 예제는 WPF 앱을 모니터 (랩톱의 경우 120 개, 2 차의 경우 96 개)로 이동할 때 작동하지만 두 번째 모니터의 DPI는 해당 앱을 이동하지 않고도 가져와야합니다. –

+0

@Issac 각 모니터마다 DPI를 얻으려면 P/Invoke를 통해 [GetDpiForMonitor] (http://msdn.microsoft.com/en-us/library/windows/desktop/dn280510.aspx) 함수를 호출해야합니다. Per-Monitor DPI에 대한 일반적인 개요를 보려면 [DPI 인식 데스크톱 및 Win32 응용 프로그램 작성] (http://msdn.microsoft.com/en-us/library/windows/desktop/dn469266.aspx)을 확인하십시오. – emoacht

+0

@IsaacLevin 당신이 그렇게해야합니까? 응용 프로그램이 monitor-DPI를 인식하는지 확인하면 올바른 화면 범위를 얻게됩니다. DPI 나 다른 무언가의 결의안을 곱하려고하는 것입니까? 폼은 실제로'Screen.Bounds'에 의해보고 된 것처럼 다른 디스플레이에 더 적은 공간을 갖습니다. – Luaan

9

스크린 샷 도구에서도 같은 문제가있었습니다. 해결책을 찾았으며 제대로 작동합니다. 응용 프로그램에서 일부 UI가있는 경우

private enum ProcessDPIAwareness 
{ 
    ProcessDPIUnaware = 0, 
    ProcessSystemDPIAware = 1, 
    ProcessPerMonitorDPIAware = 2 
} 

[DllImport("shcore.dll")] 
private static extern int SetProcessDpiAwareness(ProcessDPIAwareness value); 

private static void SetDpiAwareness() 
{ 
    try 
    { 
    if (Environment.OSVersion.Version.Major >= 6) 
    { 
     SetProcessDpiAwareness(ProcessDPIAwareness.ProcessPerMonitorDPIAware); 
    } 
    } 
    catch (EntryPointNotFoundException)//this exception occures if OS does not implement this API, just ignore it. 
    { 
    } 
} 

당신은 지금 높은 DPI로 화면에 UI를 확장하는 것은 귀하의 책임입니다 또한 등 시스템 해상도, 를 얻기 위해 전화 기능 전에 SetDpiAwareness() 메소드를 호출해야합니다.

희망이 도움이됩니다.

+0

감사합니다. 이 유일한 해결책은 Windows 8.1에서 스크린 공유 프로그램과 스케일링을 도와주었습니다. – Art

+1

Windows 7에서이 코드를 사용하면 해상도를 조정할 필요가 없지만이 코드가 Windows 7에서 실행되면 catch ' 던져진 오류를 잡으면 프로그램이 중단됩니다. 확인중인 오류를 변경해야합니다. 또는 제 경우에는 예외를 잡으려고 설정했습니다. – Byte11

관련 문제