自定义窗口样式与动画最小化 [英] Custom window style with minimize animation

查看:300
本文介绍了自定义窗口样式与动画最小化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想有一个自定义窗口,以便遵循一些教程它通过窗口样式设置为none,然后添加标题栏/恢复启用此/减少自己/关闭按钮。最小化是通过简单的处理click事件和窗口状态设置为最小化实现的,但这并不表明你在Windows 7上看到减少动画,只是瞬间隐藏窗口与其他窗口使用时,感觉很奇怪那些动画,因为你往往会感到应用程序关闭。

所以,反正是有使该动画的? ..好像当你改变WindowStyle为none禁用。

编辑:测试code

 公共部分类主窗口:窗口
{
    公共主窗口()
    {
        WindowStyle = WindowStyle.None;
        的InitializeComponent();
    }    函数[DllImport(user32.dll中)]
    静态外部INT SendMessage函数(IntPtr的的HWND,UINT味精,IntPtr的的wParam,lParam的IntPtr的);    保护覆盖无效OnMouseLeftButtonDown在(MouseButtonEventArgs E)
    {
        base.OnMouseLeftButtonDown(E);        //这似乎没有动画
        SendMessage函数(新WindowInteropHelper(本).Handle,0x0112,(IntPtr的)0xF020,IntPtr.Zero);
    }    保护覆盖无效OnMouseRightButtonDown(MouseButtonEventArgs E)
    {
        base.OnMouseRightButtonDown(E);        WindowStyle = WindowStyle.SingleBorderWindow;
        的WindowState = WindowState.Minimized;
    }    保护覆盖无效OnActivated(EventArgs的发送)
    {
        base.OnActivated(E);        Dispatcher.BeginInvoke(DispatcherPriority.ApplicationIdle,新的行动(()=> WindowStyle = WindowStyle.None));
    }
}


解决方案

编辑尝试了一下后回答。

有两种选择:
1 您只需最小化和激活窗口前更改样式:

 私人无效Button_OnClick(对象发件人,RoutedEventArgs E)
{
    //只是最小化之前更改了WindowStyle到单个边框
    this.WindowStyle = WindowStyle.SingleBorderWindow;
    this.WindowState = WindowState.Minimized;
}私人无效MainWindow_OnActivated(对象发件人,EventArgs的发送)
{
    //改变WindowStyle回无,但窗口已被激活后,才
    Dispatcher.BeginInvoke(DispatcherPriority.ApplicationIdle,新的行动(()=> WindowStyle = WindowStyle.None));
}

该解决方案有一个限制 - 如果你从任务栏最小化,它没有动画窗口

2 与SC_MINIMIZE参数发送它WM_SYSCOMMAND消息,并通过挂钩到消息(改变边框样式尽量减少窗口 HwndSource.FromHwnd(m_hWnd).AddHook(的WindowProc ))。

 内部类的API codeS
{
    公共const int的SC_RESTORE = 0xF120;
    公共const int的SC_MINIMIZE = 0xF020;
    公共const int的WM_SYSCOMMAND = 0x0112;
}私人的IntPtr的HWND;函数[DllImport(user32.dll中)]
公共静态外部INT SendMessage函数(IntPtr的的HWND,INT WMSG,IntPtr的的wParam,lParam的IntPtr的);
私人无效Window_Loaded(对象发件人,RoutedEventArgs E)
{
    的hWnd =新WindowInteropHelper(本).Handle;
    HwndSource.FromHwnd(HWND).AddHook(WindowProc中);
}私人无效Button_Click(对象发件人,RoutedEventArgs E)
{
    SendMessage消息(HWND,阿比codes.WM_SYSCOMMAND,新的IntPtr(API codes.SC_MINIMIZE),IntPtr.Zero);
}私人的IntPtr的WindowProc(HWND的IntPtr,诠释味精,IntPtr的的wParam,lParam中的IntPtr,楼盘布尔处理)
{
    如果(MSG ==阿比codes.WM_SYSCOMMAND)
    {
        如果(wParam.ToInt32()==阿比codes.SC_MINIMIZE)
        {
            WindowStyle = WindowStyle.SingleBorderWindow;
            的WindowState = WindowState.Minimized;
            办理= TRUE;
        }
        否则,如果(wParam.ToInt32()==阿比codes.SC_RESTORE)
        {
            的WindowState = WindowState.Normal;
            WindowStyle = WindowStyle.None;
            办理= TRUE;
        }
    }
    返回IntPtr.Zero;
}

不属于上述两种方法都是伟大的,因为他们只是黑客。最大的缺点是,你可以看到边框再现了一会儿,当你点击按钮。我想看看别人想出因为我不认为这是一个很好的答案我自己。

I wanted to have a customized window so followed a few tutorials which enable this by setting the window style to none, and then adding the title-bar/restore/minimize/close buttons yourself. The minimize is achieved by simply handling the click event and setting the Window-state to minimized, but this doesn't show the minimize animation you see on Windows 7, and just instantly hides the window, which feels very odd when used with other windows that do animate, as you tend to feel the application is closing.

So, is there anyway of enabling that animation? .. it seems to be disabled when you change the WindowStyle to none.

Edit : Test code

public partial class MainWindow : Window
{
    public MainWindow()
    {
        WindowStyle = WindowStyle.None;
        InitializeComponent();
    }

    [DllImport("user32.dll")]
    static extern int SendMessage(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam);

    protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)
    {
        base.OnMouseLeftButtonDown(e);

        // this doesnt seem to animate
        SendMessage(new WindowInteropHelper(this).Handle, 0x0112, (IntPtr)0xF020, IntPtr.Zero);
    }

    protected override void OnMouseRightButtonDown(MouseButtonEventArgs e)
    {
        base.OnMouseRightButtonDown(e);

        WindowStyle = WindowStyle.SingleBorderWindow;
        WindowState = WindowState.Minimized;
    }

    protected override void OnActivated(EventArgs e)
    {
        base.OnActivated(e);

        Dispatcher.BeginInvoke(DispatcherPriority.ApplicationIdle, new Action(() => WindowStyle = WindowStyle.None));
    }
}

解决方案

Edited the answer after experimenting a bit.

There are two options: 1. You can change the Style just before minimising and activating the window:

private void Button_OnClick(object sender, RoutedEventArgs e)
{
    //change the WindowStyle to single border just before minimising it
    this.WindowStyle = WindowStyle.SingleBorderWindow;
    this.WindowState = WindowState.Minimized;
}

private void MainWindow_OnActivated(object sender, EventArgs e)
{
    //change the WindowStyle back to None, but only after the Window has been activated
    Dispatcher.BeginInvoke(DispatcherPriority.ApplicationIdle, new Action(() => WindowStyle = WindowStyle.None));
}

This solution has one limitation - it doesn't animate the window if you minimise it from the taskbar.

2. Minimise the Window by sending it WM_SYSCOMMAND message with SC_MINIMIZE parameter and changing the border style by hooking into the message (HwndSource.FromHwnd(m_hWnd).AddHook(WindowProc)).

internal class ApiCodes
{
    public const int SC_RESTORE = 0xF120;
    public const int SC_MINIMIZE = 0xF020;
    public const int WM_SYSCOMMAND = 0x0112;
}

private IntPtr hWnd;

[DllImport("user32.dll")]
public static extern int SendMessage(IntPtr hWnd, int wMsg, IntPtr wParam, IntPtr lParam);


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

private void Button_Click(object sender, RoutedEventArgs e)
{
    SendMessage(hWnd, ApiCodes.WM_SYSCOMMAND, new IntPtr(ApiCodes.SC_MINIMIZE), IntPtr.Zero);
}

private IntPtr WindowProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
    if (msg == ApiCodes.WM_SYSCOMMAND)
    {
        if (wParam.ToInt32() == ApiCodes.SC_MINIMIZE)
        {
            WindowStyle = WindowStyle.SingleBorderWindow;
            WindowState = WindowState.Minimized;
            handled = true;
        }
        else if (wParam.ToInt32() == ApiCodes.SC_RESTORE)
        {
            WindowState = WindowState.Normal;
            WindowStyle = WindowStyle.None;
            handled = true;
        }
    }
    return IntPtr.Zero;
}

Neither of the above methods are great, because they are just hacks. The biggest downside is that you can actually see the border reappearing for a moment when you click the button. I'd like to see what others come up with as I don't consider this as a good answer myself.

这篇关于自定义窗口样式与动画最小化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆