Answered by:
Workaround: Silverlight OOB error when maximizing second monitor with borderless chrome

Programming Silverlight with .NET – General
http://social.msdn.microsoft.com/Forums/silverlight/en-US/a437d960-cd1f-4953-9f23-67008e490c50/workaround-silverlight-oob-error-when-maximizing-second-monitor-with-borderless-chrome
Question
2
8/16/2013 8:02:37 PM
8/18/2013 1:08:41 PM
General discussions around authoring Silverlight .NET applications.
0
1
-
text/sourcefragment 8/16/2013 8:02:37 PM Gary Frank 0
There is a bug in Silverlight that occurs when an out-of-browser (OOB) app that has a borderless chrome maximizes the window on a second monitor. The window either doesn't display at all or only a small part of it displays.
I developed a workaround. It seems to work OK with my laptop and second monitor, but I haven't tested it anywhere else.
Caveats:
It may not work if the primary window is an attached monitor. Further tweaking will address that.
It gets information from Windows, so I don't know if it will work with any computers that aren't running Windows, such as Apple.
void MinimizeButton_Click(object sender, RoutedEventArgs e) { // Silverlight Bug: // This is supposed to work just by setting to WindowState.Minimized. // But if it has borderless chrome, it doesn't display properly when restored from tray. // Work-around: // Set to WindowState.Normal, and set window to reduced monitor dimensions before minimizing. // Then it will restore properly from tray using these dimensions. if (Application.Current.IsRunningOutOfBrowser) { Application.Current.MainWindow.WindowState = WindowState.Normal; // Get the dimensions for the monitor that the window is on. Win32Rect myWin32Rect = GetMonitorDimensions(); // Give Windows the Top and Left positions so that it knows which monitor its on. // Give it the monitor resolution -- the monitor's height and width. Window winZ = Application.Current.MainWindow; winZ.Top = myWin32Rect.Top; winZ.Height = myWin32Rect.Bottom; winZ.Left = myWin32Rect.Left; winZ.Width = myWin32Rect.Right - myWin32Rect.Left; // Shrink the dimensions to create a 'Normal' size. winZ.Height = winZ.Height - (0.30 * winZ.Height); winZ.Top = winZ.Top + (0.15 * winZ.Height); winZ.Left = winZ.Left + (0.15 * winZ.Left); winZ.Width = winZ.Width - (0.30 * winZ.Width); // Minimize the window Application.Current.MainWindow.WindowState = WindowState.Minimized; } } void MaximizeButton_Click(object sender, RoutedEventArgs e) { if (Application.Current.IsRunningOutOfBrowser) { if (Application.Current.MainWindow.WindowState == WindowState.Maximized) { Application.Current.MainWindow.WindowState = WindowState.Normal; } else { if (Application.Current.HasElevatedPermissions) { // Silverlight Bug: // Window won't maximize on second monitor if borderless chrome. The window is hidden. // Work-around. // Setting to WindowState.Maximized causes the problem. // So make it work by setting the window to the monitor dimensions. // Let Windows think it's in maximized state, // since we're going to set the dimensions to maximize the window. Application.Current.MainWindow.WindowState = WindowState.Maximized; // Get the dimensions for the monitor that the window is on. Win32Rect myWin32Rect = GetMonitorDimensions(); // Give Windows the Top and Left positions so that it knows which monitor its on. // Give it the monitor resolution -- the monitor's height and width. Window winZ = Application.Current.MainWindow; winZ.Top = myWin32Rect.Top; winZ.Height = myWin32Rect.Bottom; winZ.Left = myWin32Rect.Left; winZ.Width = myWin32Rect.Right - myWin32Rect.Left; } else { MessageBox.Show("Cannot maximize window without elevated permissions."); } } } } void CloseButton_Click(object sender, RoutedEventArgs e) { if (Application.Current.IsRunningOutOfBrowser) Application.Current.MainWindow.Close(); } /// <summary> /// Get the Dimensions for the monitor that is displaying the left side of the window. /// </summary> /// <returns></returns> private Win32Rect GetMonitorDimensions() { // Get information from Windows about ALL of the monitors. DisplayManager.Displays.Clear(); DisplayManager.LoadDisplays(); Window winX = Application.Current.MainWindow; Win32Rect myWin32Rect = new Win32Rect(); // Scan the list of displays. // Get the dimensions of the monitor that contains the left edge of the window. // Application.Current.MainWindow.Left = Left edge of where window is now. foreach (DisplayInfo myDisplayInfo in DisplayManager.Displays) { // If the leftmost position of the current window is within the dimensions // of this monitor, get the dimensions of the monitor. if (winX.Left >= myDisplayInfo.MonitorArea.Left && winX.Left <= myDisplayInfo.MonitorArea.Right) { myWin32Rect.Top = myDisplayInfo.MonitorArea.Top; myWin32Rect.Bottom = myDisplayInfo.MonitorArea.Bottom; myWin32Rect.Left = myDisplayInfo.MonitorArea.Left; myWin32Rect.Right = myDisplayInfo.MonitorArea.Right; } } return myWin32Rect; }
using System; using System.Collections.ObjectModel; using System.Net; using System.Runtime.InteropServices; using System.Windows; using System.Windows.Controls; using System.Windows.Documents; using System.Windows.Ink; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Animation; using System.Windows.Shapes; // This module was created by copying code from a post by Pete Brown. // http://10rem.net/blog/2012/02/07/creating-big-silverlight-windows-and-getting-monitor-resolutions-and-positions-with-pinvoke namespace NW6ViewModel { [StructLayout(LayoutKind.Sequential)] public struct Win32Rect { public int Left { get; set; } public int Top { get; set; } public int Right { get; set; } public int Bottom { get; set; } public override string ToString() { return string.Format("{0}, {1}, {2}, {3}", Left, Top, Right, Bottom); } } [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] internal struct MonitorInfoEx { public int Size; public Win32Rect Monitor; public Win32Rect WorkArea; public uint Flags; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = DisplayManager.DeviceNameCharacterCount)] public string DeviceName; public void Init() { this.Size = 40 + 2 * DisplayManager.DeviceNameCharacterCount; this.DeviceName = string.Empty; } } public class DisplayInfo { public string MonitorName { get; internal set; } public Win32Rect MonitorArea { get; internal set; } public Win32Rect WorkArea { get; internal set; } public int Width { get; internal set; } public int Height { get; internal set; } public bool IsPrimary { get; internal set; } } /// <summary> /// This class is used to get information about all of the monitors attached to a PC. /// </summary> public class DisplayManager { // size of a device name string internal const int DeviceNameCharacterCount = 32; private delegate bool MonitorEnumProcDelegate(IntPtr hMonitor, IntPtr hdcMonitor, ref Win32Rect lprcMonitor, uint dwData); [DllImport("user32.dll")] private static extern bool EnumDisplayMonitors(IntPtr hdc, IntPtr lprcClip, MonitorEnumProcDelegate lpfnEnum, uint dwData); [DllImport("user32.dll", CharSet = CharSet.Auto)] private static extern bool GetMonitorInfo(IntPtr hMonitor, ref MonitorInfoEx lpmi); private static ObservableCollection<DisplayInfo> _displays = new ObservableCollection<DisplayInfo>(); public static ObservableCollection<DisplayInfo> Displays { get { return _displays; } } /// <summary> /// Get information about all of the monitors on the PC. /// Copy it into the Displays ObservableCollection. /// </summary> public static void LoadDisplays() { EnumDisplayMonitors(IntPtr.Zero, IntPtr.Zero, MonitorEnumProc, 0); } [AllowReversePInvokeCalls] internal static bool MonitorEnumProc(IntPtr hMonitor, IntPtr hdcMonitor, ref Win32Rect lprcMonitor, uint dwData) { var monitor = new MonitorInfoEx(); monitor.Init(); bool success = GetMonitorInfo(hMonitor, ref monitor); if (success) { var display = new DisplayInfo(); display.MonitorName = monitor.DeviceName; display.Width = monitor.Monitor.Right - monitor.Monitor.Left; display.Height = monitor.Monitor.Bottom - monitor.Monitor.Top; display.MonitorArea = monitor.Monitor; display.WorkArea = monitor.WorkArea; display.IsPrimary = (monitor.Flags > 0); _displays.Add(display); } return true; } } }
If you try this, let me know if it has any problems. Also, how can it be improved? Or do you know of a better workaround?
Gary Frank
Question
Answers
-
text/html 8/18/2013 1:08:18 PM Gary Frank 0