简体   繁体   English

最大化2个监视器上的WPF窗口

[英]Maximize WPF window on 2 monitor

Like title I want my WPF to maximize on 2 monitors (now my pc have 2 monitors). 像标题一样,我希望WPF在2个监视器上最大化(现在我的电脑上有2个监视器)。 I set 我设置

this.Width = System.Windows.Forms.Screen.AllScreens[0].Bounds.Width + System.Windows.Forms.Screen.AllScreens[1].Bounds.Width 

but it not full, have spaced like the image. 但它不完整,像图像一样间隔开。 I want user click maximize button then window maximize 2 monitor. 我希望用户单击最大化按钮,然后窗口最大化2个监视器。 Does anyone know? 有人知道吗? Thank you all! 谢谢你们!

p/s: sorry for my bad English. 附注:对不起,我的英语不好。

You need to find point Left, Top, Height, Width and directly set to the window which you want to maximize 您需要找到点Left,Top,Height,Width,并将其直接设置为要最大化的窗口

MonitorFromPoint
MonitorFromRect
MonitorFromWindow

For completeness, I present first the naive approach how the window can be maximized on the specified monitor. 为了完整起见,我首先提出一种幼稚的方法,如何在指定的监视器上最大化窗口。

void Maximize(HWND hWnd, HMONITOR hMonitor)
{
    // access monitor info
    MONITORINFO monitorInfo = { sizeof(MONITORINFO) };
    GetMonitorInfo(hMonitor, &monitorInfo);

    // restore window to normal size if it is not yet
    ShowWindow(hWnd, SW_RESTORE);

    // move window to the monitor
    SetWindowPos(hWnd, nullptr, monitorInfo.rcMonitor.left, 
    monitorInfo.rcMonitor.top, 0, 0, SWP_NOZORDER | SWP_NOSIZE);

    // maximize window
    ShowWindow(hWnd, SW_MAXIMIZE);    
}

Flickering is more obvious if function is called several times with the same input window and same target monitor. 如果在相同的输入窗口和相同的目标监视器上多次调用函数,则闪烁会更加明显。 Of course, someone can argue that it is possible to obtain the current state of the window and avoid calling the function (or making some early return in the function if the state is detected to be already correct). 当然,有人可能会争辩说有可能获得窗口的当前状态并避免调用该函数(或者,如果检测到该状态已经正确,则可以在函数中提前返回)。 However such handling will just add more complexity to the function. 但是,这样的处理只会增加功能的复杂性。 I was thinking whether it is not possible to just hide the window and perform restoration of the state just somehow in the background and only at the end show the window. 我在想是否不能仅隐藏窗口并以某种方式在后台执行状态恢复,而仅在最后显示窗口。 But trying to inject some SetRender(hWnd, FALSE) or ShowWindow(SW_HIDE) calls just made the output even worse. 但是尝试注入一些SetRender(hWnd,FALSE)或ShowWindow(SW_HIDE)调用只会使输出更糟。 After some tests, I found that changing maximize/normal window changes just one bit (WS_MAXIMIZE) in window's styles and finally with this information I get the final good solution: 经过一些测试,我发现更改最大化/普通窗口仅更改了窗口样式中的一位(WS_MAXIMIZE),最后,使用此信息,我得到了最终的好解决方案:

void Maximize(HWND hWnd, HMONITOR hMonitor)
{
    // access monitor info
    MONITORINFO monitorInfo = { sizeof(MONITORINFO) };
    GetMonitorInfo(hMonitor, &monitorInfo);

    const LONG currStyles = GetWindowLong(hWnd, GWL_STYLE);
    SetWindowLong(hWnd, GWL_STYLE, currStyles | WS_MAXIMIZE);
    const auto rc = monitorInfo.rcMonitor;
    SetWindowPos(&CWnd::wndTop, rc.left, rc.top, rc.Width(), rc.Height(), 0);
}

And that's it. 就是这样。 The function works as expected and if it is even called several times, there is no flickering. 该函数按预期工作,即使被多次调用,也不会闪烁。 The function can be easily changed to also restore window to normal size by removing WS_MAXIMIZE from the window styles and calling SetWindowPos with correct rectangle information. 通过从窗口样式中删除WS_MAXIMIZE并使用正确的矩形信息调用SetWindowPos,可以轻松更改该函数以将窗口恢复为正常大小。

        [DllImport("User32.dll")]
        private static extern IntPtr MonitorFromPoint([In]System.Drawing.Point pt, [In]uint dwFlags);

        //https://msdn.microsoft.com/en-us/library/windows/desktop/dn280510(v=vs.85).aspx
        [DllImport("Shcore.dll")]
        private static extern IntPtr GetDpiForMonitor([In]IntPtr hmonitor, [In]DpiType dpiType, [Out]out uint dpiX, [Out]out uint dpiY);

        public enum DpiType
        {
            Effective = 0,
            Angular = 1,
            Raw = 2,
        }

        /// <summary>
        /// POINT aka POINTAPI
        /// </summary>
        [StructLayout(LayoutKind.Sequential)]
        public struct POINT
        {
            /// <summary>
            /// x coordinate of point.
            /// </summary>
            public int x;
            /// <summary>
            /// y coordinate of point.
            /// </summary>
            public int y;

            /// <summary>
            /// Construct a point of coordinates (x,y).
            /// </summary>
            public POINT(int x, int y)
            {
                this.x = x;
                this.y = y;
            }
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct MINMAXINFO
        {
            public POINT ptReserved;
            public POINT ptMaxSize;
            public POINT ptMaxPosition;
            public POINT ptMinTrackSize;
            public POINT ptMaxTrackSize;
        };

        /// <summary>
        /// </summary>
        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
        public class MONITORINFO
        {
            /// <summary>
            /// </summary>            
            public int cbSize = Marshal.SizeOf(typeof(MONITORINFO));

            /// <summary>
            /// </summary>            
            public RECT rcMonitor = new RECT();

            /// <summary>
            /// </summary>            
            public RECT rcWork = new RECT();

            /// <summary>
            /// </summary>            
            public int dwFlags = 0;
        }


        /// <summary> Win32 </summary>
        [StructLayout(LayoutKind.Sequential, Pack = 0)]
        public struct RECT
        {
            /// <summary> Win32 </summary>
            public int left;
            /// <summary> Win32 </summary>
            public int top;
            /// <summary> Win32 </summary>
            public int right;
            /// <summary> Win32 </summary>
            public int bottom;

            /// <summary> Win32 </summary>
            public static readonly RECT Empty = new RECT();

            /// <summary> Win32 </summary>
            public int Width
            {
                get { return Math.Abs(right - left); }  // Abs needed for BIDI OS
            }
            /// <summary> Win32 </summary>
            public int Height
            {
                get { return bottom - top; }
            }

            /// <summary> Win32 </summary>
            public RECT(int left, int top, int right, int bottom)
            {
                this.left = left;
                this.top = top;
                this.right = right;
                this.bottom = bottom;
            }


            /// <summary> Win32 </summary>
            public RECT(RECT rcSrc)
            {
                this.left = rcSrc.left;
                this.top = rcSrc.top;
                this.right = rcSrc.right;
                this.bottom = rcSrc.bottom;
            }

            /// <summary> Win32 </summary>
            public bool IsEmpty
            {
                get
                {
                    // BUGBUG : On Bidi OS (hebrew arabic) left > right
                    return left >= right || top >= bottom;
                }
            }
            /// <summary> Return a user friendly representation of this struct </summary>
            public override string ToString()
            {
                if (this == RECT.Empty) { return "RECT {Empty}"; }
                return "RECT { left : " + left + " / top : " + top + " / right : " + right + " / bottom : " + bottom + " }";
            }

            /// <summary> Determine if 2 RECT are equal (deep compare) </summary>
            public override bool Equals(object obj)
            {
                if (!(obj is Rect)) { return false; }
                return (this == (RECT)obj);
            }

            /// <summary>Return the HashCode for this struct (not garanteed to be unique)</summary>
            public override int GetHashCode()
            {
                return left.GetHashCode() + top.GetHashCode() + right.GetHashCode() + bottom.GetHashCode();
            }


            /// <summary> Determine if 2 RECT are equal (deep compare)</summary>
            public static bool operator ==(RECT rect1, RECT rect2)
            {
                return (rect1.left == rect2.left && rect1.top == rect2.top && rect1.right == rect2.right && rect1.bottom == rect2.bottom);
            }

            /// <summary> Determine if 2 RECT are different(deep compare)</summary>
            public static bool operator !=(RECT rect1, RECT rect2)
            {
                return !(rect1 == rect2);
            }


        }

        [DllImport("user32")]
        internal static extern bool GetMonitorInfo(IntPtr hMonitor, MONITORINFO lpmi);

         [DllImport("User32")]
    internal static extern IntPtr MonitorFromWindow(IntPtr handle, int flags);

Links:- http://msdn.microsoft.com/en-us/library/windows/desktop/dd145071%28v=vs.85%29.aspx http://blogs.msdn.com/b/oldnewthing/archive/2010/04/12/9994016.aspx 链接: -http : //msdn.microsoft.com/zh-CN/library/windows/desktop/dd145071%28v=vs.85%29.aspx http://blogs.msdn.com/b/oldnewthing/archive/ 2010/04/12 / 9994016.aspx

I want user click maximize button then window maximize 2 monitor. 我希望用户单击最大化按钮,然后窗口最大化2个监视器。

When user clicks maximize button, put this. 当用户单击最大化按钮时,将其放置。

if (System.Windows.Forms.Screen.AllScreens.Length > 1)
{
    System.Drawing.Rectangle entireSize = System.Drawing.Rectangle.Empty;

    foreach (System.Windows.Forms.Screen s in System.Windows.Forms.Screen.AllScreens)
        entireSize = System.Drawing.Rectangle.Union(entireSize, s.Bounds);

    //this.WindowState = NORMAL // SET Window State to Normal.


    this.Width = entireSize.Width;
    this.Height = entireSize.Height;

    this.Left = entireSize.Left;
    this.Top = entireSize.Top;

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM