zoukankan      html  css  js  c++  java
  • WPF实现窗口比例恒定不变小结(2)

    WPF实现窗口比例恒定不2

    在上一篇中讲到可以通过捕获并处理WM_EXITSIZEMOVE消息来达到保持窗口比例不变,但是必须在释放鼠标的情况下才能调整窗口比例,算不上实时调整。在上一遍还提到在窗口的SizeChanged事件中调整窗口比例,但是因为事件触发的太频繁,导致在释放鼠标后窗口又还原为拖拉之前的大小。

    那能不能实现窗口比例的实时调整呢?让我们来看看下面一种方法。

    其实这种方法就是结合SizeChanged事件和WM_EXITSIZEMOVE消息。让我们先来分析下这2个方式:

    SizeChanged事件:

        优点:能够在鼠标按下(拖拉住窗口不放)的情况下实时调整窗口;

        缺点:在释放鼠标后,窗口可能会还原为拖拉之前的大小;

    WM_EXITSIZEMOVE消息:

        优点:在释放鼠标后,窗口能够保持拖拉后的大小;

        缺点:不能实时调整窗口,只能在释放鼠标后调整窗口;

    我们把这2种方式的结合起来,就能够弥补2者的缺点,达到实时保持窗口比例的效果。下面我分别列出2者的代码:

    处理WM_EXITSIZEMOVE消息代码:

            /// <summary>

            /// 重载窗口资源加载函数

            /// </summary>

            protected override void OnSourceInitialized(EventArgs e)

            {

                base.OnSourceInitialized(e);

                HwndSource source = HwndSource.FromVisual(this) as HwndSource;

                if (source != null)

                {

                    // 注册窗口消息处理函数

                    source.AddHook(new HwndSourceHook(WinProc));

                }

            }

            public const Int32 WM_EXITSIZEMOVE = 0x0232;

            /// <summary>

            ///窗口消息处理函数

            /// </summary>

            private IntPtr WinProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, ref Boolean handled)

            {

                IntPtr result = IntPtr.Zero;

                switch (msg)

                {

                    // 窗口消息处理

                    case WM_EXITSIZEMOVE:

                        {

                            // 上下拖拉窗口

                            if (this.Height != LastHeight)

                            {

                                this.Width = this.Height * dAspectRatio;

                            }

                            else // 左右拖拉窗口

                            {

                                this.Height = this.Width / dAspectRatio;

                            }

                            // 把修改后的窗口大小记录下来

                            LastWidth = (int)this.Width;

                            LastHeight = (int)this.Height;

                            break;

                        }

                }

                return result;

            }

        注意:代码和上一篇一致,未修改。

        处理SizeChanged事件代码

            // 声明一个定时器

            private Timer timer;

            /// <summary>

            /// SizeChanged事件处理函数

            /// </summary>

            private void Window_SizeChanged(object sender, SizeChangedEventArgs e)

            {

                if (timer != null)

                    timer.Dispose();

                // 注册定时器处理函数和定时器触发时间

                timer = new Timer(setSize, e, 80, 100);

            }

            /// <summary>

            /// 定时器处理函数

            /// </summary>

            private void setSize(object eo)

            {

                SizeChangedEventArgs e = eo as SizeChangedEventArgs;

                if (e.WidthChanged) // 左右拖拉窗口

                {

                    if (e.NewSize.Height != e.NewSize.Width / dAspectRatio)

                    {

                        this.Dispatcher.BeginInvoke(new Action(() => { this.Height = e.NewSize.Width / dAspectRatio; }));

                    }

                }

                else if (e.HeightChanged) // 上下拖拉窗口

                {

                    if (e.NewSize.Width != e.NewSize.Height * dAspectRatio)

                    {

                        this.Dispatcher.BeginInvoke(new Action(() => { this.Width = e.NewSize.Height * dAspectRatio; }));

                    }

                }

                // 解除定时器

                timer.Dispose();

            }

        注意:这里采用定时器来延迟每一次调整窗口,这是因为直接调整窗口会导致SizeChanged事件触发的太频繁了!!!会导致窗口混乱的,所以我这里采用的定时器,为每一次SizeChanged事件触发延迟了80ms,当然这个事件可以调,不过最好不要小于50ms。

        好了,代码贴完了,让我们来总结一下。这篇主要阐述的就是如何通过SizeChanged事件和WM_EXITSIZEMOVE消息来达到实时保持窗口比例的效果。用SizeChanged事件实时调整窗口比例(在鼠标按下不放的情况),用WM_EXITSIZEMOVE消息来最后定下窗口大小。两者结合使用,从而达到保持窗口比例的效果。不过屏幕可能还有闪烁。

        好了,今天就写到这里了。

    nbsp;

  • 相关阅读:
    记录wordpress+nginx配置的坑
    Nginx进行反向代理多个web项目
    Docker 安装 Zabbix-4
    小特跨境电商ERP 小程序版 库存好帮手
    小特跨境电商ERP 浏览器版 为决策者提供数据支持
    小特跨境电商ERP桌面版 8.如何部署 真的这么难安装吗?
    小特跨境电商ERP桌面版 7.销售订单毛利计算 就是这么简单
    小特跨境电商ERP桌面版 6.运费结算是个大问题?容易一团糟
    小特跨境电商ERP桌面版 5.订单发货提交后,后续还要做什么?
    小特跨境电商ERP桌面版 4.平台商品和本地单品如何映射?
  • 原文地址:https://www.cnblogs.com/wuhaowinner/p/keep_aspect_ratio.html
Copyright © 2011-2022 走看看