StrokesPlus.net教程及脚本持续更新

ShareX快捷键设置,添加一个命名Screenshot and Copy

ShareX安装路径双反斜杠
测试没问题

var clientId = "1UVb6fiUzC1hyzwT2zvsOcwi";
var clientSecret = "de1XdmFwNKx32NWw3b4LHsPh0AvyyALT";

var startimage = clip.GetImage();

var actionName = "Screenshot and Copy"

result = sp.RunProgram('C:\\Program Files\\ShareX\\ShareX.exe', 
                           `-workflow "${actionName}"`,
                           'open', 'hidden', false, true, true);

//sp.Sleep(100);
for(i=0; i< 60; i++) {
//ScreenClippingHost
    
    sp.Sleep(1000);
    var fgWinTitle = sp.ForegroundWindow().Title;
    var currimage = clip.GetImage();
    if(i > 0 && fgWinTitle != "ShareX - 区域捕捉" && clip.ContainsImage()) {

            sp.Sleep(100); 

            var ms = new clr.System.IO.MemoryStream();
            currimage.Save(ms, drawing.System.Drawing.Imaging.ImageFormat.Png);
            ms.Position = 0;
            var base64Img = clr.System.Convert.ToBase64String(ms.GetBuffer());
            //var imgHTML = "<img alt='Clipped Image' src='" + "data:image/png;base64," + base64Img + "' />";
            //clip.SetText(imgHTML);
            ms.Close();

            var authHost = "https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id=" + clientId + "&client_secret=" + clientSecret;
            var client = new http.System.Net.Http.HttpClient();
            var json = client.GetStringAsync(authHost);
            var obj = JSON.parse(json.Result);
            client.Dispose();

            if (obj.access_token) {
                var token = obj.access_token;
                var ocrHost = "https://aip.baidubce.com/rest/2.0/ocr/v1/general_basic?access_token=" + token;
                var request = clr.System.Net.WebRequest.Create(ocrHost);
                request.Method = "post";
                var encoding = clr.System.Text.Encoding.Default;
                var paraString = "image=" + clr.System.Net.WebUtility.UrlEncode(base64Img);
                var buffer =  encoding.GetBytes(paraString);
                request.ContentLength = buffer.Length;
                request.GetRequestStream().Write(buffer, 0, buffer.Length);

                var response = request.GetResponse();
                var reader = new clr.System.IO.StreamReader(response.GetResponseStream(), clr.System.Text.Encoding.UTF8);
                var result = reader.ReadToEnd();

                var json = JSON.parse(result);
                var jsonArray = json.words_result;
                if (jsonArray) {
                    var OCRText = "";
                    for(var i=0; i<jsonArray.length; i++) {
                        OCRText += jsonArray[i].words
                    }
                    if (OCRText.length) {
                        clip.SetText(OCRText);
                        //clr.System.Media.SystemSounds.Asterisk.Play();
                    }
                }
                else {
                    clip.SetText(result);
                }
                
                response.Dispose();
                reader.Dispose();
            }

        //以下break前的注释代码内容为屏幕左下角显示OCR结果,根据需要选用

        /*var info = new DisplayTextInfo();
        //info.Title = 'Test';
        info.TitleAlignment = 'Center';
        info.Message = clip.GetText();
        info.MessageAlignment = 'Left';
        info.Duration = 2000;
        //弹出窗口的透明度,有效范围:0.05  -  1.0(1.0不透明)
        info.Opacity = 0.5;
        //位置也支持位置,使用此格式指定类型:'100,200'
        //类型:topleft,top,topright,right,bottomright,bottom,bottomleft,left
        info.Location = 'bottom'; 
        info.TitleFont = new Font('Segoe UI', 12, host.flags(FontStyle.Bold));
        info.MessageFont = new Font('Segoe UI Semibold', 12);
        //info.BackColor = '56,169,255';//'56,169,255'; //也支持 RGBinfo.ForeColor = 'white';
        info.BackColor = "105,105,105";             
        info.Padding = 10;//大小
        //如果为true,则始终显示在主屏幕上(除非Location是点类型),
        //否则会在手势开始的屏幕上显示
        info.UsePrimaryScreen = true; 
        sp.DisplayText(info);
        //sp.DisplayTextUpdate(info);
        */

        break;
    }
}

谢谢分享!
不过暂时不想再装app
继续用系统截图来吧

ps:mouseinc是怎么集成屏幕OCR的,感觉比较小巧且稳定

添加个截图功能就行了

但是用s+添加截图代码麻烦

用系统截图 卡到提示没脚本频次啥样

对了,S+有个鼠标右键框选区域显示截图的

不是截图拖选框,截图区域太小不好控制

var clientId = "1UVb6fiUzC1hyzwT2zvsOcwi";
var clientSecret = "de1XdmFwNKx32NWw3b4LHsPh0AvyyALT";

sp.Sleep(100); 
//Create a new Bitmap in memory
var memoryImage = new drawing.System.Drawing.Bitmap(action.Bounds.Width, action.Bounds.Height);
//Create a graphics object associated with the bitmap
var memoryGraphics = drawing.System.Drawing.Graphics.FromImage(memoryImage);
//Copy the screen within the bounding rectangle of the drawn gesture area
//I used a square gesture since that seems more intuitive, but it's not neccessary
memoryGraphics.CopyFromScreen(action.Bounds.X, action.Bounds.Y, 0, 0, action.Bounds.Size);
var ms = new clr.System.IO.MemoryStream();
memoryImage.Save(ms, drawing.System.Drawing.Imaging.ImageFormat.Png);
ms.Position = 0;
var base64Image = clr.System.Convert.ToBase64String(ms.GetBuffer());
memoryGraphics.Dispose();
memoryImage.Dispose();
ms.Dispose()

var authHost = "https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id=" + clientId + "&client_secret=" + clientSecret;
var client = new http.System.Net.Http.HttpClient();
var json = client.GetStringAsync(authHost);
var obj = JSON.parse(json.Result);
client.Dispose();

if (obj.access_token) {
    var token = obj.access_token;
    var ocrHost = "https://aip.baidubce.com/rest/2.0/ocr/v1/general_basic?access_token=" + token;
    var request = clr.System.Net.WebRequest.Create(ocrHost);
    request.Method = "post";
    var encoding = clr.System.Text.Encoding.Default;
    var paraString = "image=" + clr.System.Net.WebUtility.UrlEncode(base64Image);
    var buffer =  encoding.GetBytes(paraString);
    request.ContentLength = buffer.Length;
    request.GetRequestStream().Write(buffer, 0, buffer.Length);

    var response = request.GetResponse();
    var reader = new clr.System.IO.StreamReader(response.GetResponseStream(), clr.System.Text.Encoding.UTF8);
    var result = reader.ReadToEnd();

    var json = JSON.parse(result);
    var jsonArray = json.words_result;
    if (jsonArray) {
        var OCRText = "";
        for(var i=0; i<jsonArray.length; i++) {
            OCRText += jsonArray[i].words
        }
        if (OCRText.length) {
            clip.SetText(OCRText);
            clr.System.Media.SystemSounds.Asterisk.Play();
        }
    }
    else {
        clip.SetText(result);
    }
    
    response.Dispose();
    reader.Dispose();
}

    //单独显示设置颜色关闭 ×变回原内容颜色会变 不单独显示接着显示太长
    /*var info = new DisplayTextInfo();
    //info.Title = 'Test';
    info.TitleAlignment = 'Center';
    info.Message = clip.GetText();
    info.MessageAlignment = 'Left';
    info.Duration = 2000;
    //弹出窗口的透明度,有效范围:0.05  -  1.0(1.0不透明)
    info.Opacity = 0.5;
    //位置也支持位置,使用此格式指定类型:'100,200'
    //类型:topleft,top,topright,right,bottomright,bottom,bottomleft,left
    info.Location = 'bottom'; 
    info.TitleFont = new Font('Segoe UI', 12, host.flags(FontStyle.Bold));
    info.MessageFont = new Font('Segoe UI Semibold', 12);
    //info.BackColor = '56,169,255';//'56,169,255'; //也支持 RGBinfo.ForeColor = 'white';
    info.BackColor = "105,105,105";             
    info.Padding = 10;//大小
    //如果为true,则始终显示在主屏幕上(除非Location是点类型),
    //否则会在手势开始的屏幕上显示
    info.UsePrimaryScreen = true; 
    sp.DisplayText(info);*/



统计手势次数

弹出列表显示

var popupMenuInfoEx = new PopupMenuInfoEx(sp.GetCurrentMousePoint());
var applications = sp_config.Gestures.Where(g => g.Active).OrderBy("MatchCount desc").ToArray();
for (var i = 0; i < applications.Length;i++) {
    var appActions = sp_config.Gestures.Where(x => x.Description == applications[i].Description).First().Actions;
  
popupMenuInfoEx.MenuItems.Add(new PopupMenuItem(applications[i].Description+' '+applications[i].MatchCount, applications[i].Script));

}
sp.ShowPopupMenuEx(popupMenuInfoEx);

统计脚本次数

var popupMenuInfoEx = new PopupMenuInfoEx(sp.GetCurrentMousePoint());
var applications = sp_config.Hotkeys.Where(g => g.Active).OrderBy("MatchCount desc").ToArray();
for (var i = 0; i < applications.Length;i++) {
    var appActions = sp_config.Hotkeys.Where(x => x.Description == applications[i].Description).First().Actions;
  
popupMenuInfoEx.MenuItems.Add(new PopupMenuItem(applications[i].Description+' '+applications[i].MatchCount, applications[i].Script));
}
sp.ShowPopupMenuEx(popupMenuInfoEx);

切换语言

//Get current culture
var culture = sp.GetCurrentCulture();

//Create input box to prompt selecting a language based on available files
var inputBoxInfo = new InputBoxInfo();
inputBoxInfo.Title = "Change Culture";
inputBoxInfo.Message = "Select an available language below. These are the languages available in the StrokesPlus.net\\Resources folder.";
var files = clr.System.IO.Directory.GetFiles(clr.System.IO.Path.GetDirectoryName(clr.System.Reflection.Assembly.GetEntryAssembly().Location) + "\\Resources");
for (i=0;i<files.Length;i++)
{
    var fi = new FileInfo(files[i]);
    var file = fi.Name;
    if(file.indexOf("Icons") !== 0) { //Ignore the Icons.resources file
        file = file.replace(/resources/ig , "").replace(/\./ig,"");
        if(file == "") file = "en-US"; //Since the culture name isn't in the English file name, add it manually
        inputBoxInfo.Items.Add(CultureInfo.GetCultureInfo(file).DisplayName + " [" + file + "]");
    }
}
inputBoxInfo.Sort = true;
//Show the input box
var res = sp.InputBox(inputBoxInfo);

//If a selection was made, change the culture
if(res != null) {
    var n = /\[(.*)\]/i; //Define the regular expression for matching the culture string
    var match = n.exec(res); //Get the text between the brackets, e.g. [en-US]
    sp.ChangeCulture(match[1]);
}

监控设备接入

0.5.5.7之前版本,新版本未测试

查看全部设备名称和ID

var devices = sp.AllDevices();
var deviceList = "";
for(var i = 0; i < devices.Count; i++)
{
    deviceList += `DeviceID: ${devices[i].DeviceID}
    Name: ${devices[i].Name}
    Description: ${devices[i].Description}
    Status: ${devices[i].Status}
`;
}
// Copy list to clipboard
clip.SetText(deviceList);

// Example to look for a specific device
if(devices.Where(d => d.Name == "Rob's Galaxy Note10").Count() > 0) {
    sp.MessageBox("Phone connected!", "Galaxy Phone via Bluetooth");
}

添加到 全局动作-硬件事件

//设置5000ms检查一次
sp.CreateTimer("DeviceWatch", 
               0, 
               5000, 
                `var devices = sp.AllDevices();
                //if(devices.Where(d => d.Name == "USB 输入设备").Count() > 0) {
                if(devices.Where(d => d.DeviceID == "HID\\VID_17EF&PID_6093\\6&18889FB2&0&0000").Count() > 0 && !sp.GetStoredBool("USBMouseDevice")) {
                    sp.MessageBox('Title', '设备连接');
                //}  else if(devices.Where(d => d.Name == "USB 输入设备").Count() === 0) {
                } else if(devices.Where(d => d.DeviceID == "HID\\\\VID_17EF&PID_6093\\\\6&38CD7B48&0&0000").Count() === 0) {
                    sp.MessageBox('Title', '设备断开连接');                    
                }
               `
);

@12style 用了33#的屏幕边缘滚动调节亮度、声音、浏览器标签页切换、程序切换代码
启动报错(不是一定会报错,有时正常,不清楚复现规律)

[ScriptEngine.Execute() - Exception] 源数组长度不足。请检查 srcIndex 和长度以及数组的下限。

后果:快捷失效,然后鼠标滚轮也失效
禁用滚轮中键代码后滚轮恢复正常

主程序:strokesplus.net 0.5.7.4 zip版

执行滚动的时候会报错嘛

滚轮脚本里面完整代码发下

有个问题,比如在excel中,我定义了鼠标右划+滚轮上下滚动,来调节字体大小这个功能
但是我执行动作的时候,在滚轮滚动了以后右键松开了才会执行这个动作释放一次快捷键,如果我需要多次调整,就要重复的执行这样的动作,再划一次右键+滚轮
脚本是否可以实现在我没有松开右键,在滚轮多次滚动的时候就多次发送这个快捷键呢?

试试这个

放大K换成G

            if(sp.GetStoredBool("AltDown")) {

                sp.SendVKeyDown(vk.VK_F);
                sp.Sleep(50) ;
                sp.SendVKeyDown(vk.VK_K);
                sp.Sleep(50) ;
                sp.SendVKeyUp(vk.VK_K);
                sp.Sleep(50) ;
                sp.SendVKeyUp(vk.VK_F);
            } else {
            //First stroll, send Alt down
                sp.StoreBool("AltDown", true); 
                sp.SendAltDown();

                sp.Sleep(50) ;    
                sp.SendVKeyDown(vk.VK_H);
                sp.Sleep(50) ;

                sp.SendVKeyUp(vk.VK_H);
                sp.Sleep(50) ;
                sp.SendVKeyDown(vk.VK_F);
                sp.Sleep(50) ;
                sp.SendVKeyDown(vk.VK_K);
                sp.Sleep(50) ;
                sp.SendVKeyUp(vk.VK_K);
                sp.Sleep(50) ;
                sp.SendVKeyUp(vk.VK_F);

            }

            sp.CreateTimer("TimerAltDown", 800, 0, `sp.SendAltUp(); sp.DeleteTimer("TimerAltDown");`);
            sp.DeleteStoredBool("AltDown");

方法2,不管是不是在输入,都直接会关闭,像是完全不检测键盘是不是在输入,倒计时结束直接就关了。

平台:windows11 ,搜狗五笔。

方法1,不会关闭。且,大家打开,显示却是OFF

Alt+左键拖动窗口
这个功能是否可以改成右键+左键拖动窗口呢,我直接改代码实现不了
目前是使用右键手势功能

右键手势是如何实现的呢

试下右键手势设置摇杆手势,按下左键修饰键,在手势之后


我的意思是目前我的右键是软件的手势键,如果想实现右键+左键拖动窗口的功能,把Alt+左键拖动窗口的代码中Alt键改成右键,好像实现不了,嘿嘿
另外
现在的软件中忽略键是Ctrl、Alt、Shift、Win几个功能键,能不能用中键实现忽略键的功能,就是我按下中键以后,就不会激活右键的手势功能呢?

摇滚手势 右键按下按左键 不能实现拖动吗

大佬,什么时候方便能更新下这个配置文件吗?我用0.5.7.4导入后直接无限“脚本载入出错”弹窗,没法用了。

我之前也这样,后来单独挑选想要的导入算了

不知道是不是我方法不对,我下了这里面的案例也不能用

暂时不要用这个配置了
或者在0.5.5.8上试试
我没精力也没办法测试更新这个配置