• Github每日精选(第40期):为 Windows 带来 macOS “快速查看”功能QuickLook


    QuickLook

    QucikLookmacOS 中的Quick Look 快速查看功能,它允许用户通过按键Space以闪电般的速度查看文件内容。

    这个功能是非常有用的,特别是对于查找文件的时候,我们可能不清楚里面的内容,通过这个软件,我们只要轻轻的按一下,空格键,我们马上就能够预览里面的内容了。然而到现在为止,Windows 没有这个方便的功能…

    作者知道在 Internet 上已经有几种替代方法可用(例如WinQuickLookSeer)。尽管有这些选择,作者仍然决定自己制作另一个,因为它们要么没有被积极开发,缺乏多样性,要么要求一些其他的资源。

    github的地址在这里

    在这里插入图片描述

    能带来什么

    我们先来看看QuickLook 能 给我们带来什么,看我们在查看文件的时候,我们想看看这个word里面写了什么,我们可以这样操作。

    选择我们要查看的word文件,按下空格键。

    在这里插入图片描述

    再来,我们先看看zip文件中,存在哪些文件,这是一个实用的操作,选到该压缩文件,轻轻按下空格键。压缩文件中的内容,清楚的展现在我们的眼前。

    在这里插入图片描述

    确实非常的直观好用。

    下载/安装

    到这里,下载release版本的,安装就可以了。

    热键和按钮
    • Spacebar 显示/隐藏预览窗口
    • Esc隐藏预览窗口
    • Enter打开/执行当前文件
    • Mouse ↑ ↓ ← →预览另一个文件
    • Mouse Wheel放大/缩小(图像)
    • Ctrl+Mouse Wheel放大/缩小 (PDF)
    • Wheel增加/减少音量
    相关代码分析

    当我们按住 空格键,我们是怎么知道相应的消息的呢?QuickLook 使用了hook的手段。来看看相关的代码。

    using System;
    using System.Windows.Forms;
    using System.Windows.Input;
    using QuickLook.Common.NativeMethods;
    using KeyEventArgs = System.Windows.Forms.KeyEventArgs;
    using KeyEventHandler = System.Windows.Forms.KeyEventHandler;
    
    namespace QuickLook.Helpers
    {
        internal class GlobalKeyboardHook : IDisposable
        {
            private static GlobalKeyboardHook _instance;
    
            private User32.KeyboardHookProc _callback;
            private IntPtr _hhook = IntPtr.Zero;
    
            protected GlobalKeyboardHook()
            {
                Hook();
            }
    
            public void Dispose()
            {
                GC.SuppressFinalize(this);
    
                Unhook();
            }
    
            internal event KeyEventHandler KeyDown;
            internal event KeyEventHandler KeyUp;
    
            internal static GlobalKeyboardHook GetInstance()
            {
                return _instance ?? (_instance = new GlobalKeyboardHook());
            }
    
            private void Hook()
            {
                _callback = HookProc;
    
                var hInstance = Kernel32.LoadLibrary("user32.dll");
                _hhook = User32.SetWindowsHookEx(User32.WH_KEYBOARD_LL, _callback, hInstance, 0);
            }
    
            private void Unhook()
            {
                if (_callback == null) return;
    
                User32.UnhookWindowsHookEx(_hhook);
    
                _callback = null;
            }
    
            private int HookProc(int code, int wParam, ref User32.KeyboardHookStruct lParam)
            {
                if (code < 0)
                    return User32.CallNextHookEx(_hhook, code, wParam, ref lParam);
    
                if (IsWindowsKeyPressed())
                    return User32.CallNextHookEx(_hhook, code, wParam, ref lParam);
    
                var key = (Keys) lParam.vkCode;
                key = AddModifiers(key);
    
                var kea = new KeyEventArgs(key);
    
                if (wParam == User32.WM_KEYDOWN || wParam == User32.WM_SYSKEYDOWN)
                    KeyDown?.Invoke(this, kea);
                else if (wParam == User32.WM_KEYUP || wParam == User32.WM_SYSKEYUP)
                    KeyUp?.Invoke(this, kea);
    
                return kea.Handled ? 1 : User32.CallNextHookEx(_hhook, code, wParam, ref lParam);
            }
    
            private bool IsWindowsKeyPressed()
            {
                return Keyboard.IsKeyDown(Key.LWin) || Keyboard.IsKeyDown(Key.RWin);
            }
    
            private Keys AddModifiers(Keys key)
            {
                //Ctrl
                if ((Keyboard.Modifiers & ModifierKeys.Control) != 0) key = key | Keys.Control;
    
                //Shift
                if ((Keyboard.Modifiers & ModifierKeys.Shift) != 0) key = key | Keys.Shift;
    
                //Alt
                if ((Keyboard.Modifiers & ModifierKeys.Alt) != 0) key = key | Keys.Alt;
    
                return key;
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
  • 相关阅读:
    Java学习笔记4.4.2 包装类 - 基本数据类型、包装类与字符串相互转换
    跨越千年医学对话:用AI技术解锁中医古籍知识,构建能够精准问答的智能语言模型,成就专业级古籍解读助手(LLAMA)
    算法学习 | 动态规划经典练习题合集
    ARM学习
    哈希表专项练习 LeetCode
    [Qt]QListView 重绘实例之三:滚动条覆盖的问题处理
    Linux系统进程的个人理解和解释
    全渠道商城授权管控经销商,渠道商管理系统助力医药企业快速扩大渠道规模
    C#中BitConverter.ToUInt16、BitConverter.ToUInt32原理与用法详解
    Leaflet结合Echarts实现迁徙图
  • 原文地址:https://blog.csdn.net/weixin_40425640/article/details/126366863