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

[转载代码] 办公软件WPS的JSA中列举窗口信息

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

  1. function 寻根开枝叶测试(){        //找到根再顺枝到叶
  2.         let 窗口句柄=鼠标所指窗口句柄();
  3.         console.clear();
  4.         while(窗口句柄){        //收藏
  5.                 var 句柄=窗口句柄;
  6.                 let 窗口信息=获取窗口信息(窗口句柄);
  7.                 窗口信息显示(窗口信息,"","窗口");
  8.                 窗口句柄=父窗口(窗口句柄);
  9.         }
  10.         const 根句柄=句柄,根序=1;
  11.         console.log("\t["+根序+"]根句柄:"+根句柄);
  12.         //生长
  13.         let 枝句柄=根句柄;
  14.         子弟窗口(枝句柄,0,根序,0);
  15. }
  16. function 父窗口(窗口句柄){        //返回父窗口句柄
  17.         const 执行宏调用=ExecuteExcel4Macro;
  18.         父句柄=执行宏调用(`CALL("User32","GetParent","JJ",${窗口句柄})`);
  19.         return 父句柄;
  20. }
  21. function 子弟窗口(父句柄,兄句柄,父祖序,兄弟序){        //显示窗口信息树
  22.         let 子句柄=下个子窗口(父句柄,兄句柄);
  23.         while(子句柄){
  24.                 兄弟序++;let 传承=父祖序+'.'+兄弟序;
  25.                 let 子窗口信息=获取窗口信息(子句柄);
  26.                 窗口信息显示(子窗口信息,"["+传承+"]","");
  27.                 子弟窗口(子句柄,0,传承,0);        //---回溯---//
  28.                 子句柄=下个子窗口(父句柄,子句柄);
  29.         }
  30. }
  31. function 下个子窗口(父句柄,兄句柄){return 下一个子窗口(父句柄,兄句柄,0,0);}
  32. function 下一个子窗口(父句柄,上个子句柄,标题,类){
  33.         const 执行宏调用=ExecuteExcel4Macro;
  34.         var 子句柄;
  35.         if(!标题){        //标题为0               
  36.                 if(!类){        //类为0
  37.                         子句柄=执行宏调用(`CALL("User32","FindWindowExA","JJJJJ",${父句柄},${上个子句柄},0,0)`);
  38.                 }else{
  39.                         子句柄=执行宏调用(`CALL("User32","FindWindowExA","JJJFJ",${父句柄},${上个子句柄},"${类}",0)`);
  40.                 }
  41.         }else{
  42.                 if(!类){        //类为0
  43.                         子句柄=执行宏调用(`CALL("User32","FindWindowExA","JJJJF",${父句柄},${上个子句柄},0,"${标题}")`);
  44.                 }else{
  45.                         子句柄=执行宏调用(`CALL("User32","FindWindowExA","JJJFF",${父句柄},${上个子句柄},"${类}","${标题}")`);
  46.                 }
  47.         }
  48.         return 子句柄;
  49. }
  50. function 鼠标所指窗口句柄(){        //返回窗口句柄
  51.         const 执行宏调用=ExecuteExcel4Macro;
  52.         let 鼠标指针坐标=获取鼠标位置();        //===调用函数===/
  53.         let 水平=鼠标指针坐标[0],垂直=鼠标指针坐标[1];        //鼠标指针处窗口句柄        //扩展了一个参数
  54.         let 窗口句柄=执行宏调用(`CALL("User32", "WindowFromPoint", "JJJ", ${水平},${垂直})`);
  55.         return 窗口句柄;
  56. }
  57. function 获取鼠标位置(){        //返回坐标数组[x,y]
  58.         const 执行宏调用=ExecuteExcel4Macro;
  59.         var 坐标结构=执行宏调用(`CALL("User32","GetCursorPos","1E",0)`);        //参数:4+4字节坐标结构
  60.         const 缓冲区=new ArrayBuffer(8); //8字节对应64位
  61.         const 数据操作=new DataView(缓冲区);        //操作对象
  62.         数据操作.setFloat64(0,坐标结构);        //(操作)写入64位数
  63.         let 坐标=[];
  64.         坐标[0]=数据操作.getInt32(4);        //取32位坐标x
  65.         坐标[1]=数据操作.getInt32(0);        //取32位坐标y
  66.         return 坐标;
  67. }
  68. function 获取窗口信息(窗口句柄){        //返回数组[句柄,标题,类,坐标]
  69.         let 窗口标题=获取窗口标题(窗口句柄);
  70.         let 窗口类名=获取窗口类名(窗口句柄);
  71.         let 窗口坐标=获取窗口坐标(窗口句柄);
  72.         return [窗口句柄,窗口标题,窗口类名,窗口坐标];
  73. }
  74. function 窗口信息显示(窗口信息,目录,说明){        //句柄、标题、类、坐标
  75.         let 窗口句柄=窗口信息[0],窗口标题=窗口信息[1];
  76.         let 窗口类名=窗口信息[2],窗口坐标=窗口信息[3];
  77.         console.log(目录+说明+"句柄:"+窗口句柄+"\t"+说明+"标题:"+窗口标题+"\t"+说明+"类名:"+窗口类名+"\t"+说明+"坐标:"+窗口坐标);
  78. }
  79. function 获取窗口标题(窗口句柄){
  80.         const 执行宏调用=ExecuteExcel4Macro;
  81.         let 窗口标题长度=执行宏调用(`CALL("User32", "GetWindowTextLengthA", "JJ", ${窗口句柄})`);
  82.         let 缓冲区大小=窗口标题长度+1,窗口标题="";
  83.         const 内存地址 = 执行宏调用(`CALL("Kernel32", "VirtualAlloc", "JJJJJ", 0, ${缓冲区大小}, ${0x3000}, 4)`);        //申请内存
  84.         let 标题长度=执行宏调用(`CALL("User32", "GetWindowTextA", "JJJJ", ${窗口句柄},${内存地址},${窗口标题长度+1})`);
  85.         if(标题长度){窗口标题=内存读取字符串(内存地址);}
  86.         执行宏调用(`CALL("Kernel32", "VirtualFree", "JJJJ", ${内存地址}, 0, ${0x8000})`);        //释放内存
  87.         return 窗口标题;
  88. }
  89. function 获取窗口类名(窗口句柄){
  90.         const 执行宏调用=ExecuteExcel4Macro;
  91.         let 缓冲区大小=256,类名="";        //类名最长255
  92.         const 内存地址=执行宏调用(`CALL("Kernel32","VirtualAlloc","JJJJJ",0,${缓冲区大小},${0x3000},4)`);        //申请内存
  93.         let 类名长度=执行宏调用(`CALL("User32","GetClassNameA","JJJJ",${窗口句柄},${内存地址},${缓冲区大小})`);
  94.         if(类名长度){窗口类名=内存读取字符串(内存地址);}
  95.         执行宏调用(`CALL("Kernel32","VirtualFree","JJJJ",${内存地址},0,${0x8000})`);        //释放内存
  96.         return 窗口类名;
  97. }
  98. function 获取窗口坐标(窗口句柄){        //返回坐标数组:左上右下
  99.         const 执行宏调用=ExecuteExcel4Macro;
  100.         let 内存地址=申请虚拟内存(16);
  101.         let 结果=执行宏调用(`CALL("User32","GetWindowRect","JJJ",${窗口句柄},${内存地址})`);
  102.         let 数组缓冲=内存读取数据(内存地址,16);
  103.         释放虚拟内存(内存地址);
  104.         let 坐标数组=缓冲转数组(数组缓冲);
  105.         return 坐标数组;
  106. }
  107. function 内存读取字符串(内存地址){        //返回字符串
  108.         const 执行宏调用=ExecuteExcel4Macro,段长度=127;
  109.         const 总字节=执行宏调用(`CALL("Kernel32","lstrlenA","JJ",${内存地址})`);        //内存文本字节数
  110.         let 偏移字节=0,文本字符串=分段文本='';
  111.         while(偏移字节<总字节){        //返回字符串F。        //返回超255字节时,也需要分段操作
  112.                 分段文本=执行宏调用(`CALL("Kernel32","lstrcpynW","FFJJ","",${内存地址+偏移字节},${段长度})`);
  113.                 偏移字节+=分段文本.replace(/[^\x00-\xff]/g,'xx').length;        //计算字符串字节数
  114.                 文本字符串+=分段文本;
  115.         }
  116.         return 文本字符串;
  117. }
  118. function 内存读取数据(内存地址,字节数){        //返回数组缓冲
  119.         const 执行宏调用=ExecuteExcel4Macro;
  120.         let 偏移,i,读取字节=[],读出数据;
  121.         for(偏移=i=0;偏移<字节数;i++){
  122.                 if(字节数-偏移>=4){读取字节[i]=4;偏移+=4;}
  123.                 else{if(字节数-偏移>=2){读取字节[i]=2;偏移+=2;}
  124.                 else{if(字节数-偏移==1){读取字节[i]=1;偏移++;}}}
  125.         }
  126.         const 数组缓冲=new ArrayBuffer(字节数);        //用于存储读出的数据
  127.         const 数据操作=new DataView(数组缓冲);
  128.         for(偏移=i=0;偏移<字节数;i++){        //库Kernel32.dll和NtDll.dll里都有RtlMoveMemory        //读出
  129.                 读出数据=执行宏调用(`CALL("Kernel32","RtlMoveMemory","1NJJ",${内存地址},${内存地址+偏移},${读取字节[i]})`);
  130.                 if(读取字节[i]==4){数据操作.setInt32(偏移,读出数据,true);偏移+=4;}
  131.                 else{if(读取字节[i]==2){数据操作.setInt16(偏移,读出数据,true);偏移+=2;}
  132.                 else{if(读取字节[i]==1){数据操作.setInt8(偏移,读出数据,true);偏移++;}}}
  133.         }
  134.         return 数组缓冲;        //返回
  135. }
  136. function 缓冲转数组(数组缓冲){        //返回数组[]
  137.         let 总字节=数组缓冲.byteLength;
  138.         let 组数=Math.ceil(总字节/4);
  139.         const 数据操作=new DataView(数组缓冲);
  140.         let 数组=[];
  141.         for(let i=0;i<组数;i++){
  142.                 数组[i]=数据操作.getInt32(i*4,true);
  143.         }
  144.         return 数组;
  145. }
  146. function 申请虚拟内存(字节数){        //返回内存地址
  147.         const 执行宏调用=ExecuteExcel4Macro;
  148.         const 内存地址=执行宏调用(`CALL("Kernel32","VirtualAlloc","JJJJJ",0,${字节数},${0x3000},4)`);
  149.         return 内存地址;
  150. }
  151. function 释放虚拟内存(内存地址){
  152.         const 执行宏调用=ExecuteExcel4Macro;
  153.         执行宏调用(`CALL("Kernel32","VirtualFree","JJJJ",${内存地址},0,${0x8000})`);
  154. }
复制代码


试想脱离表格文件.xls/.xlsx,只加载对象Excel.Application。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2026-5-7 19:03

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

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