활성 화면 크기를 얻으려면 어떻게해야합니까?


142

내가 찾고있는 것은 System.Windows.SystemParameters.WorkArea 것은 현재 창이있는 모니터 .

설명 : 문제 의 창이 WPF아닙니다 WinForm.


2
WPF 에서이 작업을 수행하는 가장 좋은 방법을 반영하도록 수락 된 답변을 변경했습니다. System.Windows.SystemParameters. *
— chilltemp

1
WinForms 네임 스페이스를 사용하지 않는 것에 대한 집착은 나에게 이상해 보인다. 대신 문제를 올바르게 해결하는 데 필요한 도구가 없습니다.
— Jeff Yates

4
저에게는 WinForms와 WPF가 아닙니다. 새로운 것을 배우는 것입니다. 두 가지 방법을 모두 배우지 않으면 어떤 방법이 더 좋은지 결정할 수 없습니다.
— chilltemp

3
글쎄,이 시나리오에서는 WinForms를 사용하는 방법이 하나뿐이므로 "두 가지 방법"이 없습니다.
— Jeff Yates

@ Jeff Yates : 맞습니다. 이 질문을 한 원래 프로젝트를 발굴하여 PrimaryScreen * 속성을 사용한 것을 발견했습니다. 그들은 오늘의 내 필요를 해결했지만 실제 질문은하지 않았습니다. 도망 가서 죄송합니다. 이에 따라 수락 된 답변을 변경했습니다.
— chilltemp

답변:


143

Screen.FromControl, Screen.FromPoint그리고 Screen.FromRectangle이 당신을 도움이 될 것입니다. 예를 들어 WinForms에서는 다음과 같습니다.

class MyForm : Form
{
  public Rectangle GetScreen()
  {
    return Screen.FromControl(this).Bounds;
  }
}

WPF에 해당하는 전화를 모릅니다. 따라서이 확장 방법과 같은 작업을 수행해야합니다.

static class ExtensionsForWPF
{
  public static System.Windows.Forms.Screen GetScreen(this Window window)
  {
    return System.Windows.Forms.Screen.FromHandle(new WindowInteropHelper(window).Handle);
  }
}

1
아마도 내 태깅으로 인해 WinForms가 아닌 WPF 창을 사용하고 있음이 명확하지 않았습니다. System.Windows.Forms.dll을 참조하지 않았으며 WPF에 자체 상속 트리가 있으므로 어쨌든 작동하지 않습니다.
— chilltemp

1
천만에요. 정답을 얻지 못한 것에 대한 사과-게시물을 업데이트하기 전에 WPF에서 사용할 수있는 것을 조사해야했습니다.
— Jeff Yates

오른쪽 가장자리에 창을 배치합니다. var bounds = this.GetScreen (). WorkingArea; this.Left = 범위. 오른쪽-this.Width; 그러나 이상적이지 않은 System.Windows.Forms 및 System.Drawing에 대한 참조가 필요합니다.
— Anthony

1
@devios이 통화는 DPI를 인식하지 못합니다. 계산을해야합니다.
— Lynn Crumbling

6
윈도우 10 프로 (v10.0.14393)와 내 4 모니터 시스템에 .NET 4.5을 목표로 내 VS 2015 WPF 응용 프로그램에서 window모니터에 이상 내 차의 (예를 들어, 그것의 Top < 0), FromHandle을 돌려 Screen내 차 모니터 (비록 window이었다 완전히 내 보조 모니터)!?! 한숨. Screen.AllScreens배열을 직접 검색해야 할 것 같습니다 . 왜 "그냥 작동"할 수 없습니까?!? Arrrrgh.
— Tom

62

이를 사용하여 기본 화면의 데스크탑 작업 공간 경계를 확보 할 수 있습니다.

System.Windows.SystemParameters.WorkArea

이것은 또한 기본 화면의 크기를 얻는 데 유용합니다.

System.Windows.SystemParameters.PrimaryScreenWidth System.Windows.SystemParameters.PrimaryScreenHeight


19
혼란 스러워요. 이것은 기본 화면 크기 만 반환하는 것 같습니다. 창이 현재있는 화면의 크기를 알고 싶습니다.
— VitalyB

1
이것은 질문에 대한 답이 아니며 기본 디스플레이의 크기를 가져 오려는 경우에도 WPF의 SystemParameters가 올바르지 않습니다. 픽셀이 아닌 장치 독립적 인 단위를 반환합니다 . 더 나은 구현을 위해 다음 답변을 참조하십시오 : stackoverflow.com/questions/254197/…
— Patrick Klug

1
PrimaryScreenHeight / Width는 예상대로 정확하게 작동했으며 MSDN에는 다음과 같은 기능이 있습니다. "기본 디스플레이 모니터의 화면 높이를 픽셀 단위로 나타내는 값을 가져옵니다." WorkArea는 픽셀을 구체적으로 말하지는 않지만 설명서 및 사용 예제를 통해 픽셀로도 생각합니다. 장치 독립 장치의 사용을 나타내는 링크가 있습니까?
— chilltemp


17

WinForms를 사용하지 않고 NativeMethods를 사용하는 솔루션 추가. 먼저 필요한 기본 메소드를 정의해야합니다.

public static class NativeMethods
{
    public const Int32 MONITOR_DEFAULTTOPRIMERTY = 0x00000001;
    public const Int32 MONITOR_DEFAULTTONEAREST = 0x00000002;


    [DllImport( "user32.dll" )]
    public static extern IntPtr MonitorFromWindow( IntPtr handle, Int32 flags );


    [DllImport( "user32.dll" )]
    public static extern Boolean GetMonitorInfo( IntPtr hMonitor, NativeMonitorInfo lpmi );


    [Serializable, StructLayout( LayoutKind.Sequential )]
    public struct NativeRectangle
    {
        public Int32 Left;
        public Int32 Top;
        public Int32 Right;
        public Int32 Bottom;


        public NativeRectangle( Int32 left, Int32 top, Int32 right, Int32 bottom )
        {
            this.Left = left;
            this.Top = top;
            this.Right = right;
            this.Bottom = bottom;
        }
    }


    [StructLayout( LayoutKind.Sequential, CharSet = CharSet.Auto )]
    public sealed class NativeMonitorInfo
    {
        public Int32 Size = Marshal.SizeOf( typeof( NativeMonitorInfo ) );
        public NativeRectangle Monitor;
        public NativeRectangle Work;
        public Int32 Flags;
    }
}

그런 다음 모니터 핸들과 이와 같은 모니터 정보를 얻습니다.

        var hwnd = new WindowInteropHelper( this ).EnsureHandle();
        var monitor = NativeMethods.MonitorFromWindow( hwnd, NativeMethods.MONITOR_DEFAULTTONEAREST );

        if ( monitor != IntPtr.Zero )
        {
            var monitorInfo = new NativeMonitorInfo();
            NativeMethods.GetMonitorInfo( monitor, monitorInfo );

            var left = monitorInfo.Monitor.Left;
            var top = monitorInfo.Monitor.Top;
            var width = ( monitorInfo.Monitor.Right - monitorInfo.Monitor.Left );
            var height = ( monitorInfo.Monitor.Bottom - monitorInfo.Monitor.Top );
        }

1
창의 스케일 팩터 (100 % / 125 % / 150 % / 200 %)가있는 경우 실제 화면 크기를 얻을 수 있습니까?
— Kiquenet


12

창의 배율을주의하십시오 (100 % / 125 % / 150 % / 200 %). 다음 코드를 사용하여 실제 화면 크기를 얻을 수 있습니다.

SystemParameters.FullPrimaryScreenHeight
SystemParameters.FullPrimaryScreenWidth

1
기본 화면입니다. 앱 창이 가상 (확장 된) 화면에있는 경우 (예 : PC에 하나 또는 두 개의 외부 모니터가 연결된 경우) 어떻게해야합니까?
— Matt

4

내 첫 번째 창을 열기 전에 화면 해상도를 원했기 때문에 실제로 화면 크기를 측정하기 전에 보이지 않는 창을 여는 빠른 솔루션 (두 창을 모두 열어 두려면 창 매개 변수를 창에 맞게 조정해야 함) 같은 화면-주로 WindowStartupLocation중요합니다)

Window w = new Window();
w.ResizeMode = ResizeMode.NoResize;
w.WindowState = WindowState.Normal;
w.WindowStyle = WindowStyle.None;
w.Background = Brushes.Transparent;
w.Width = 0;
w.Height = 0;
w.AllowsTransparency = true;
w.IsHitTestVisible = false;
w.WindowStartupLocation = WindowStartupLocation.Manual;
w.Show();
Screen scr = Screen.FromHandle(new WindowInteropHelper(w).Handle);
w.Close();

3

이것은 System.Windows.Forms 또는 My.Compuer.Screen 대신 SystemParameters 를 사용 하는 "중앙 화면 DotNet 4.5 솔루션 "입니다 . Windows 8 에서 화면 크기 계산 이 변경 되었으므로 나에게 맞는 유일한 방법은 다음과 같습니다 (작업 표시 줄 계산). 포함) :

Private Sub Window_Loaded(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles MyBase.Loaded
    Dim BarWidth As Double = SystemParameters.VirtualScreenWidth - SystemParameters.WorkArea.Width
    Dim BarHeight As Double = SystemParameters.VirtualScreenHeight - SystemParameters.WorkArea.Height
    Me.Left = (SystemParameters.VirtualScreenWidth - Me.ActualWidth - BarWidth) / 2
    Me.Top = (SystemParameters.VirtualScreenHeight - Me.ActualHeight - BarHeight) / 2         
End Sub

중앙 화면 WPF XAML


WPF에서 설치 관리자 설정?
— Kiquenet

주요 질문은 화면 위치에 관한 것입니다. Msi 설치 프로그램, Innosetup 또는 기타와 마찬가지로 CPU 확인, 권한 확인, 드라이버 확인 등을 사용하여 매우 간단한 자체 설치 프로그램을 만들었습니다. 스크린 샷입니다.
— Nasenbaer 19 :

3

내 창 응용 프로그램의 최대 크기를 설정해야했습니다. 응용 프로그램이 기본 화면 또는 보조 화면에 표시됨에 따라 변경 될 수 있습니다. 이 문제를 극복하기 위해 e는 다음에 보여줄 간단한 방법을 만들었습니다.

/// <summary>
/// Set the max size of the application window taking into account the current monitor
/// </summary>
public static void SetMaxSizeWindow(ioConnect _receiver)
{
    Point absoluteScreenPos = _receiver.PointToScreen(Mouse.GetPosition(_receiver));

    if (System.Windows.SystemParameters.VirtualScreenLeft == System.Windows.SystemParameters.WorkArea.Left)
    {
        //Primary Monitor is on the Left
        if (absoluteScreenPos.X <= System.Windows.SystemParameters.PrimaryScreenWidth)
        {
            //Primary monitor
            _receiver.WindowApplication.MaxWidth = System.Windows.SystemParameters.WorkArea.Width;
            _receiver.WindowApplication.MaxHeight = System.Windows.SystemParameters.WorkArea.Height;
        }
        else
        {
            //Secondary monitor
            _receiver.WindowApplication.MaxWidth = System.Windows.SystemParameters.VirtualScreenWidth - System.Windows.SystemParameters.WorkArea.Width;
            _receiver.WindowApplication.MaxHeight = System.Windows.SystemParameters.VirtualScreenHeight;
        }
    }

    if (System.Windows.SystemParameters.VirtualScreenLeft < 0)
    {
        //Primary Monitor is on the Right
        if (absoluteScreenPos.X > 0)
        {
            //Primary monitor
            _receiver.WindowApplication.MaxWidth = System.Windows.SystemParameters.WorkArea.Width;
            _receiver.WindowApplication.MaxHeight = System.Windows.SystemParameters.WorkArea.Height;
        }
        else
        {
            //Secondary monitor
            _receiver.WindowApplication.MaxWidth = System.Windows.SystemParameters.VirtualScreenWidth - System.Windows.SystemParameters.WorkArea.Width;
            _receiver.WindowApplication.MaxHeight = System.Windows.SystemParameters.VirtualScreenHeight;
        }
    }
}

1

C # winforms에서 다음 방법을 사용하여 시작 지점을 얻었습니다 (예 : 여러 모니터 / 디스플레이가 있고 한 양식이 다른 양식을 호출하는 경우).

private Point get_start_point()
    {
        return
            new Point(Screen.GetBounds(parent_class_with_form.ActiveForm).X,
                      Screen.GetBounds(parent_class_with_form.ActiveForm).Y
                      );
    }

1

WinForms

다중 모니터 설정의 경우 X 및 Y 위치도 고려해야합니다.

Rectangle activeScreenDimensions = Screen.FromControl(this).Bounds;
this.Size = new Size(activeScreenDimensions.Width + activeScreenDimensions.X, activeScreenDimensions.Height + activeScreenDimensions.Y);

0

이 디버깅 코드는 트릭을 잘 수행해야합니다.

스크린 클래스 의 속성을 탐색 할 수 있습니다

Screen.AllScreens 를 사용하여 모든 디스플레이를 배열 또는 목록에 넣은 다음 현재 디스플레이 및 해당 속성의 인덱스를 캡처합니다.

여기에 이미지 설명을 입력하십시오

C # (VB에서 Telerik으로 변환-다시 확인하십시오)

        {
    List<Screen> arrAvailableDisplays = new List<Screen>();
    List<string> arrDisplayNames = new List<string>();

    foreach (Screen Display in Screen.AllScreens)
    {
        arrAvailableDisplays.Add(Display);
        arrDisplayNames.Add(Display.DeviceName);
    }

    Screen scrCurrentDisplayInfo = Screen.FromControl(this);
    string strDeviceName = Screen.FromControl(this).DeviceName;
    int idxDevice = arrDisplayNames.IndexOf(strDeviceName);

    MessageBox.Show(this, "Number of Displays Found: " + arrAvailableDisplays.Count.ToString() + Constants.vbCrLf + "ID: " + idxDevice.ToString() + Constants.vbCrLf + "Device Name: " + scrCurrentDisplayInfo.DeviceName.ToString + Constants.vbCrLf + "Primary: " + scrCurrentDisplayInfo.Primary.ToString + Constants.vbCrLf + "Bounds: " + scrCurrentDisplayInfo.Bounds.ToString + Constants.vbCrLf + "Working Area: " + scrCurrentDisplayInfo.WorkingArea.ToString + Constants.vbCrLf + "Bits per Pixel: " + scrCurrentDisplayInfo.BitsPerPixel.ToString + Constants.vbCrLf + "Width: " + scrCurrentDisplayInfo.Bounds.Width.ToString + Constants.vbCrLf + "Height: " + scrCurrentDisplayInfo.Bounds.Height.ToString + Constants.vbCrLf + "Work Area Width: " + scrCurrentDisplayInfo.WorkingArea.Width.ToString + Constants.vbCrLf + "Work Area Height: " + scrCurrentDisplayInfo.WorkingArea.Height.ToString, "Current Info for Display '" + scrCurrentDisplayInfo.DeviceName.ToString + "' - ID: " + idxDevice.ToString(), MessageBoxButtons.OK, MessageBoxIcon.Information);
}

VB (원본 코드)

 Dim arrAvailableDisplays As New List(Of Screen)()
    Dim arrDisplayNames As New List(Of String)()

    For Each Display As Screen In Screen.AllScreens
        arrAvailableDisplays.Add(Display)
        arrDisplayNames.Add(Display.DeviceName)
    Next

    Dim scrCurrentDisplayInfo As Screen = Screen.FromControl(Me)
    Dim strDeviceName As String = Screen.FromControl(Me).DeviceName
    Dim idxDevice As Integer = arrDisplayNames.IndexOf(strDeviceName)

    MessageBox.Show(Me,
                    "Number of Displays Found: " + arrAvailableDisplays.Count.ToString & vbCrLf &
                    "ID: " & idxDevice.ToString + vbCrLf &
                    "Device Name: " & scrCurrentDisplayInfo.DeviceName.ToString + vbCrLf &
                    "Primary: " & scrCurrentDisplayInfo.Primary.ToString + vbCrLf &
                    "Bounds: " & scrCurrentDisplayInfo.Bounds.ToString + vbCrLf &
                    "Working Area: " & scrCurrentDisplayInfo.WorkingArea.ToString + vbCrLf &
                    "Bits per Pixel: " & scrCurrentDisplayInfo.BitsPerPixel.ToString + vbCrLf &
                    "Width: " & scrCurrentDisplayInfo.Bounds.Width.ToString + vbCrLf &
                    "Height: " & scrCurrentDisplayInfo.Bounds.Height.ToString + vbCrLf &
                    "Work Area Width: " & scrCurrentDisplayInfo.WorkingArea.Width.ToString + vbCrLf &
                    "Work Area Height: " & scrCurrentDisplayInfo.WorkingArea.Height.ToString,
                    "Current Info for Display '" & scrCurrentDisplayInfo.DeviceName.ToString & "' - ID: " & idxDevice.ToString, MessageBoxButtons.OK, MessageBoxIcon.Information)

화면 목록

당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.