【问题标题】:WPF Minimize on Taskbar ClickWPF最小化任务栏点击
【发布时间】:2011-09-09 12:40:07
【问题描述】:

我有一个 WPF 应用程序,根据利益相关者的要求,它必须具有 WindowStyle="None"、ResizeMode="NoResize" 和 AllowTransparency="True"。我知道如果不使用 Windows chrome,您必须重新实现许多操作系统窗口处理功能。我能够创建一个有效的自定义最小化按钮,但是当您单击屏幕底部的任务栏图标时,我无法重新实现 Windows 最小化应用程序的功能。

用户要求是应用程序应在单击任务栏图标时最小化并在再次单击时恢复。后者从未停止工作,但我无法实施前者。这是我正在使用的代码:

    public ShellView(ShellViewModel viewModel)
    {
        InitializeComponent();

        // Set the ViewModel as this View's data context.
        this.DataContext = viewModel;

        this.Loaded += new RoutedEventHandler(ShellView_Loaded);
    }

    private void ShellView_Loaded(object sender, RoutedEventArgs e)
    {
        var m_hWnd = new WindowInteropHelper(this).Handle;
        HwndSource.FromHwnd(m_hWnd).AddHook(WindowProc);
    }

    private IntPtr WindowProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
    {
        if (msg == NativeMethods.CS_DBLCLKS)
        {
            this.WindowState = WindowState.Minimized;
            // handled = true
        }

        return IntPtr.Zero;
    }

    /// <summary>
    /// http://msdn.microsoft.com/en-us/library/ms646360(v=vs.85).aspx
    /// </summary>
    internal class NativeMethods
    {
        public const int SC_RESTORE = 0xF120;
        public const int SC_MINIMIZE = 0xF020;
        public const int SC_CLOSE = 0xF060;
        public const int WM_SYSCOMMAND = 0x0112;
        public const int WS_SYSMENU = 0x80000;
        public const int WS_MINIMIZEBOX = 0x20000;
        public const int CS_DBLCLKS = 0x8;
        NativeMethods() { }
    }

【问题讨论】:

  • 我差点忘记了,我在发帖前搜索了 StackOverflow,但找不到适用于 WPF 的可接受的解决方案。我已经看到了 WinForms 的解决方案。
  • 您不需要使用本机方法来最小化和从任务栏恢复。我几乎所有的应用程序都以这种方式运行,而我没有遇到过这种情况……WindowState = WindowState.Minimized 不起作用吗?
  • @FlyingStreudel 问题是没有一种托管方式来检测用户何时单击任务栏。在所有其他情况下,我可以很好地最小化和最大化,但我没有办法让应用程序响应它的任务栏图标的单击事件。要求是最小化任务栏按钮的点击。
  • 我想我很困惑,即使是 WindowStyle=None 和 AllowsTransparency=True。该窗口仍应响应任务栏上的单击。是否还有其他因素阻止了这种情况?
  • @FlyingStreudel 此链接适用于 WinForms,但同样的推理适用于 WPF。 stackoverflow.com/questions/5180609/… 我刚刚打开了 Expression Blend 并创建了一个没有任何更改的新应用程序,只是 WindowStyle="None"、AllowsTransparency="True"。如果 ResizeMode="NoResize" 它不起作用,但如果我不更改 ResizeMode 它会突然起作用。很奇怪。

标签: c# wpf winapi minimize


【解决方案1】:

使用ResizeMode="CanMinimize"。这将允许您最小化到任务栏。

【讨论】:

    【解决方案2】:

    我过去曾使用此代码使用 WPF 的 WindowStyle=None 最小化/最大化 Windows

    private void MinimizeButton_Click(object sender, RoutedEventArgs e)
    {
        this.WindowState = WindowState.Minimized;
    }
    
    private void MaximizeButton_Click(object sender, RoutedEventArgs e)
    {
        AdjustWindowSize();
    }
    
    private void AdjustWindowSize()
    {
        if (this.WindowState == WindowState.Maximized)
        {
            this.WindowState = WindowState.Normal;
        }
        else
        {
            this.WindowState = WindowState.Maximized;
        }
    }
    
    private void FakeTitleBar_MouseDown(object sender, MouseButtonEventArgs e)
    {
        if(e.ChangedButton == MouseButton.Left)
        {
            if (e.ClickCount == 2)
            {
                AdjustWindowSize();
            }
            else
            {
                Application.Current.MainWindow.DragMove();
            }
        }
     }
    

    【讨论】:

    • 不幸的是,这不能处理左键单击的任务栏图标。
    • @masenkablast - 抱歉,刚刚注意到您指的是 TaskBar 行为,而不是 TrayIcon 行为。任务栏行为不是 Windows 的一部分,而不是应用程序吗?
    • 但是,如果您在问题中设置了所有这三个属性,则会禁用 Windows 行为。
    【解决方案3】:

    我刚刚意识到如果 ResizeMode=NoResize 比这种情况发生,如果它等于 CanResize 比你不要禁用操作系统功能以通过单击任务栏图标最小化。我投票结束这个问题。

    【讨论】:

    • 禁用调整大小的替代方法是将窗口的MinHeight/MaxHeightMinWidth/MaxWidth 设置为相同。
    • @Joel B Fant,我觉得这很可疑。
    • @Rachel 这听起来是个好主意。禁用调整大小的主要原因是,如果您有一个无镶边窗口并最大化窗口,如果启用调整大小,操作系统会从您的窗口裁剪像素,因为它需要调整大小。
    • 这里完全正常,因为目的是如果其他人遇到类似问题并找到您的问题,他们也会找到解决方案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多