找回密码
 注册
搜索
[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
查看: 54|回复: 1

[转载代码] 办公软件WPS的JSA中模拟鼠标点击

[复制链接]
发表于 7 小时前 | 显示全部楼层 |阅读模式
办公软件WPS的表格:通过ExecuteExcel4Macro调用WinAPI实现

函数:
  1. function 操作鼠标(操作数组){
  2.         let 操作组数=操作数组.length;
  3.         let 结构字节数=对象字节数(操作数组[0]);        /*****计算结构对象字节数*****/
  4.         let 总字节=结构字节数*操作组数;
  5.         const 数组缓冲=new ArrayBuffer(总字节);
  6.         for(let i=0;i<操作组数;i++){
  7.                 结构对象填入数组缓冲(数组缓冲,i*结构字节数,操作数组[i]);        /*****对象转数组缓冲*****/
  8.         }
  9.         const 执行宏调用=ExecuteExcel4Macro;        //申请内存
  10.         const 内存地址=执行宏调用(`CALL("Kernel32","VirtualAlloc","JJJJJ",0,${总字节},${0x3000},4)`);
  11.         数据写入内存(内存地址,数组缓冲,总字节);        /*****写入鼠标操作结构*****/        //执行鼠标操作
  12.         鼠标操作结果=执行宏调用(`CALL("User32","SendInput","JJJJ",${操作组数},${内存地址},${结构字节数})`);
  13.         if(!鼠标操作结果){console.log("错误代码:"+执行宏调用(`CALL("Kernel32","GetLastError","I")`));}
  14.         执行宏调用(`CALL("Kernel32", "VirtualFree", "JJJJ", ${内存地址}, 0, ${0x8000})`);        //释放内存
  15. }
复制代码


测试函数:

  1. function 鼠标单击测试(){
  2.         let 左键按下=鼠标操作对象(2),左键松开=鼠标操作对象(4);        /*****生成单个对象*****/
  3.         let 点击=鼠标操作对象(2|4),右击=鼠标操作对象(8|0x10);

  4.         alert("移动鼠标指针到将要点击的位置,按【空格】或【回车】记下坐标。");
  5.         var 鼠标指针坐标=获取鼠标位置();        /*****获取鼠标指针坐标*****/
  6.         var 水平=鼠标指针坐标[0],垂直=鼠标指针坐标[1];
  7.         alert("将点击的鼠标位置:("+水平+","+垂直+"),确定则进行点击操作。");
  8.         设置鼠标位置(水平,垂直);        /*****移动鼠标指针*****/
  9.         let 单击=[点击];
  10.         操作鼠标(单击);        /*****鼠标单击操作*****/
  11. }
  12. function 鼠标双击测试(){
  13.         alert("移动鼠标指针到将要双击的位置,按【空格】或【回车】记下坐标。");
  14.         var 鼠标指针坐标=获取鼠标位置();        /*****获取鼠标指针坐标*****/
  15.         var 水平=鼠标指针坐标[0],垂直=鼠标指针坐标[1];
  16.         alert("将双击的鼠标位置:("+水平+","+垂直+"),确定则进行双击操作。");
  17.         设置鼠标位置(水平,垂直);        /*****移动鼠标指针*****/
  18.        
  19.         let 点击=鼠标操作对象(2|4);
  20.         let 双击=[点击,点击];
  21.         操作鼠标(双击);        /*****鼠标双击操作*****/
  22. }
  23. function 鼠标右键测试(){
  24.         let 右击=鼠标操作对象(8|0x10);
  25.         操作鼠标([右击]);        /*****鼠标右击操作*****/
  26. }
  27. function 鼠标拖拽测试(){
  28.         console.clear();console.log("移动鼠标指针到将要拖拽的位置(如标题栏),再按F5执行函数。");
  29.         let 左键按下=鼠标操作对象(2),左键松开=鼠标操作对象(4);
  30.         //let 移动鼠标=鼠标移动对象(50,-20,1);        //相对右移上移        //测试无效
  31.         //let 拖拽=[左键按下,移动鼠标,左键松开];        //测试无效
  32.         操作鼠标([左键按下]);        /*****鼠标操作*****/
  33.         var 鼠标指针坐标=获取鼠标位置();        /*****获取鼠标指针坐标*****/
  34.         var 水平=鼠标指针坐标[0],垂直=鼠标指针坐标[1];
  35.         设置鼠标位置(水平+50,垂直-20);        /*****移动鼠标指针*****/
  36.         操作鼠标([左键松开]);        /*****鼠标操作*****/
  37. }
复制代码


调用函数:

  1. function 数据写入内存(内存地址,数组缓冲,字节数){
  2.         const 数据操作=new DataView(数组缓冲);
  3.         let 偏移=i=0,待写数据=[],写入字节=[];
  4.         while(字节数>偏移){
  5.                 if(字节数-偏移>=4){待写数据[i]=数据操作.getInt32(偏移,true);写入字节[i]=4;i++;偏移+=4;}
  6.                 else{if(字节数-偏移>=2){待写数据[i]=数据操作.getInt16(偏移,true);写入字节[i]=2;i++;偏移+=2;}
  7.                 else{if(字节数-偏移==1){待写数据[i]=数据操作.getInt8(偏移,true);写入字节[i]=1;i++;偏移++;}}}
  8.         }
  9.         const 执行宏调用=ExecuteExcel4Macro;
  10.         for(偏移=i=0;i<写入字节.length;i++){        //写入
  11.                 执行宏调用(`CALL("Kernel32","RtlMoveMemory","2JNJ",${内存地址+偏移},${待写数据[i]},${写入字节[i]})`);
  12.                 偏移+=写入字节[i];
  13.         }
  14. }
  15. function 设置鼠标位置(水平,垂直){
  16.         const 执行宏调用=ExecuteExcel4Macro;
  17.         var 结果=执行宏调用(`CALL("User32","SetCursorPos","AJJ",${水平},${垂直})`);
  18.         return 结果;        //成功返回true
  19. }
  20. function 获取鼠标位置(){        //返回坐标数组[x,y]
  21.         const 执行宏调用=ExecuteExcel4Macro;
  22.         //逻辑值 GetCursorPos([输出]结构 屏幕坐标指针)
  23.         var 坐标结构=执行宏调用(`CALL("User32","GetCursorPos","1E",0)`);        //参数:4+4字节坐标结构
  24.         const 缓冲区=new ArrayBuffer(8); //8字节对应64位
  25.         const 数据操作=new DataView(缓冲区);        //操作对象
  26.         数据操作.setFloat64(0,坐标结构);        //(操作)写入64位数
  27.         let 坐标=[];
  28.         坐标[0]=数据操作.getInt32(4);        //取32位坐标x
  29.         坐标[1]=数据操作.getInt32(0);        //取32位坐标y
  30.         return 坐标;
  31. }
  32. function 鼠标操作对象(操作){
  33.         class 鼠标操作 {        //类
  34.                 constructor(动作){        //类的构造方法,用于构造属性
  35.                         this.输入类型1 = [4,0],        //鼠标0        //字节数,数据
  36.                         this.水平坐标2 = [4,0],        //相对坐标,即移动量
  37.                         this.垂直坐标3 = [4,0],
  38.                         this.滚轮转量4 = [4,0],
  39.                         this.输入操作5 = [4,动作],        //右键按下8        绝对坐标0x8000
  40.                         this.时间戳值6 = [4,0],        //系统确定
  41.                         this.扩展数据7 = [4,0]
  42.                 }
  43.         };
  44.         let 鼠标对象 = new 鼠标操作(操作);
  45.         return 鼠标对象;
  46. }
  47. function 对象字节数(结构对象){
  48.         let 对象数据字节数=0;
  49.         for (let 属性名 in 结构对象) {
  50.                 if (结构对象.hasOwnProperty(属性名)) {
  51.                         对象数据字节数+=结构对象[属性名][0];        //累加字节数
  52.                 }
  53.         }
  54.         return 对象数据字节数;
  55. }
  56. function 结构对象填入数组缓冲(数组缓冲,偏移,结构对象){
  57.         const 数据操作=new DataView(数组缓冲);
  58.         let 字节数,待填数据;
  59.         for (let 属性名 in 结构对象) {
  60.                 if (结构对象.hasOwnProperty(属性名)) {
  61.                         字节数=结构对象[属性名][0],待填数据=结构对象[属性名][1];
  62.                         if(字节数==4){数据操作.setInt32(偏移,待填数据,true);}        //小端序
  63.                         else{if(字节数==2){数据操作.setInt32(偏移,待填数据,true);}
  64.                         else{if(字节数==1){数据操作.setInt32(偏移,待填数据,true);}}}
  65.                         偏移+=字节数;
  66.                 }
  67.         }
  68. }
复制代码

主要是为了验证JSA中调用WinAPI时 输出型结构参数 是否可获取,输入型结构参数 是否也可以通过内存来引用
 楼主| 发表于 7 小时前 | 显示全部楼层
另一种方式:
  1. function 鼠标事件单击测试(){
  2.         const 执行宏调用=ExecuteExcel4Macro;
  3.         执行宏调用(`CALL("User32","mouse_event","JJJJJJ",${2|4},0,0,0,0)`);        //左键单击
  4. }
  5. function 鼠标事件双击测试(){
  6.         const 执行宏调用=ExecuteExcel4Macro;
  7.         执行宏调用(`CALL("User32","mouse_event","JJJJJJ",${2|4},0,0,0,0)`);        //左键双击
  8.         执行宏调用(`CALL("User32","mouse_event","JJJJJJ",${6},0,0,0,0)`);
  9. }
  10. function 鼠标事件右击测试(){
  11.         const 执行宏调用=ExecuteExcel4Macro;
  12.         执行宏调用(`CALL("User32","mouse_event","JJJJJJ",${8|0x10},0,0,0,0)`);        //右键
  13. }
复制代码


鼠标左键右键常量:
MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_LEFTUP   = 0x2|0x4
MOUSEEVENTF_RIGHTDOWN | MOUSEEVENTF_RIGHTUP = 0x8|0x10
您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|手机版|小黑屋|批处理之家 ( 渝ICP备10000708号 )

GMT+8, 2026-4-22 20:00

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表