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


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.