IntPtr WindowProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
 {
     switch (msg)
     {
     case 0x0024:
         Win32.MINMAXINFO mmi     = (Win32.MINMAXINFO)Marshal.PtrToStructure(lParam, typeof(Win32.MINMAXINFO));
         IntPtr           monitor = Win32.MonitorFromWindow(hwnd, 0x00000002 /*MONITOR_DEFAULTTONEAREST*/);
         if (monitor != IntPtr.Zero)
         {
             Win32.MONITORINFO monitorInfo = new Win32.MONITORINFO {
             };
             Win32.GetMonitorInfo(monitor, monitorInfo);
             Win32.RECT rcWorkArea    = monitorInfo.rcWork;
             Win32.RECT rcMonitorArea = monitorInfo.rcMonitor;
             mmi.ptMaxPosition.x = Math.Abs(rcWorkArea.left - rcMonitorArea.left);
             mmi.ptMaxPosition.y = Math.Abs(rcWorkArea.top - rcMonitorArea.top);
             mmi.ptMaxSize.x     = Math.Abs(rcWorkArea.right - rcWorkArea.left);
             mmi.ptMaxSize.y     = Math.Abs(rcWorkArea.bottom - rcWorkArea.top);
             if (!CachedMinTrackSize.Equals(mmi.ptMinTrackSize) || CachedMinHeight != MinHeight && CachedMinWidth != MinWidth)
             {
                 mmi.ptMinTrackSize.x = (int)((CachedMinWidth = MinWidth) * WindowCompositionTarget.TransformToDevice.M11);
                 mmi.ptMinTrackSize.y = (int)((CachedMinHeight = MinHeight) * WindowCompositionTarget.TransformToDevice.M22);
                 CachedMinTrackSize   = mmi.ptMinTrackSize;
             }
         }
         Marshal.StructureToPtr(mmi, lParam, true);
         handled = true;
         break;
     }
     return(IntPtr.Zero);
 }
        private void WmGetMinMaxInfo(IntPtr hwnd, IntPtr lParam)
        {
            // MINMAXINFO structure
            Win32.MINMAXINFO mmi = (Win32.MINMAXINFO)Marshal.PtrToStructure(lParam, typeof(Win32.MINMAXINFO));

            // Get handle for nearest monitor to this window
            WindowInteropHelper wih = new WindowInteropHelper(this);
            IntPtr hMonitor         = Win32.MonitorFromWindow(wih.Handle, Win32.MONITOR_DEFAULTTONEAREST);

            // Get monitor info
            Win32.MONITORINFOEX monitorInfo = new Win32.MONITORINFOEX();
            monitorInfo.cbSize = Marshal.SizeOf(monitorInfo);
            Win32.GetMonitorInfo(new HandleRef(this, hMonitor), monitorInfo);

            // Get HwndSource
            HwndSource source = HwndSource.FromHwnd(wih.Handle);

            if (source == null)
            {
                // Should never be null
                throw new Exception("Cannot get HwndSource instance.");
            }
            if (source.CompositionTarget == null)
            {
                // Should never be null
                throw new Exception("Cannot get HwndTarget instance.");
            }

            // Get transformation matrix
            System.Windows.Media.Matrix matrix = source.CompositionTarget.TransformFromDevice;

            // Convert working area
            Win32.RECT           workingArea        = monitorInfo.rcWork;
            System.Windows.Point dpiIndependentSize =
                matrix.Transform(new System.Windows.Point(
                                     workingArea.Right - workingArea.Left,
                                     workingArea.Bottom - workingArea.Top
                                     ));

            // Convert minimum size
            System.Windows.Point dpiIndenpendentTrackingSize = matrix.Transform(new System.Windows.Point(
                                                                                    this.MinWidth,
                                                                                    this.MinHeight
                                                                                    ));

            // Set the maximized size of the window
            mmi.ptMaxSize.x = (int)dpiIndependentSize.X;
            mmi.ptMaxSize.y = (int)dpiIndependentSize.Y;

            // Set the position of the maximized window
            mmi.ptMaxPosition.x = 0;
            mmi.ptMaxPosition.y = 0;

            // Set the minimum tracking size
            mmi.ptMinTrackSize.x = (int)dpiIndenpendentTrackingSize.X;
            mmi.ptMinTrackSize.y = (int)dpiIndenpendentTrackingSize.Y;

            Marshal.StructureToPtr(mmi, lParam, true);
        }
Beispiel #3
0
        /// <summary>
        /// Get the max size allowed for this window based on the current screen.
        /// </summary>
        /// <param name="hwnd">The handle to the window.</param>
        /// <returns>The max size allowed for this window based on the current screen.</returns>
        private Win32.MINMAXINFO GetMaxInfo(IntPtr hwnd)
        {
            System.Windows.Forms.Screen screen = System.Windows.Forms.Screen.FromHandle(hwnd);
            Win32.MINMAXINFO            info   = new Win32.MINMAXINFO();
            info.ptMaxPosition.x = Math.Abs(screen.WorkingArea.Left - screen.Bounds.Left);
            info.ptMaxPosition.y = Math.Abs(screen.WorkingArea.Top - screen.Bounds.Top);
            info.ptMaxSize.x     = screen.WorkingArea.Width;
            info.ptMaxSize.y     = screen.WorkingArea.Height;

            return(info);
        }
        protected override void WndProc(ref Message m)
        {
            base.WndProc(ref m);
            switch ((WM)m.Msg)
            {
            case WM.SETTINGCHANGE:
                if ((SPI)m.WParam.ToInt32() == SPI.SETWORKAREA)
                {
                    if (WindowState == FormWindowState.Maximized)
                    {
                        // When the taskbar or other docked windows change the available work area
                        // then we need to adjust ourself if we are currently maximized.
                        // However this works only if we shortly get unmaximized.
                        WindowState = FormWindowState.Normal;
                        WindowState = FormWindowState.Maximized;
                    }
                }
                break;

            case WM.GETMINMAXINFO:
            {
                // We need to handle this event here because on certain resize actions
                // and taskbar positions parts of the window are hidden. We need to ensure this
                // doesn't happen.
                Screen    currentScreen = Screen.FromControl(this);
                Rectangle validArea     = currentScreen.WorkingArea;

                Win32.MINMAXINFO info = (Win32.MINMAXINFO)Marshal.PtrToStructure(m.LParam, typeof(Win32.MINMAXINFO));

                // Don't use the position of the screen (or its valid area). The position given here
                // is local to the screen area.
                info.ptMaxPosition.x = 0;
                info.ptMaxPosition.y = 0;
                if (info.ptMaxSize.x > validArea.Width)
                {
                    info.ptMaxSize.x = validArea.Width;
                }
                if (info.ptMaxSize.y > validArea.Height)
                {
                    info.ptMaxSize.y = validArea.Height;
                }

                Marshal.StructureToPtr(info, m.LParam, true);
                m.Result = IntPtr.Zero;

                break;
            }
            }
        }
Beispiel #5
0
        private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
        {
            if (msg == Win32.WM_GETMINMAXINFO)
            {
                // Get the monitor handle.
                IntPtr hMonitor = Win32.MonitorFromWindow(hwnd, Win32.MONITOR_DEFAULTTONEAREST);

                if (hMonitor != IntPtr.Zero)
                {
                    // Gets monitor information.
                    Win32.MONITORINFO monitorInfo = Win32.MONITORINFO.Create();

                    if (Win32.GetMonitorInfo(hMonitor, ref monitorInfo) != 0)
                    {
                        // Gets the MINMAXINFO.
                        Win32.MINMAXINFO minMaxInfo = (Win32.MINMAXINFO)Marshal.PtrToStructure(lParam, typeof(Win32.MINMAXINFO));

                        if (IsFullScreenMode)
                        {
                            // If it is the full screen mode, it must use the entire screen.
                            minMaxInfo.ptMaxPosition.x = monitorInfo.rcMonitor.left;
                            minMaxInfo.ptMaxPosition.y = monitorInfo.rcMonitor.top;
                            minMaxInfo.ptMaxSize.x     = Math.Abs(monitorInfo.rcMonitor.right - monitorInfo.rcMonitor.left);
                            minMaxInfo.ptMaxSize.y     = Math.Abs(monitorInfo.rcMonitor.bottom - monitorInfo.rcMonitor.top);
                        }
                        else
                        {
                            // If it is not the full screen mode, it must use the work area.
                            minMaxInfo.ptMaxPosition.x = monitorInfo.rcWork.left;
                            minMaxInfo.ptMaxPosition.y = monitorInfo.rcWork.top;
                            minMaxInfo.ptMaxSize.x     = Math.Abs(monitorInfo.rcWork.right - monitorInfo.rcWork.left);
                            minMaxInfo.ptMaxSize.y     = Math.Abs(monitorInfo.rcWork.bottom - monitorInfo.rcWork.top);
                        }

                        // Sets the modified MINMAXINFO.
                        Marshal.StructureToPtr(minMaxInfo, lParam, false);
                        handled = true;
                    }
                } // if (hMonitor != IntPtr.Zero)
            }     // if (msg == Win32.WM_GETMINMAXINFO)

            return(IntPtr.Zero);
        }
Beispiel #6
0
        /// <summary>
        /// Process the message that requests the size for a max window.
        /// </summary>
        /// <param name="hwnd">The window handle.</param>
        /// <param name="msg">The message to process.</param>
        /// <param name="wParam">A parameter.</param>
        /// <param name="lParam">A parameter.</param>
        /// <param name="handled">A value that indicates if the message was handled.</param>
        /// <returns>IntPtr.Zero.</returns>
        protected override IntPtr WindowProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
        {
            switch (msg)
            {
            case Win32.Constant.WM_GETMINMAXINFO:

                Win32.MINMAXINFO info    = (Win32.MINMAXINFO)System.Runtime.InteropServices.Marshal.PtrToStructure(lParam, typeof(Win32.MINMAXINFO));
                Win32.MINMAXINFO maxInfo = GetMaxInfo(hwnd);

                info.ptMaxPosition.x = maxInfo.ptMaxPosition.x;
                info.ptMaxPosition.y = maxInfo.ptMaxPosition.y;
                info.ptMaxSize.x     = maxInfo.ptMaxSize.x;
                info.ptMaxSize.y     = maxInfo.ptMaxSize.y;

                System.Runtime.InteropServices.Marshal.StructureToPtr(info, lParam, true);
                return(IntPtr.Zero);

            default:
                return(IntPtr.Zero);
            }
        }
Beispiel #7
0
        /// <summary>
        /// Set border thickness based on the maximize state.
        /// </summary>
        /// <param name="e">Size info.</param>
        protected override void SizeChange(SizeChangedEventArgs e)
        {
            base.SizeChange(e);

            if (ParentWindow != null)
            {
                if (ParentWindow.WindowState == WindowState.Maximized)
                {
                    ParentWindow.BorderThickness = new Thickness(0);
                }
                else
                {
                    Win32.MINMAXINFO maxInfo = GetMaxInfo(ParentWindowHwnd);
                    if (e.NewSize.Height == maxInfo.ptMaxSize.y && ParentWindow.Top == 0)
                    {
                        ParentWindow.BorderThickness = new Thickness(0);
                    }
                    else
                    {
                        ParentWindow.BorderThickness = new Thickness(4);
                    }
                }
            }
        }
        /// <summary>
        /// Get the max size allowed for this window based on the current screen.
        /// </summary>
        /// <param name="hwnd">The handle to the window.</param>
        /// <returns>The max size allowed for this window based on the current screen.</returns>
        private Win32.MINMAXINFO GetMaxInfo(IntPtr hwnd)
        {
            System.Windows.Forms.Screen screen = System.Windows.Forms.Screen.FromHandle(hwnd);
            Win32.MINMAXINFO info = new Win32.MINMAXINFO();
            info.ptMaxPosition.x = Math.Abs(screen.WorkingArea.Left - screen.Bounds.Left);
            info.ptMaxPosition.y = Math.Abs(screen.WorkingArea.Top - screen.Bounds.Top);
            info.ptMaxSize.x = screen.WorkingArea.Width;
            info.ptMaxSize.y = screen.WorkingArea.Height;            

            return info;
        }