To, czego szukam, jest odpowiednikiem System.Windows.SystemParameters.WorkArea
monitora, na którym aktualnie jest wyświetlane okno.
Wyjaśnienie: okno, o którym mowa WPF
, nie WinForm
.
To, czego szukam, jest odpowiednikiem System.Windows.SystemParameters.WorkArea
monitora, na którym aktualnie jest wyświetlane okno.
Wyjaśnienie: okno, o którym mowa WPF
, nie WinForm
.
Odpowiedzi:
Screen.FromControl
, Screen.FromPoint
I Screen.FromRectangle
powinien w tym pomóc. Na przykład w WinForms byłoby to:
class MyForm : Form
{
public Rectangle GetScreen()
{
return Screen.FromControl(this).Bounds;
}
}
Nie znam równoważnego wywołania WPF. Dlatego musisz zrobić coś takiego jak ta metoda rozszerzenia.
static class ExtensionsForWPF
{
public static System.Windows.Forms.Screen GetScreen(this Window window)
{
return System.Windows.Forms.Screen.FromHandle(new WindowInteropHelper(window).Handle);
}
}
window
monitora nad moim głównym (np ITS Top < 0
), FromHandle
powrócił Screen
do mojego głównego monitora (choć window
był całkowicie w ciągu monitor pomocniczy)!?! Westchnienie. Wygląda na to, że będę musiał sam przeszukać Screen.AllScreens
Array. Dlaczego rzeczy nie mogą „po prostu działać”?!? Arrrrgh.
Możesz użyć tego, aby uzyskać granice obszaru roboczego pulpitu na ekranie głównym:
System.Windows.SystemParameters.WorkArea
Jest to również przydatne do uzyskania rozmiaru ekranu głównego:
System.Windows.SystemParameters.PrimaryScreenWidth
System.Windows.SystemParameters.PrimaryScreenHeight
Możesz również potrzebować:
aby uzyskać łączny rozmiar wszystkich monitorów, a nie jednego w szczególności.
PresentationFramework.dll
iusing System.Windows;
Dodanie rozwiązania, które nie używa WinForms, ale zamiast tego NativeMethods. Najpierw musisz zdefiniować potrzebne metody natywne.
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;
}
}
A następnie zdobądź uchwyt monitora i takie informacje o monitorze.
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 );
}
Uważaj na współczynnik skalowania swoich okien (100% / 125% / 150% / 200%). Możesz uzyskać rzeczywisty rozmiar ekranu, używając następującego kodu:
SystemParameters.FullPrimaryScreenHeight
SystemParameters.FullPrimaryScreenWidth
Chciałem mieć rozdzielczość ekranu przed otwarciem pierwszego z moich okien, więc tutaj szybkie rozwiązanie, aby otworzyć niewidoczne okno przed faktycznym pomiarem wymiarów ekranu (musisz dostosować parametry okna do swojego okna, aby upewnić się, że oba są otwarte ten sam ekran - przede wszystkim WindowStartupLocation
ważny)
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();
To jest " rozwiązanie DotNet 4.5 ekranu centralnego ", używające SystemParameters zamiast System.Windows.Forms lub My.Compuer.Screen : Ponieważ Windows 8 zmienił obliczanie wymiarów ekranu, jedyny sposób, w jaki to działa dla mnie wygląda tak (Obliczanie paska zadań w zestawie):
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
Musiałem ustawić maksymalny rozmiar mojej aplikacji okiennej. Ten można odpowiednio zmienić, aplikacja jest wyświetlana na głównym ekranie lub w drugim. Aby rozwiązać ten problem, stworzyliśmy prostą metodę, którą pokażę dalej:
/// <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;
}
}
}
w C # winforms mam punkt startowy (w przypadku gdy mamy kilka monitorów / diplay i jeden formularz wywołuje inny) za pomocą następującej metody:
private Point get_start_point()
{
return
new Point(Screen.GetBounds(parent_class_with_form.ActiveForm).X,
Screen.GetBounds(parent_class_with_form.ActiveForm).Y
);
}
W przypadku konfiguracji z wieloma monitorami konieczne będzie również uwzględnienie pozycji X i Y:
Rectangle activeScreenDimensions = Screen.FromControl(this).Bounds;
this.Size = new Size(activeScreenDimensions.Width + activeScreenDimensions.X, activeScreenDimensions.Height + activeScreenDimensions.Y);
Ten kod debugujący powinien dobrze załatwić sprawę:
Możesz zbadać właściwości klasy ekranu
Umieść wszystkie ekrany w tablicy lub liście za pomocą Screen.AllScreens, a następnie przechwyć indeks bieżącego ekranu i jego właściwości.
C # (przekonwertowany z VB przez Telerik - sprawdź dokładnie)
{
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 (oryginalny kod)
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)