Поддерживать видимость панели задач с WPF Window.WindowStyle = нет - PullRequest
1 голос
/ 16 марта 2012

Я разрабатываю приложение WPF.Я полностью избавился от стандартной границы окна и создал свою собственную, установив WindowStyle на None и AllowsTransparency на true.Единственная проблема состоит в том, что, когда окно развернуто, оно заполняет весь экран, покрывая панель задач.Есть ли способ создать свои собственные границы без этого?

Ответы [ 3 ]

1 голос
/ 11 ноября 2015

Используйте метод CompatibilityMaximizedNoneWindow.

using System;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Interop;

using Point = System.Drawing.Point;

internal static class WindowExtensions
{
    public static PointF StandartDPI = new PointF(96f, 96f);
    private static PointF? currentDpi = null;
    public static float WidthZoom {get{return CurrentDPI.X/ StandartDPI.X; } }
    public static float HeigthZoom { get { return CurrentDPI.Y / StandartDPI.Y; } }

    public static PointF CurrentDPI
    {
        get
        {
            if (!currentDpi.HasValue)
            {
                var wiHelper = new WindowInteropHelper(App.Current.MainWindow);
                Graphics g = Graphics.FromHwnd(wiHelper.Handle);
                try
                {
                    currentDpi = new PointF(g.DpiX, g.DpiY);
                }
                catch
                {
                    currentDpi = StandartDPI;
                }
                finally
                {
                    g.Dispose();
                }
            }
            return currentDpi.Value;
        }
    }


    public static Window GetWindowFromTemplate(this object templateFrameworkElement)
    {
        var window = ((FrameworkElement)templateFrameworkElement).TemplatedParent as Window;
        return window;
    }

    private static int minWidth;
    private static int minHeight;

    public static void CompatibilityMaximizedNoneWindow(this Window window)
    {
        var wiHelper = new WindowInteropHelper(window);
        minHeight = (int)window.MinHeight;
        minWidth = (int)window.MinWidth;

        var handle = wiHelper.Handle;
        var hwndSource = HwndSource.FromHwnd(handle);
        if (hwndSource != null)
        {
            hwndSource.AddHook(CompatibilityMaximizedNoneWindowProc);
        }
    }

    [DllImport("user32")]
    private static extern bool GetMonitorInfo(IntPtr hMonitor, MONITORINFO lpmi);[DllImport("user32")]
    private static extern IntPtr MonitorFromWindow(IntPtr handle, int flags);

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto, Pack = 4)]
    private class MONITORINFO
    {
        public int cbSize = Marshal.SizeOf(typeof(MONITORINFO));
        public RECT rcMonitor = new RECT();
        public RECT rcWork = new RECT();
        public int dwFlags = 0;
    }

    [StructLayout(LayoutKind.Sequential)]
    private struct RECT
    {
        public int left;
        public int top;
        public int right;
        public int bottom;
    }

    [StructLayout(LayoutKind.Sequential)]
    private struct POINT
    {
        public int x;
        public int y;

        public POINT(int x, int y)
        {
            this.x = x; this.y = y;
        }
    }

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

    private static IntPtr CompatibilityMaximizedNoneWindowProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
    {
        const int WM_GETMINMAXINFO = 0x0024;
        const int MONITOR_DEFAULTTONEAREST = 0x00000002;
        switch (msg)
        {
            case WM_GETMINMAXINFO:
                var mmi = (MINMAXINFO)Marshal.PtrToStructure(lParam, typeof(MINMAXINFO));
                var monitor = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST);
                if (monitor != IntPtr.Zero)
                {
                    var monitorInfo = new MONITORINFO();
                    GetMonitorInfo(monitor, monitorInfo);
                    var rcWorkArea = monitorInfo.rcWork;
                    var 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);
                    //Hack для ограничения минимальных размеров окна
                    mmi.ptMinTrackSize.x = (int)(minWidth*WidthZoom);
                    mmi.ptMinTrackSize.y = (int)(minHeight*HeigthZoom);
                    //Hack для нормальной работы всплывающей панели задач
                    var taskbar = new TaskbarInfo();
                    if (taskbar.AutoHide)
                    {
                        switch (taskbar.Position)
                        {
                            case TaskbarInfo.TaskbarPosition.Top:
                                mmi.ptMaxPosition.y++;
                                mmi.ptMaxSize.y--;
                                break;
                            case TaskbarInfo.TaskbarPosition.Bottom:
                                mmi.ptMaxPosition.y--;
                                mmi.ptMaxSize.y--;
                                break;
                            case TaskbarInfo.TaskbarPosition.Left:
                                mmi.ptMaxPosition.x++;
                                mmi.ptMaxSize.x--;
                                break;
                            case TaskbarInfo.TaskbarPosition.Right:
                                mmi.ptMaxPosition.x--;
                                mmi.ptMaxSize.x--;
                                break;
                        }
                    }
                }
                Marshal.StructureToPtr(mmi, lParam, true); handled = true; break;
        }
        return (IntPtr)0;
    }
}
1 голос
/ 06 июля 2017

Намного проще, в вашем конструкторе окон просто установите

this.MaxHeight = SystemParameters.MaximizedPrimaryScreenHeight;

, и окно не покроет панель задач.

0 голосов
/ 16 марта 2012

Взгляните на Microsoft.Windows.Shell.Он делает все это и даже больше для вас.Отслеживать это немного расстраивает.Я думаю, что лучше всего использовать тот, который включен в последний элемент управления ленты .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...