美文网首页
WPF放大镜的实现

WPF放大镜的实现

作者: 雪之梦_8f14 | 来源:发表于2019-07-22 17:55 被阅读0次

源代码

准备

  • 通过nuget 获取MouseKeyHook 库


    image.png
  • 添加Forms和Drawing两个dll的引用
  • Native代码 API准备
        #region Native

        const int SM_XVIRTUALSCREEN = 76;
        const int SM_YVIRTUALSCREEN = 77;
        const int SM_CXVIRTUALSCREEN = 78;
        const int SM_CYVIRTUALSCREEN = 79;

        const int SM_CXSCREEN = 0;
        const int SM_CYSCREEN = 1;

        [DllImport("Magnification.dll")]
        public static extern bool MagSetFullscreenTransform(float level, int xOffset, int yOffsety);

        [DllImport("Magnification.dll")]
        public static extern bool MagGetFullscreenTransform(out float level, out int xOffset, out int yOffsety);

        [DllImport("Magnification.dll")]
        public static extern bool MagInitialize();

        [DllImport("user32.dll")]
        public static extern int GetSystemMetrics(int index);

        #endregion Native

代码

工具类代码

 public static class MagnifierHelper
    {
        #region Native

        const int SM_XVIRTUALSCREEN = 76;
        const int SM_YVIRTUALSCREEN = 77;
        const int SM_CXVIRTUALSCREEN = 78;
        const int SM_CYVIRTUALSCREEN = 79;

        const int SM_CXSCREEN = 0;
        const int SM_CYSCREEN = 1;

        [DllImport("Magnification.dll")]
        public static extern bool MagSetFullscreenTransform(float level, int xOffset, int yOffsety);

        [DllImport("Magnification.dll")]
        public static extern bool MagGetFullscreenTransform(out float level, out int xOffset, out int yOffsety);

        [DllImport("Magnification.dll")]
        public static extern bool MagInitialize();

        [DllImport("user32.dll")]
        public static extern int GetSystemMetrics(int index);

        #endregion Native

        const int GAP = 100;

        static float _magnificationFactor = 2f;

        private static IKeyboardMouseEvents m_GlobalHook;

        public static float MagnificationFactor
        {
            get { return _magnificationFactor; }
            set
            {
                if (value < 1)
                {
                    value = 1;
                }

                if (value > 1)
                {
                    IsZoomed = true;
                }
                else
                {
                    IsZoomed = false;
                }
                _magnificationFactor = value;
            }
        }

        private static Rectangle _boundary;

        private static int _virtualLeft = 0;

        private static int _virtualTop = 0;

        private static int _virtualOffsetX = 0;

        private static int _virtualOffsetY = 0;

        private static bool _magInitialized = false;

        public static bool MagInitialized
        {
            get { return _magInitialized; }
            private set
            {
                _magInitialized = value;
            }
        }

        #region FullProperty IsZoomed

        private static bool _isZoomed;

        public static bool IsZoomed
        {
            get { return _isZoomed; }
            set { _isZoomed = value; }
        }

        #endregion  FullProperty IsZoomed

        static MagnifierHelper()
        {
            int left = GetSystemMetrics(SM_XVIRTUALSCREEN);
            int top = GetSystemMetrics(SM_YVIRTUALSCREEN);

            int width = GetSystemMetrics(SM_CXVIRTUALSCREEN);
            int height = GetSystemMetrics(SM_CYVIRTUALSCREEN);

            _virtualLeft = left;
            _virtualTop = top;

            var offsetX = left - left / _magnificationFactor;

            var offsetY = top - top / _magnificationFactor;

            _virtualOffsetX = (int)offsetX;
            _virtualOffsetY = (int)offsetY;

            _boundary = new Rectangle(left, top, width, height);

            MagInitialized = MagInitialize();

            Subscribe();
        }

        private static void SetZoom(int offsetX, int offsetY)
        {
            if (_magnificationFactor < 1.0)
            {
                return;
            }

            App.Current.Dispatcher.BeginInvoke((Action)(() =>
                        {
                            MagSetFullscreenTransform(_magnificationFactor, offsetX, offsetY);
                        }));
        }

        // 此方法必须使用ui线程执行
        public static void ZoomIn(float factor)
        {
            MagnificationFactor = factor;

            int xDlg = (int)((float)GetSystemMetrics(
            SM_CXSCREEN) * (1.0 - (1.0 / _magnificationFactor)) / 2.0);
            int yDlg = (int)((float)GetSystemMetrics(
                SM_CYSCREEN) * (1.0 - (1.0 / _magnificationFactor)) / 2.0);

            //SetZoom(_virtualOffsetX, _virtualOffsetY);
            SetZoom(xDlg, yDlg);
        }

        /// <summary>
        /// 取消放大
        /// </summary>
        public static void ZoomOut()
        {
            QuitMagnify();
        }

        private static void QuitMagnify()
        {
            MagnificationFactor = 1;

            SetZoom(0, 0);
        }

        private static void Subscribe()
        {
            m_GlobalHook = Hook.GlobalEvents();

            m_GlobalHook.MouseMove += M_GlobalHook_MouseMove;
        }

        private static Rectangle GetVisibleRegion()
        {
            Rectangle rect = new Rectangle();

            float level;
            int xOffset;
            int yOffset;
            bool ret1 = MagGetFullscreenTransform(out level, out xOffset, out yOffset);

            var transformWidth = (int)(_boundary.Width / level);
            var transformHeight = (int)(_boundary.Height / level);

            rect.X = xOffset - _virtualOffsetX;
            rect.Y = yOffset - _virtualOffsetY;
            rect.Width = transformWidth;
            rect.Height = transformHeight;

            return rect;
        }

        private static Rectangle GetEdgeRegion()
        {
            var visibleRegion = GetVisibleRegion();

            visibleRegion.X += GAP;

            visibleRegion.Y += GAP;

            visibleRegion.Width -= 2 * GAP;

            visibleRegion.Height -= 2 * GAP;

            return visibleRegion;
        }

        private static void M_GlobalHook_MouseMove(object sender, System.Windows.Forms.MouseEventArgs e)
        {
            //return;
            if (!IsZoomed)
            {
                return;
            }

            var visibleRegion = GetVisibleRegion();

            var edgeRegion = GetEdgeRegion();

            float level;
            int xOffset;
            int yOffset;
            bool ret1 = MagGetFullscreenTransform(out level, out xOffset, out yOffset);

            if (level <= 1)
            {
                return;
            }

            var point = e.Location;

            point.X -= _virtualLeft;
            point.Y -= _virtualTop;


            // 左侧
            if (point.X < edgeRegion.X)
            {
                if (xOffset >= _boundary.Left)
                {
                    xOffset -= 5;

                    if (xOffset < _virtualOffsetX)
                    {
                        xOffset = _virtualOffsetX;
                    }
                }
            }

            // 上侧
            if (point.Y < edgeRegion.Y)
            {
                if (yOffset >= _virtualOffsetY)
                {
                    yOffset -= 5;

                    if (yOffset < _virtualOffsetY)
                    {
                        yOffset = _virtualOffsetY;
                    }
                }
            }

            // 右侧
            if (point.X > edgeRegion.Right)
            {
                xOffset += 5;
            }

            // 下侧
            if (point.Y > edgeRegion.Bottom)
            {
                yOffset += 5;
            }

            var maxX = (int)(_boundary.Width - _boundary.Width / level) + _virtualOffsetX;
            var maxY = (int)(_boundary.Height - _boundary.Height / level) + _virtualOffsetY;

            if (xOffset > maxX)
            {
                xOffset = maxX;
            }

            if (yOffset > maxY)
            {
                yOffset = maxY;
            }

            SetZoom(xOffset, yOffset);
        }

        public static void Dispose()
        {
            m_GlobalHook.MouseMove -= M_GlobalHook_MouseMove;
            m_GlobalHook.Dispose();
        }

        //private static void SetInputStream()
        //{
        //    float level;
        //    int xOffset;
        //    int yOffset;
        //    bool ret1 = MagGetFullscreenTransform(out level, out xOffset, out yOffset);

        //    if ()
        //}
    }

调用代码

MagnifierHelper.ZoomIn(2.0f);
 MagnifierHelper.ZoomOut();

相关文章

  • WPF放大镜的实现

    源代码 源码地址 准备 通过nuget 获取MouseKeyHook 库image.png 添加Forms和Dra...

  • WPF放大镜效果

    在做WPF项目中,不止两个项目需要有放大镜功能。第一个项目是一个手术室的远程示教系统,主要是为了方便专家演示病症时...

  • WPF中使用传感器

    在WPF 中使用传感器已知有两种方式可以实现: C++通过实现COM接口的方式拿到数据,再传到WPF中使用 直接使...

  • WPF简介

    目录 什么是WPF? WPF的历史? 为什么要用WPF及WPF作用 WPF与winForm区别? 什么是WPF? ...

  • 关于用mfc(c++)调用wpf(C#)编写的dll,实现界面消

    关于用mfc(c++)调用wpf(C#)编写的dll,实现界面消息回调的方法。 这几天有一个小项目。使用wpf...

  • 2018-12-01

    JS实现放大镜功能 网店中的商品都能放大查看细节,这里是放大功能的简单实现。。。。 这个放大镜具有选择放大倍数的功...

  • 【WPF】WPF介绍

    一、WPF简介 WPF:WPF即Windows Presentation Foundation,翻译为中文“Win...

  • WPF中使用加速键(或称访问键)

    在界面中有很多字母带下划线的加速键如下图中带下划线的字母,在WPF如何实现呢? 如何定义 WPF中定义比较简单,就...

  • javascript实现放大镜插件【含进阶】

    [目录] 【简单的实现放大镜动能】 成果图 放大镜的原理 网页结构 实现步骤第一步 获取元素第二步 注册鼠标进...

  • WPF/C#学习笔记.1:WPF中的布局TabControl,G

    WPF/C#学习笔记.1 WPF中的布局TabControl,Grid与GridSpliter等 WPF布局原则 ...

网友评论

      本文标题:WPF放大镜的实现

      本文链接:https://www.haomeiwen.com/subject/mbawlctx.html