O que estou procurando é o equivalente a System.Windows.SystemParameters.WorkArea
ao monitor em que a janela está atualmente.
Esclarecimento: A janela em questão é WPF
, não WinForm
.
O que estou procurando é o equivalente a System.Windows.SystemParameters.WorkArea
ao monitor em que a janela está atualmente.
Esclarecimento: A janela em questão é WPF
, não WinForm
.
Respostas:
Screen.FromControl
, Screen.FromPoint
E Screen.FromRectangle
deve ajudá-lo com isso. Por exemplo, no WinForms, seria:
class MyForm : Form
{
public Rectangle GetScreen()
{
return Screen.FromControl(this).Bounds;
}
}
Não conheço uma chamada equivalente para WPF. Portanto, você precisa fazer algo como este método de extensão.
static class ExtensionsForWPF
{
public static System.Windows.Forms.Screen GetScreen(this Window window)
{
return System.Windows.Forms.Screen.FromHandle(new WindowInteropHelper(window).Handle);
}
}
window
no monitor acima do meu primário (por exemplo, seu Top < 0
), FromHandle
retornei o Screen
do meu monitor primário (mesmo que window
estivesse completamente dentro o monitor secundário)!?! Suspiro. Parece que vou ter que procurar no Screen.AllScreens
Array sozinho. Por que as coisas não podem "simplesmente funcionar"?!? Arrrrgh.
Você pode usar isso para obter os limites do espaço de trabalho da área de trabalho da tela principal:
System.Windows.SystemParameters.WorkArea
Isso também é útil para obter apenas o tamanho da tela principal:
System.Windows.SystemParameters.PrimaryScreenWidth
System.Windows.SystemParameters.PrimaryScreenHeight
Além disso, você pode precisar de:
para obter o tamanho combinado de todos os monitores e não um em particular.
PresentationFramework.dll
e #using System.Windows;
Adicionando uma solução que não usa WinForms, mas NativeMethods. Primeiro, você precisa definir os métodos nativos necessários.
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, em seguida, obtenha a alça do monitor e as informações do monitor assim.
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 );
}
Adicionar ao ffpf
Screen.FromControl(this).Bounds
Cuidado com o fator de escala de suas janelas (100% / 125% / 150% / 200%). Você pode obter o tamanho real da tela usando o seguinte código:
SystemParameters.FullPrimaryScreenHeight
SystemParameters.FullPrimaryScreenWidth
Eu queria ter a resolução da tela antes de abrir a primeira das minhas janelas, então aqui está uma solução rápida para abrir uma janela invisível antes de realmente medir as dimensões da tela (você precisa adaptar os parâmetros da janela à sua janela para garantir que ambos estejam abertos em a mesma tela - principalmente a 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();
Esta é uma " solução Center Screen DotNet 4.5 ", usando SystemParameters em vez de System.Windows.Forms ou My.Compuer.Screen : Como o Windows 8 alterou o cálculo da dimensão da tela, a única maneira de funcionar para mim é assim (cálculo da barra de tarefas incluído):
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
Eu precisava definir o tamanho máximo do meu aplicativo de janela. Este pode ser alterado de acordo com a aplicação apresentada na tela principal ou na secundária. Para superar esse problema, criamos um método simples que mostrarei a seguir:
/// <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;
}
}
}
no winforms C #, tenho o ponto de partida (por exemplo, quando temos vários monitor / diplay e um formulário está chamando outro) com a ajuda do seguinte método:
private Point get_start_point()
{
return
new Point(Screen.GetBounds(parent_class_with_form.ActiveForm).X,
Screen.GetBounds(parent_class_with_form.ActiveForm).Y
);
}
Para configurações de vários monitores, você também precisará ter em conta a posição X e Y:
Rectangle activeScreenDimensions = Screen.FromControl(this).Bounds;
this.Size = new Size(activeScreenDimensions.Width + activeScreenDimensions.X, activeScreenDimensions.Height + activeScreenDimensions.Y);
Este código de depuração deve executar bem o truque:
Você pode explorar as propriedades da classe Screen
Coloque todas as exibições em uma matriz ou lista usando Screen.AllScreens e capture o índice da exibição atual e suas propriedades.
C # (convertido de VB por Telerik - verifique novamente)
{
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 (código original)
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)