アクティブな画面の寸法を取得するにはどうすればよいですか?


142

私が探しているのはSystem.Windows.SystemParameters.WorkArea、ウィンドウが現在オンになっているモニターと同等です。

明確化: 問題のウィンドウはWPFではなくWinFormです。


2
WPFからこれを行うための最良の方法を反映するために、受け入れられた回答を変更しました。System.Windows.SystemParameters。*
chilltemp

1
WinForms名前空間を使用しないことに執着しているのは奇妙に思えますが、何も得られません。代わりに、問題を適切に解決するために必要なツールがなくなります。
ジェフイェーツ

4
私にとっては、WinFormsとWPFの違いではありません。新しいことを学ぶことです。両方の方法を学ばなければ、どちらの方法が優れているかを判断できません。
chilltemp 2011年

3
まあ、このシナリオでは、WinFormsを使用するという1つの方法しかないため、「両方の方法」はありません。
ジェフイエーツ、2011年

@ジェフイェーツ:あなたは正しいです。この質問をした元のプロジェクトを調べたところ、PrimaryScreen *プロパティを使用していることがわかりました。彼らはその日の私のニーズを解決しましたが、私が尋ねた実際の質問ではありませんでした。走り回ってごめんなさい。それに応じて、受け入れられた回答を変更しました。
chilltemp 2011年

回答:


143

Screen.FromControlScreen.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 2008年

1
どういたしまして。正直に答えられなかったことをお詫びします。投稿を更新する前に、WPFで利用できるものを調査する必要がありました。
ジェフイェーツ

これは、ウィンドウを右端に配置するように機能します。var bounds = this.GetScreen()。WorkingArea; this.Left = bounds.Right-this.Width; ただし、System.Windows.FormsおよびSystem.Drawingへの参照が必要であり、理想的ではありません。
アンソニー

1
@deviosこの呼び出しはDPI対応ではないことに注意してください。計算を行う必要があります。
Lynn Crumbling 2015

6
でWindows 10のPro(v10.0.14393)の私の4 -モニターシステム上で.NET 4.5をターゲットに私のVS 2015 WPFアプリでwindowモニターに上記の私のプライマリの(例えば、そのTop < 0)、FromHandle返されScreenていても(私のプライマリモニタのためwindowだった完全に内セカンダリモニター)!?!はぁ。Screen.AllScreens自分でアレイを検索する必要があるようです。なぜ「うまくいかない」のか?!?ああ。
トム

62

これを使用して、プライマリ画面のデスクトップワークスペースの境界を取得できます。

System.Windows.SystemParameters.WorkArea

これは、主画面のサイズだけを取得する場合にも役立ちます。

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


19
私は混乱しています...これは、プライマリ画面の寸法を返すようです。ウィンドウが現在ある画面の寸法を知りたい...
VitalyB

1
これは質問には答えません。プライマリディスプレイのサイズを取得したいだけの場合でも、(WPFの)SystemParametersは正しくありません。ピクセルではなく、デバイスに依存しない単位を返します。より高度な実装のためにこの回答を参照してください。stackoverflow.com/questions/254197/...
パトリックKLUG

1
PrimaryScreenHeight / Widthは期待どおりに機能し、MSDNには次のように記載されています。「プライマリディスプレイモニターの画面の高さ(ピクセル単位)を示す値を取得します。」WorkAreaはピクセルを具体的に述べていませんが、ドキュメントと使用例は、ピクセルでもあると私に信じさせます。デバイスに依存しないユニットの使用を示すものへのリンクはありますか?
chilltemp 2011年


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
これはメイン画面用です-アプリウィンドウが仮想(拡張)画面上にある場合(つまり、1つまたは2つの外部モニターがPCに接続されている場合)はどうなりますか?
マット

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

これは、「センター画面で過去ログ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でのインストーラーのセットアップ?
Kiquenet

主な質問は、画面の位置についてです。Msiインストーラー、Innosetupなどのように、CPUチェック、アクセス許可チェック、ドライバー検証など、使用方法が非常に簡単な独自のインストーラーを作成しました。それはスクリーンショットです。
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には、次のメソッドの助けを借りて、スタートポイントがあります(複数のモニター/ディスプレイがあり、1つのフォームが別のフォームを呼び出している場合)。

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クラスのプロパティを探索できます

Screen.AllScreensを使用してすべてのディスプレイを配列またはリストに配置し、現在のディスプレイのインデックスとそのプロパティをキャプチャします。

ここに画像の説明を入力してください

C# (TelerikによってVBから変換-再確認してください)

        {
    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.