WPF Window Resizing(WindowResizer.dll)改进

WPF Window Resizing(CodeProject原文)

原文中的代码演示了如何动态实时改变WPF窗口的方法,不过在测试中发现一个小问题,即当鼠标按下后一直向一个方向缩小窗口的时候,当鼠标超过了另一条边的时候(在左边框按下,一直向右拖动鼠标,直到鼠标超过右边框时,异常就出现了,其他四个方向同理)会引发异常.

以下代码在原来的基础上,主要修改了updateSize函数,解决了问题.


2013-04-02:新问题,找时间修改

      1,当拖动左边框的时候,右边框应固定不动,但现在右边框则在不停的闪动,虽然最后的位置是正确的。同样,上下拖动也存在相同的问题。是因为时时改变了当前窗口的左上角坐标点位置,重绘引起的闪动。


完整代码示例:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.Runtime.InteropServices;
using System.Windows.Interop;
using System.Threading;
using System.Windows.Media.Effects;

namespace DNBSoft.WPF
{
    public class WindowResizer
    {
        private Window target = null;

        private bool resizeRight = false;
        private bool resizeLeft = false;
        private bool resizeUp = false;
        private bool resizeDown = false;

        private Dictionary<UIElement, short> leftElements = new Dictionary<UIElement, short>();
        private Dictionary<UIElement, short> rightElements = new Dictionary<UIElement, short>();
        private Dictionary<UIElement, short> upElements = new Dictionary<UIElement, short>();
        private Dictionary<UIElement, short> downElements = new Dictionary<UIElement, short>();

        private PointAPI startMousePoint = new PointAPI();          //鼠标左键点下时的坐标点
        private Size startWindowSize = new Size();                  //鼠标左键点下时,窗口的大小
        private Point startWindowLeftUpPoint = new Point();         //鼠标左键点下时,窗口左上角坐标点位置

        public int minWidth = 10;
        public int minHeight = 10;

        private delegate void RefreshDelegate();

        public WindowResizer(Window target)
        {
            this.target = target;

            if (target == null)
            {
                throw new Exception("Invalid Window handle");
            }
        }

        #region add resize components
        private void connectMouseHandlers(UIElement element)
        {
            element.MouseLeftButtonDown += new MouseButtonEventHandler(element_MouseLeftButtonDown);
            element.MouseEnter += new MouseEventHandler(element_MouseEnter);
            element.MouseLeave += new MouseEventHandler(setArrowCursor);
        }

        public void addResizerRight(UIElement element)
        {
            connectMouseHandlers(element);
            rightElements.Add(element, 0);
        }

        public void addResizerLeft(UIElement element)
        {
            connectMouseHandlers(element);
            leftElements.Add(element, 0);
        }

        public void addResizerUp(UIElement element)
        {
            connectMouseHandlers(element);
            upElements.Add(element, 0);
        }

        public void addResizerDown(UIElement element)
        {
            connectMouseHandlers(element);
            downElements.Add(element, 0);
        }

        public void addResizerRightDown(UIElement element)
        {
            connectMouseHandlers(element);
            rightElements.Add(element, 0);
            downElements.Add(element, 0);
        }

        public void addResizerLeftDown(UIElement element)
        {
            connectMouseHandlers(element);
            leftElements.Add(element, 0);
            downElements.Add(element, 0);
        }

        public void addResizerRightUp(UIElement element)
        {
            connectMouseHandlers(element);
            rightElements.Add(element, 0);
            upElements.Add(element, 0);
        }

        public void addResizerLeftUp(UIElement element)
        {
            connectMouseHandlers(element);
            leftElements.Add(element, 0);
            upElements.Add(element, 0);
        }
        #endregion

        #region resize handlers
        private void element_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            GetCursorPos(out startMousePoint);
            startWindowSize = new Size(target.Width, target.Height);
            startWindowLeftUpPoint = new Point(target.Left, target.Top);

            #region updateResizeDirection
            UIElement sourceSender = (UIElement)sender;
            if (leftElements.ContainsKey(sourceSender))
            {
                resizeLeft = true;
            }
            if (rightElements.ContainsKey(sourceSender))
            {
                resizeRight = true;
            }
            if (upElements.ContainsKey(sourceSender))
            {
                resizeUp = true;
            }
            if (downElements.ContainsKey(sourceSender))
            {
                resizeDown = true;
            }
            #endregion

            Thread t = new Thread(new ThreadStart(updateSizeLoop));
            t.Name = "Mouse Position Poll Thread";
            t.Start();
        }

        private void updateSizeLoop()
        {
            try
            {
                while (resizeDown || resizeLeft || resizeRight || resizeUp)
                {
                    target.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Render, new RefreshDelegate(updateSize));
                    target.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Render, new RefreshDelegate(updateMouseDown));
                    Thread.Sleep(20);
                }

                target.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Render, new RefreshDelegate(setArrowCursor));
            }
            catch (Exception)
            {
            }
        }

        #region updates
        private void updateSize()
        {
            PointAPI currentMousePoint = new PointAPI();
            GetCursorPos(out currentMousePoint);

            try
            {
                if (resizeRight)
                {
                    //如果当鼠标左键点下时,窗口的宽度已经达到最小值,
                    if (target.Width == minWidth)
                    {
                        //鼠标向右移动,表示当前是将窗口变大,此时窗口只能变大,因为已经达到最小宽度了
                        if ((startMousePoint.X - currentMousePoint.X) < 0)
                        {
                            target.Width = this.startWindowSize.Width - (startMousePoint.X - currentMousePoint.X);
                        }
                    }
                    else
                    {
                        //此时,窗口可大可小
                        if ((th
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
Window Resizer 1.0.3 Readme 06-29-2004 -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- Window Resizer 是一个用来修改窗口属性的小程序。 特点: 程序小巧实用,完全绿色软件。 安装: 解开压缩包后直接运行,对于 Windows 98/NT,您需要拷贝 Msvbvm60.dll (建议使用版本号为 6.0.9782 (SP6) 的 Msvbvm60.dll) 到 system 目录中(该文件可在 Windows 2000 中找到, 也可下载 Microsoft VB6 Runtime 补丁)。 功能: - 查找控件的句柄 选择本程序窗口的空白处,拖动到任意目标,松开即可在句柄一栏看到结果。对于无效的 窗口和控件(这类控件一般呈灰色),请先使用菜单中的激活控件命令激活。 - 设置窗口大小 首先拖动本窗口,到合适位置,并调整到适当大小,切换到目标窗口,再返回,程序自动 得到该窗口的句柄,然后选择菜单中的设置窗口大小即可。 - 更改窗口的标题 (也适用于按钮,静态文本和文本框) 切换到目标窗口或控件,然后返回,程序自动得到该窗口的句柄,在窗口标题中输入新值 然后选择菜单中的设置窗口标题即可。 - 同时设置窗口大小和标题 取得句柄后单击设置全部即可。 - 让窗口在前端显示 选定目标窗口,选择菜单中的让窗口前端显示命令。 - 激活窗口/控件/菜单 切换到目标窗口或含有目标控件的窗口,回到本程序,选择本程序菜单中的激活控件即可。 该功能被开启后一直有效,直到再次选择相应菜单。 - 半透明显示窗口 该功能仅在 Windows 2000 / Windows XP / Windows Server 2003 和 Windows Vista 中有效。 注意: 调整有些程序大小更改文字或执行灰色按钮可能造成意想不到的情况,请慎用。 本程序完全免费,欢迎自由传播,但是请不要擅自修改它。 请不要将本程序作为商业用途,或用于破解别人程序。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值