一直想给 Quicker 的沙拉查词动作 加个划词小图标,实现真正的划词翻译。
类似的划词翻译:
目前实现的效果:
体验跟有道差太多了😭用的话勉强能用。。。。
下面就简单记录下实现的思路(→_→)
识别划词
网上有的说使用系统接口,或者调用金山词霸的
dll。看得有点混乱,难下手。
于是决定换一个简单但不完美的思路——监听鼠标的左键事件 。
Quicker 恰好提供了按键检测模块,现成的轮子美滋滋( ̄y▽, ̄)╭
划词一共有两种状态,满足下面这两种状态则模拟 Ctrl+C
获取文本,获取文本成功就是划词成功了。
按照上面的思路,简单画一个实现流程
太长我也没眼看了😳
到这一步的话大概就是知云文献翻译的效果。
划词图标
划词小图标简单的实现想法:在划词后,弹出一个小窗口,小窗口的位置在鼠标附近。
在 Quicker 动作中写窗口的话首选 C# 了(Quicker 支持运行 C#
代码,并且动作库中也有不少 C#实现的动作),于是决定尝试下
C#,写一个小窗口就溜。
零基础第一步:以前看到 C# 脑里会变成 C 井 🤣,查了下原来叫 C
Sharp。(菜鸡说起都是泪)
第二步:B 站白嫖入门教程。一开始看 B 站的C#语言入门详解 ,没看一点就原地螺旋升天睡着了。不过好歹也知道自己需要的是
C# 的 WinForm 程序。
第三步:C# WinForm 教程。再次来到学习网站 B 站,C# WinForm 图形界面
GUI 编程62 集视频教程
(桌面开发) 阿发你好 🤣🤣。实际上也没看多少,看了前面几个就差不多弄一个比较理想的窗口了。
第四步:特定问题。一些特定的问题,直接搜索参考(抄袭)别人的解决方案就行。
程序中只涉及两个部分,主窗口和按钮。
实现逻辑:
检测到划词操作成功后,则运行 C# 程序,在鼠标附近弹出且置顶。
如果鼠标点击划词图标(按钮),那么关闭窗口,并且给 Quicker
返回成功触发值。
如果鼠标点击了图标外部,使得图标失去了焦点,那么关闭窗口,并且给
Quicker 返回未成功触发值。
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 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 using System.Drawing; using System.Windows.Forms; public static void Exec (Quicker.Public.IStepContext context) { var getBitmp = context.GetVarValue("saladictImg" ); Image pic = getBitmp as Image; Saladict.icon = pic; Saladict form = new Saladict(); form.ShowDialog(); bool trigger = Saladict.triggerSuccess; context.SetVarValue("CSharpTrigger" , trigger); } public partial class Saladict : Form { public static bool triggerSuccess = false ; public static Image icon; public Saladict () { InitializeComponent(); this.CloseButton.BackgroundImage = icon; } private void Saladict_Load (object sender, EventArgs e) { var _point = new System.Drawing.Point(Cursor.Position.X, Cursor.Position.Y); Top = _point.Y; Left = _point.X; this.BackColor = Color.Black; this.TransparencyKey = Color.Black; } private void Clicked (object sender, EventArgs e) { triggerSuccess = true ; this.Deactivate -= LoseFocus; this.Close(); } private void LoseFocus (object sender, EventArgs e) { triggerSuccess = false ; this.Deactivate -= LoseFocus; this.Close(); } private System.ComponentModel.IContainer components = null; protected override void Dispose (bool disposing) { if (disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } #region Windows 窗体设计器生成的代码 private void InitializeComponent () { this.CloseButton = new System.Windows.Forms.Button(); this.SuspendLayout(); this.CloseButton.BackColor = System.Drawing.Color.Transparent; this.CloseButton.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Stretch; this.CloseButton.FlatAppearance.BorderSize = 0 ; this.CloseButton.FlatAppearance.MouseDownBackColor = System.Drawing.Color.Transparent; this.CloseButton.FlatAppearance.MouseOverBackColor = System.Drawing.Color.Transparent; this.CloseButton.FlatStyle = System.Windows.Forms.FlatStyle.Flat; this.CloseButton.ForeColor = System.Drawing.Color.Transparent; this.CloseButton.Location = new System.Drawing.Point(0 , 0 ); this.CloseButton.Margin = new System.Windows.Forms.Padding(0 ); this.CloseButton.MaximumSize = new System.Drawing.Size(40 , 40 ); this.CloseButton.MinimumSize = new System.Drawing.Size(30 , 30 ); this.CloseButton.Name = "CloseButton" ; this.CloseButton.Size = new System.Drawing.Size(40 , 40 ); this.CloseButton.TabIndex = 0 ; this.CloseButton.UseVisualStyleBackColor = false ; this.CloseButton.Click += new System.EventHandler(this.Clicked); this.AutoScaleDimensions = new System.Drawing.SizeF(8F , 15F ); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.AutoSize = true ; this.BackgroundImageLayout = System.Windows.Forms.ImageLayout.None; this.ClientSize = new System.Drawing.Size(40 , 40 ); this.Controls.Add(this.CloseButton); this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None; this.MaximumSize = new System.Drawing.Size(40 , 40 ); this.MinimumSize = new System.Drawing.Size(30 , 30 ); this.Name = "Saladict" ; this.ShowInTaskbar = false ; this.StartPosition = System.Windows.Forms.FormStartPosition.Manual; this.TopMost = true ; this.Deactivate += new System.EventHandler(this.LoseFocus); this.Load += new System.EventHandler(this.Saladict_Load); this.ResumeLayout(false ); } #endregion private System.Windows.Forms.Button CloseButton; }
其实还存在几个令人非常不爽的问题,程序比较简陋。
弹出的窗口会抢占焦点
图标显示有锯齿
没有处理高分屏显示的问题。(主要是贫穷如我没有高分屏😅)
实现过程中一个小插曲——这图标文件怎么存。想了两个方案
检查电脑特定路径中是否存在图标文件,不存在就后台下载一份。
把图标转成 base64 编码,以文本形式存在 Quicker
变量中,要用的时候再转回图片,传入 C#。
还是第二个方案比较好一点,免得下载文件了。
总结
需求才是学习的最大动力啊,用着 Quicker
附带着学了其他东西。下面总结下划词的实现。
实现过程:
首先要判断是否划词成功——通过监控鼠标左键状态实现。
其次要在划词成功后弹出划词图标——通过 C# WinForm 画一个小窗口。
存在问题:
纯粹通过鼠标左键来判断划词容易误判;并且模拟 Ctrl+C
获取文本也容易在某些窗口引起误操作(例如终端窗口)。
划词图标抢占焦点;图标显示有锯齿;高分屏不友好。
划词图标抢占焦点的问题,虽然可通过加载鼠标挂钩获取全局坐标来判断,但是实现成本太高,响应速度也成问题,故暂时不考虑这个方案了。