15

我需要在我的 WPF 应用程序中更改 Windows 任务栏。为此,我设置WindowStyle="None"了 ,这意味着禁用 Windows 任务栏,并使用用于恢复、最小化和关闭应用程序的按钮制作自定义任务栏。现在我的问题是如果应用程序处于最大化模式,那么我在 Windows 上看不到开始菜单。

我在这里发现了一个类似的问题,但是当我尝试这段代码时,它没有编译。全屏模式,但不覆盖任务栏

如何创建自己的任务栏并在最大化时看到 Windows 开始菜单?xaml中是否有可以设置它的属性窗口?

4

7 回答 7

25

你可以试试这个:

MaxHeight = SystemParameters.MaximizedPrimaryScreenHeight;
MaxWidth = SystemParameters.MaximizedPrimaryScreenWidth;
于 2016-01-26T08:54:34.830 回答
5

在 CodeProject 上找到了一个可能有帮助的解决方案:http: //www.codeproject.com/Articles/107994/Taskbar-with-Window-Maximized-and-WindowState-to-N

WindowStyle="None"
WindowState="Maximized"
ResizeMode="NoResize"

this.Width = System.Windows.Forms.Screen.PrimaryScreen.WorkingArea.Width;
this.Height = System.Windows.Forms.Screen.PrimaryScreen.WorkingArea.Height;
this.Left = 0;
this.Top = 0;
this.WindowState = WindowState.Normal;
于 2016-01-26T08:58:54.813 回答
4

您可以通过添加以下内容轻松地在 XAML 中添加对高度的约束:

MaxHeight="{Binding Source={x:Static SystemParameters.MaximizedPrimaryScreenHeight}}"

进入窗口的标签。

于 2020-10-30T03:34:56.810 回答
2
WindowStyle="None" 
AllowsTransparency="True"  

this.Top = 0;
this.Left = 0;
this.Width = SystemParameters.WorkArea.Width;
this.Height = SystemParameters.WorkArea.Height;
于 2017-06-04T08:32:19.807 回答
2

提出的解决方案对我有用,无论用户设置如何,仍需要将像素更正为 dpi 设置器值,以使窗口具有正确的大小:

在 xml 中:

WindowStyle="None" WindowState="Maximized" ResizeMode="NoResize"

在代码中:

public MainWindow()
{
    InitializeComponent();
    var graphics = System.Drawing.Graphics.FromHwnd(IntPtr.Zero);
    var pixelWidth = System.Windows.Forms.Screen.PrimaryScreen.WorkingArea.Width ;
    var pixelHeight = System.Windows.Forms.Screen.PrimaryScreen.WorkingArea.Height;
    var pixelToDPI = 96.0 / graphics.DpiX ;
    this.Width = pixelWidth * pixelToDPI;
    this.Height = pixelHeight * pixelToDPI;
    this.Left = 0;
    this.Top = 0;
    this.WindowState = WindowState.Normal;
}
于 2017-08-13T11:37:54.553 回答
1

WPF 解决方案

假设我们想将 WPF 项目的 mainWindow 放在屏幕的右下角,而不覆盖任务栏。我们会这样写:

public MainWindow()
    {
        InitializeComponent();
        // set position of window on screen
        this.Left = SystemParameters.PrimaryScreenWidth - this.Width;
        this.Top = SystemParameters.WorkArea.Bottom - this.Height;
    }

this = 我们的对象(MainWindow) 当我们从 PrimarySrceenWidth 中减去我们的窗口位置(左)时,我们首先要放置 left 参数。比,我们通过从屏幕底部的工作区域中减去窗口高度来做同样的事情来获得最低点。屏幕的工作区域不包括任务栏!

请享用!

阿夫里

于 2018-04-05T22:42:46.053 回答
1

我在以下链接中找到了一个非常巧妙的解决方案, https://codekong.wordpress.com/2010/11/10/custom-window-style-and-accounting-for-the-taskbar/

这直接开箱即用。刚刚在此处添加此内容以供参考,以在不久的将来帮助任何人。

此处的现有解决方案均不适用于以扩展模式连接的多个屏幕。

在此处粘贴提供的解决方案以防止将其从博客中删除,

需要从 XAML 或后面的代码绑定 SourceInitialized 事件,

this.SourceInitialized += new EventHandler(Window1_SourceInitialized);

虽然这里是事件回调的源代码,

void Window1_SourceInitialized(object sender, EventArgs e)
{
    WindowSizing.WindowInitialized(this);
}

这是 WindowSizing.cs 的代码,

using System;
using System.Runtime.InteropServices;
using System.Windows;

namespace OfficeStyleWindowProject
{
   public static class WindowSizing
   {
    const int MONITOR_DEFAULTTONEAREST = 0x00000002;

    #region DLLImports

    [DllImport("shell32", CallingConvention = CallingConvention.StdCall)]
    public static extern int SHAppBarMessage(int dwMessage, ref APPBARDATA pData);

    [DllImport("user32", SetLastError = true)]
    static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

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

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

    #endregion

    private static MINMAXINFO AdjustWorkingAreaForAutoHide(IntPtr monitorContainingApplication, MINMAXINFO mmi)
    {
        IntPtr hwnd = FindWindow("Shell_TrayWnd", null);
        if (hwnd == null) return mmi;
        IntPtr monitorWithTaskbarOnIt = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST);
        if (!monitorContainingApplication.Equals(monitorWithTaskbarOnIt)) return mmi;
        APPBARDATA abd = new APPBARDATA();
        abd.cbSize = Marshal.SizeOf(abd);
        abd.hWnd = hwnd;
        SHAppBarMessage((int)ABMsg.ABM_GETTASKBARPOS, ref abd);
        int uEdge = GetEdge(abd.rc);
        bool autoHide = System.Convert.ToBoolean(SHAppBarMessage((int)ABMsg.ABM_GETSTATE, ref abd));

        if (!autoHide) return mmi;

        switch (uEdge)
        {
            case (int)ABEdge.ABE_LEFT:
                mmi.ptMaxPosition.x += 2;
                mmi.ptMaxTrackSize.x -= 2;
                mmi.ptMaxSize.x -= 2;
                break;
            case (int)ABEdge.ABE_RIGHT:
                mmi.ptMaxSize.x -= 2;
                mmi.ptMaxTrackSize.x -= 2;
                break;
            case (int)ABEdge.ABE_TOP:
                mmi.ptMaxPosition.y += 2;
                mmi.ptMaxTrackSize.y -= 2;
                mmi.ptMaxSize.y -= 2;
                break;
           case (int)ABEdge.ABE_BOTTOM:
                mmi.ptMaxSize.y -= 2;
                mmi.ptMaxTrackSize.y -= 2;
                break;
            default:
                return mmi;
        }
        return mmi;
    }

    private static int GetEdge(RECT rc)
    {
        int uEdge = -1;
        if (rc.top == rc.left && rc.bottom > rc.right)
            uEdge = (int)ABEdge.ABE_LEFT;
        else if (rc.top == rc.left && rc.bottom < rc.right)
            uEdge = (int)ABEdge.ABE_TOP;
        else if (rc.top > rc.left)
            uEdge = (int)ABEdge.ABE_BOTTOM;
        else
            uEdge = (int)ABEdge.ABE_RIGHT;
        return uEdge;
    }

    public static void WindowInitialized(Window window)
    {
        IntPtr handle = (new System.Windows.Interop.WindowInteropHelper(window)).Handle;
        System.Windows.Interop.HwndSource.FromHwnd(handle).AddHook(new System.Windows.Interop.HwndSourceHook(WindowProc));
    }

    private static IntPtr WindowProc(System.IntPtr hwnd, int msg, System.IntPtr wParam, System.IntPtr lParam, ref bool handled)
    {
        switch (msg)
        {
           case 0x0024:
                WmGetMinMaxInfo(hwnd, lParam);
                handled = true;
                break;
        }

        return (IntPtr)0;
    }

    private static void WmGetMinMaxInfo(IntPtr hwnd, IntPtr lParam)
    {
        MINMAXINFO mmi = (MINMAXINFO)Marshal.PtrToStructure(lParam, typeof(MINMAXINFO));
        IntPtr monitorContainingApplication = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST);

        if (monitorContainingApplication != System.IntPtr.Zero)
        {
            MONITORINFO monitorInfo = new MONITORINFO();
            GetMonitorInfo(monitorContainingApplication, monitorInfo);
            RECT rcWorkArea = monitorInfo.rcWork;
            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);
            mmi.ptMaxTrackSize.x = mmi.ptMaxSize.x;                                                 //maximum drag X size for the window
            mmi.ptMaxTrackSize.y = mmi.ptMaxSize.y;                                                 //maximum drag Y size for the window
            mmi.ptMinTrackSize.x = 800;                                                             //minimum drag X size for the window
            mmi.ptMinTrackSize.y = 600;                                                             //minimum drag Y size for the window
            mmi = AdjustWorkingAreaForAutoHide(monitorContainingApplication, mmi);                  //need to adjust sizing if taskbar is set to autohide
        }
        Marshal.StructureToPtr(mmi, lParam, true);
    }

    public enum ABEdge
    {
        ABE_LEFT = 0,
        ABE_TOP = 1,
        ABE_RIGHT = 2,
        ABE_BOTTOM = 3
    }

    public enum ABMsg
    {
        ABM_NEW = 0,
        ABM_REMOVE = 1,
        ABM_QUERYPOS = 2,
        ABM_SETPOS = 3,
        ABM_GETSTATE = 4,
        ABM_GETTASKBARPOS = 5,
        ABM_ACTIVATE = 6,
        ABM_GETAUTOHIDEBAR = 7,
        ABM_SETAUTOHIDEBAR = 8,
        ABM_WINDOWPOSCHANGED = 9,
        ABM_SETSTATE = 10
    }

    [StructLayout(LayoutKind.Sequential)]
    public struct APPBARDATA
    {
        public int cbSize;
        public IntPtr hWnd;
        public int uCallbackMessage;
        public int uEdge;
        public RECT rc;
        public bool lParam;
    }

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

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
    public 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)]
    public struct POINT
    {
        public int x;
        public int y;

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

    [StructLayout(LayoutKind.Sequential, Pack = 0)]
    public struct RECT
    {
        public int left;
        public int top;
        public int right;
        public int bottom;
    }
}
}

〜奥马尔

于 2021-10-22T06:39:46.673 回答