Як я можу отримати активні розміри екрана?


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: Ви маєте рацію. Я розкопав оригінальний проект, для якого я задав це питання, і виявив, що я використовував властивості 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
Можливо, мій тег не дав зрозуміти, що я використовую WPF windows, а не WinForms. У мене немає посилання на System.Windows.Forms.dll, і це все одно не працюватиме, оскільки WPF має своє дерево спадкування.
chilltemp

1
Ласкаво просимо. Мої вибачення за те, що я не отримав прямо відповіді - мені довелося розслідувати, що було доступно у WPF, перш ніж я оновив свою посаду.
Джефф Йейтс

Це працює, щоб поставити вікно з правого краю: var bounds = this.GetScreen (). WorkingArea; this.Left = bounds.Right - this.Width; Але для цього потрібні посилання на System.Windows.Forms та System.Drawing, що не ідеально.
Ентоні

1
@devios Остерігайтеся, що цей дзвінок не відомий DPI; вам потрібно буде зробити розрахунки.
Лінн Кришиться

6
У моєму VS 2015 WPF додатки таргетингу .NET 4.5 на моїй системі 4-монітора на Windows 10 Pro (v10.0.14393) з windowна моніторі вище моїх первинних (наприклад, його Top < 0), FromHandleповернув Screenдля мого первинного монітора (хоча і windowбув повністю в межах вторинний монітор)!?! Зітхнути. Схоже, мені доведеться самостійно шукати Screen.AllScreensмасив. Чому речі не можуть "просто працювати"?!? Arrrrgh.
Том

62

Ви можете використовувати це для отримання меж робочого простору робочого столу основного екрану:

System.Windows.SystemParameters.WorkArea

Це також корисно для отримання лише розміру основного екрана:

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


19
Я розгублений ... Це, здається, лише повертає основні розміри екрана. Хочу знати розміри екрана, у якому зараз знаходиться вікно ...
VitalyB

1
це не відповідає на запитання, і навіть якщо ви просто хочете отримати розмір основного дисплея, SystemParameters (у WPF) невірні. вони повертають незалежні пристрої, а не пікселі. для кращої реалізації дивіться цю відповідь: stackoverflow.com/questions/254197/…
Патрік Клюг

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%)?
Кікенет


12

Остерігайтеся коефіцієнта масштабу ваших вікон (100% / 125% / 150% / 200%). Ви можете отримати реальний розмір екрана, скориставшись наступним кодом:

SystemParameters.FullPrimaryScreenHeight
SystemParameters.FullPrimaryScreenWidth

1
Це для основного екрану - що робити, якщо вікно вашої програми знаходиться на віртуальному (розширеному) екрані (тобто у вас на ПК приєднано один або два зовнішніх монітора)?
Метт

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

Це "Центр екрану DotNet 4.5 ", використовуючи SystemParameters замість System.Windows.Forms або My.Compuer.Screen : Оскільки 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?
Кікенет

Головне питання щодо положення екрана. Як і інсталятор Msi, Innosetup або інші, я створив власного інсталятора з перевіркою процесора, перевірки дозволу, перевірки драйверів та багато іншого, дуже простого у користуванні. Ось скріншот про.
Nasenbaer

3

Мені потрібно було встановити максимальний розмір програми для вікон. Це може змінитися відповідно, додаток відображається на первинному екрані або у вторинному. Щоб подолати цю проблему, я створив простий метод, який я вам покажу далі:

/// <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)

Список екранів

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.