简体   繁体   English

如何在不覆盖任务栏的情况下制作全屏模式:wpf c#

[英]How to make full screen mode, without covering the taskbar using :wpf c#

I need to change windows taskbar in my WPF application.我需要在我的 WPF 应用程序中更改 windows 任务栏。 For that I set WindowStyle="None" , which means to disable the windows taskbar, and make custom taskbar with buttons for restoring, minimizing and closing the application.为此,我设置了WindowStyle="None" ,这意味着禁用 windows 任务栏,并使用用于恢复、最小化和关闭应用程序的按钮制作自定义任务栏。 Now my problem is if the application is in maximize mode then I can't see the start menu on windows.现在我的问题是如果应用程序处于最大化模式,那么我在 windows 上看不到开始菜单。

I found a similar question here, but when I tried this code it didn't compile.我在这里发现了一个类似的问题,但是当我尝试这段代码时,它没有编译。 full screen mode, but don't cover the taskbar 全屏模式,但不覆盖任务栏

How can I create my own taskbar and able to see the windows start menu when I maximized it?如何创建自己的任务栏并在最大化 windows 开始菜单时看到它? Is there a property window in xaml which can set it? xaml中是否有可以设置的属性window?

You may try this:你可以试试这个:

MaxHeight = SystemParameters.MaximizedPrimaryScreenHeight;
MaxWidth = SystemParameters.MaximizedPrimaryScreenWidth;

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

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

and

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;

You can easily add the constraints on height in XAML by adding:您可以通过添加以下内容轻松地在 XAML 中添加对高度的约束:

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

into the Window's tag.进入窗口的标签。

WindowStyle="None" 
AllowsTransparency="True"  

and

this.Top = 0;
this.Left = 0;
this.Width = SystemParameters.WorkArea.Width;
this.Height = SystemParameters.WorkArea.Height;

Proposed solution worked for me but still need to correct pixel to dpi setter values for window to have correct size regardless user settings:建议的解决方案对我有用,仍然需要将像素更正为窗口的 dpi 设置器值以具有正确的大小,无论用户设置如何:

in xaml :在 xaml 中:

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

in code :在代码中:

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;
}

Solution for WPF WPF解决方案

Let's say we want to place the mainWindow of a WPF project at the bottom-right of the screen without it covering the taskBar.假设我们想将 WPF 项目的 mainWindow 放置在屏幕的右下角而不覆盖 taskBar。 We'll write this:我们会这样写:

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

this = our object (the MainWindow) We first get to place the left parameter when we subtract our window position (left) from the PrimarySrceenWidth. this = 我们的对象(MainWindow) 当我们从 PrimarySrceenWidth 中减去我们的窗口位置(左)时,我们首先要放置左参数。 Than, we do the same to get the most lower point, by subtracting the windows height from the working area of the screen bottom.然后,我们通过从屏幕底部的工作区域中减去窗口高度来获得最低点。 The working area of the screen does not include the task bar!屏幕的工作区不包括任务栏!

enjoy!请享用!

Avri艾薇

I have found a pretty neat solution for the problem in discussion here at the following link, https://codekong.wordpress.com/2010/11/10/custom-window-style-and-accounting-for-the-taskbar/我在以下链接中找到了解决问题的非常巧妙的解决方案, https://codekong.wordpress.com/2010/11/10/custom-window-style-and-accounting-for-the-taskbar/

This works directly out of the box.这直接开箱即用。 Just added this here for reference to help anyone in near future.刚刚在此处添加此内容以供参考,以在不久的将来帮助任何人。

None of the existing solutions here worked for multiple screens attached in Extended mode.这里现有的解决方案都不适用于以扩展模式连接的多个屏幕。

Pasting the provided solution here to save it from being removed from the blog,在此处粘贴提供的解决方案以防止其从博客中删除,

Need to bind SourceInitialized event either from XAML or code behind,需要从 XAML 或后面的代码绑定 SourceInitialized 事件,

this.SourceInitialized += new EventHandler(Window1_SourceInitialized);

While here's the source code for event callback,虽然这里是事件回调的源代码,

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

Here's the code for WindowSizing.cs,这是 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;
    }
}
}

~Umar ~欧玛

m-pavan-kumar's answer was correct. m-pavan-kumar 的回答是正确的。 I'm 2 points off being able to comment of course.当然,我可以评论两分。

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

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

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