Quello che sto cercando è l'equivalente di System.Windows.SystemParameters.WorkArea
per il monitor su cui la finestra è attualmente attiva.
Chiarimento: la finestra in questione è WPF
no WinForm
.
Quello che sto cercando è l'equivalente di System.Windows.SystemParameters.WorkArea
per il monitor su cui la finestra è attualmente attiva.
Chiarimento: la finestra in questione è WPF
no WinForm
.
Risposte:
Screen.FromControl
, Screen.FromPoint
E Screen.FromRectangle
dovrebbe aiutare con questo. Ad esempio in WinForms sarebbe:
class MyForm : Form
{
public Rectangle GetScreen()
{
return Screen.FromControl(this).Bounds;
}
}
Non conosco una chiamata equivalente per WPF. Pertanto, devi fare qualcosa di simile a questo metodo di estensione.
static class ExtensionsForWPF
{
public static System.Windows.Forms.Screen GetScreen(this Window window)
{
return System.Windows.Forms.Screen.FromHandle(new WindowInteropHelper(window).Handle);
}
}
window
sul monitor sopra quello della mia Primaria (ad esempio, il suo Top < 0
), ha FromHandle
restituito il Screen
monitor per il mio Primario (anche se window
era completamente all'interno il monitor secondario)!?! Sospiro. Sembra che dovrò cercare l' Screen.AllScreens
Array da solo. Perché le cose non "funzionano"?!? Arrrrgh.
Puoi usarlo per ottenere i limiti dell'area di lavoro desktop della schermata principale:
System.Windows.SystemParameters.WorkArea
Questo è utile anche per ottenere solo le dimensioni dello schermo principale:
System.Windows.SystemParameters.PrimaryScreenWidth
System.Windows.SystemParameters.PrimaryScreenHeight
Inoltre potresti aver bisogno di:
per ottenere la dimensione combinata di tutti i monitor e non uno in particolare.
PresentationFramework.dll
eusing System.Windows;
Aggiunta di una soluzione che non utilizza WinForms ma NativeMethods. Innanzitutto è necessario definire i metodi nativi necessari.
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;
}
}
E quindi ottenere la maniglia del monitor e le informazioni del monitor in questo modo.
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 );
}
Fai attenzione al fattore di scala delle tue finestre (100% / 125% / 150% / 200%). È possibile ottenere le dimensioni reali dello schermo utilizzando il seguente codice:
SystemParameters.FullPrimaryScreenHeight
SystemParameters.FullPrimaryScreenWidth
Volevo avere la risoluzione dello schermo prima di aprire la prima delle mie finestre, quindi qui una soluzione rapida per aprire una finestra invisibile prima di misurare effettivamente le dimensioni dello schermo (è necessario adattare i parametri della finestra alla finestra per assicurarsi che entrambi siano aperti lo stesso schermo - principalmente WindowStartupLocation
è importante)
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();
Questa è una "soluzione Center Dot Dot 4.5 4.5 ", che utilizza SystemParameters anziché System.Windows.Forms o My.Compuer.Screen : poiché Windows 8 ha modificato il calcolo delle dimensioni dello schermo, l'unico modo in cui funziona per me è simile a quello (calcolo della barra delle applicazioni incluso):
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
Avevo bisogno di impostare la dimensione massima della mia applicazione per finestre. Questo potrebbe cambiare di conseguenza l'applicazione è stata mostrata nella schermata principale o nella schermata secondaria. Per ovviare a questo problema, abbiamo creato un metodo semplice che ti mostro in seguito:
/// <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;
}
}
}
in winform C # ho il punto di partenza (nel caso in cui abbiamo diversi monitor / diplay e un modulo ne chiama un altro) con l'aiuto del seguente metodo:
private Point get_start_point()
{
return
new Point(Screen.GetBounds(parent_class_with_form.ActiveForm).X,
Screen.GetBounds(parent_class_with_form.ActiveForm).Y
);
}
Per le configurazioni multi-monitor dovrai anche tenere conto della posizione X e Y:
Rectangle activeScreenDimensions = Screen.FromControl(this).Bounds;
this.Size = new Size(activeScreenDimensions.Width + activeScreenDimensions.X, activeScreenDimensions.Height + activeScreenDimensions.Y);
Questo codice di debug dovrebbe fare bene il trucco:
Puoi esplorare le proprietà della classe schermo
Metti tutti i display in un array o in un elenco usando Screen.AllScreens quindi acquisisce l'indice del display corrente e le sue proprietà.
C # (Convertito da VB da Telerik - Per favore ricontrolla)
{
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 (codice originale)
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)