前言
罗技鼠标的驱动中可以通过编写宏的方式实现任意字符串的输出,可是我在WPS中使用时会出现bug,整个字符串会变为第一个字符的重复,不清楚这是我电脑的个例还是普遍情况。为了解决这个问题,我就想到了WinCompose这个软件,当初写qmk键盘固件的时候第一次接触到该软件,按下组合键后输入一段序列就可以直接输出预先定义好的字符串。Lua脚本搭配上该软件可以实现一些比较好玩的功能。
WinCompose
首先给出该项目地址:
https://github.com/samhocevar/wincompose
A compose key for Windows, free and open-source, created by Sam Hocevar.
A compose key allows to easily write special characters such as é ž à ō û ø ☺ ¤ ∅ « ♯ ⸘ Ⓚ ㊷ ♪ ♬ using short and often very intuitive key combinations. For instance, ö is obtained using o + ", and ♥ is obtained using < + 3.
WinCompose also supports Emoji input for 😁 👻 👍 💩 🎁 🌹 🐊.
功能实现
-- WinCompose软件中设定的组合键
local WINC_KEY = "ralt"
-- 输入序列时按键的间隔,过小会出现软件反应不及时的情况
local WINC_INTERVAL = 10
function TypeUnicodeWords(words)
local word, i
-- 正则匹配unicode编码
for word in string.gmatch(words, "%\\u(%w+)") do
-- 输入WinCompose序列
PressAndReleaseKey(WINC_KEY)
Sleep(WINC_INTERVAL)
PressAndReleaseKey("u")
for i=1, #word do
Sleep(WINC_INTERVAL)
PressAndReleaseKey(string.sub(word, i, i))
end
Sleep(WINC_INTERVAL)
PressAndReleaseKey("enter")
end
end
上面的代码中只给出了关键参数和功能函数,具体的应用可以看下面的应用实例。
因为罗技的脚本中不支持中文,所有使用这个函数的时候需要提前对字符串进行unicode编码转换,最简单的方法就是直接找一个在线转换工具,比如下面这个网站:
https://tool.ip138.com/ascii/
在脚本中要注意使用[[ ]]
这种忽略转义的字符串表示形式,例如:
local example = [[\u6d4b\u8bd5\u6587\u5b57\u000a\u0061\u0062\u0043\u0044\u000a\uff0c\u3002\u002c\u002e]]
应用实例
人一天之中最常问自己的问题是什么呢?毫无疑问就是“吃什么”,本次的实例就是编写一个可以回答这一问题的脚本。按下功能键后就会输出预定义菜单中随机一个选项。
-- WinCompose软件中设定的组合键
local WINC_KEY = "ralt"
-- 输入序列时按键的间隔,过小会出现软件反应不及时的情况
local WINC_INTERVAL = 10
-- 菜单,weight可取任意自然数,数值越大,随机到的可能性越大
local MENU = {
-- 饺子
{name=[[\u997a\u5b50]], weight=4},
-- 汉堡
{name=[[\u6c49\u5821]], weight=0},
-- 披萨
{name=[[\u62ab\u8428]], weight=2},
-- 螺蛳粉
{name=[[\u87ba\u86f3\u7c89]], weight=1},
}
-- 是否检测鼠标左键的相关事件
EnablePrimaryMouseButtonEvents(false)
function OnEvent(event, arg)
if (event == "MOUSE_BUTTON_PRESSED" and arg == 7) then
RandomEat(MENU)
end
end
function RandomEat(menu)
-- 创建局部变量
local t = {}
local total = 0
local key, item, target
-- 根据menu创建权值表
for key, item in pairs(menu) do
total = total + item.weight
t[key] = total
end
-- 根据总权值roll点
math.randomseed(GetRunningTime())
target = math.random(t[#t])
-- 根据点数在权值表中查找对应序列号
for key, item in pairs(t) do
if (target <= item) then
TypeUnicodeWords(menu[key].name)
return
end
end
end
function TypeUnicodeWords(words)
local word, i
-- 正则匹配unicode编码
for word in string.gmatch(words, "%\\u(%w+)") do
-- 输入WinCompose序列
PressAndReleaseKey(WINC_KEY)
Sleep(WINC_INTERVAL)
PressAndReleaseKey("u")
for i=1, #word do
Sleep(WINC_INTERVAL)
PressAndReleaseKey(string.sub(word, i, i))
end
Sleep(WINC_INTERVAL)
PressAndReleaseKey("enter")
end
end