|
|
办公软件WPS的表格:通过ExecuteExcel4Macro调用WinAPI实现
列举记事本所有菜单文本:(请先打开一个记事本!)
- function 显示窗口所有菜单测试(){ //记事本窗口
- console.clear();
- let 记事本句柄=查找窗口(0,"Notepad"); //按记事本类查找
- if(!记事本句柄){alert("未找到记事本!退出");return;}
- 显示菜单(记事本句柄);
- }
复制代码
打开记事本的字体对话框,相单于点击了菜单“格式》字体”:
- function 查找窗口菜单并操作测试(){ //找一个记事本窗口,(模拟菜单)打开字体对话框
- console.clear();
- let 记事本句柄=查找窗口(0,"Notepad"); //按记事本类查找
- if(!记事本句柄){alert("未找到记事本!退出");return;}
-
- let 菜单组=查找菜单(记事本句柄,"字体");
- console.log("菜单组:"+菜单组);
- if(菜单组.length==1){
- console.log("只找到一个:"+菜单组[0]);
- let 执行命令=0x111;
- 投送带参消息(记事本句柄,执行命令,菜单组[0][1],0); //相当于点击字体菜单项,打开字体对话框
- }
- }
复制代码
用到的函数:
- function 发送带参消息(窗口句柄,消息,短参,长参){ //短参16位,长参32位
- const 执行宏调用=ExecuteExcel4Macro;
- 执行宏调用(`CALL("User32","SendMessageA","JJJJJ",${窗口句柄},${消息},${短参},${长参})`);
- }
- function 投送带参消息(窗口句柄,消息,短参,长参){ //短参16位,长参32位
- const 执行宏调用=ExecuteExcel4Macro;
- 执行宏调用(`CALL("User32","PostMessageA","JJJJJ",${窗口句柄},${消息},${短参},${长参})`);
- }
- function 查找窗口(标题,类){ //返回句柄
- const 执行宏调用=ExecuteExcel4Macro;
- var 窗口句柄;
- if(!标题){ //标题为0
- if(!类){ 窗口句柄=执行宏调用(`CALL("User32","FindWindowA","JJJ",0,0)`); //类为0
- }else{ 窗口句柄=执行宏调用(`CALL("User32","FindWindowA","JFJ","${类}",0)`);}
- }else{
- if(!类){ 窗口句柄=执行宏调用(`CALL("User32","FindWindowA","JJF",0,"${标题}")`); //类为0
- }else{ 窗口句柄=执行宏调用(`CALL("User32","FindWindowA","JFF","${类}","${标题}")`);}
- }
- return 窗口句柄;
- }
- function 显示菜单(窗口句柄){ //显示窗口主菜单文本
- let 菜单句柄=获取菜单(窗口句柄);
- let 菜单数=获取菜单数(菜单句柄);
- let 菜单标识=0x400;
- for(let i=0;i<菜单数;i++){ //菜单序号i
- let 菜单文本=获取菜单文本(菜单句柄,i,菜单标识);
- let 菜单号=获取菜单号(菜单句柄,i);
- if(菜单号==-1){
- console.log("菜单文本(+):"+菜单文本);
- 显示子菜单(菜单句柄,i);
- }else{console.log("菜单文本(-):"+菜单文本+"\t菜单号:"+菜单号);}
- }
- }
- function 显示子菜单(菜单句柄,菜单序号){ //显示子菜单文本(菜单号为0的一般为分隔线)
- let 子菜单句柄=获取子菜单(菜单句柄,菜单序号);
- let 子菜单数=获取菜单数(子菜单句柄);
- let 子菜单标识=0x400;
- for(let i=0;i<子菜单数;i++){ //子菜单序号i
- let 子菜单文本=获取菜单文本(子菜单句柄,i,子菜单标识);
- let 子菜单号=获取菜单号(子菜单句柄,i);
- if(子菜单号==-1){
- console.log("子菜单文本(+):"+子菜单文本);
- 显示子菜单(子菜单句柄,i); //分隔线的菜单号为0
- }else{console.log("子菜单文本(-):"+子菜单文本+"\t子菜单号:"+子菜单号);}
- }
- }
- function 查找菜单(窗口句柄,部分菜单文本){
- let 菜单句柄=获取菜单(窗口句柄);
- let 菜单数=获取菜单数(菜单句柄);
- let 菜单标识=0x400;var 菜单组=[];
- for(let i=0;i<菜单数;i++){ //菜单序号i
- let 菜单文本=获取菜单文本(菜单句柄,i,菜单标识);
- let 菜单号=获取菜单号(菜单句柄,i);
- if(菜单号==-1){
- 查找子菜单(菜单句柄,i,部分菜单文本,菜单组);
- }else{
- if(菜单文本.indexOf(部分菜单文本)!=-1){
- 菜单组.push([菜单文本,菜单号]);
- }
- }
- }
- return 菜单组;
- }
- function 查找子菜单(菜单句柄,菜单序号,查找内容,菜单组){
- let 子菜单句柄=获取子菜单(菜单句柄,菜单序号);
- let 子菜单数=获取菜单数(子菜单句柄);
- let 子菜单标识=0x400;
- for(let i=0;i<子菜单数;i++){ //子菜单序号i
- let 子菜单文本=获取菜单文本(子菜单句柄,i,子菜单标识);
- let 子菜单号=获取菜单号(子菜单句柄,i);
- if(子菜单号==-1){
- 查找子菜单(子菜单句柄,i,查找内容,菜单组); //分隔线的菜单号为0
- }else{
- if(子菜单文本.indexOf(查找内容)!=-1){
- 菜单组.push([子菜单文本,子菜单号]);
- }
- }
- }
- }
- function 获取菜单(窗口句柄){ //标准窗口的菜单对象句柄
- const 执行宏调用=ExecuteExcel4Macro;
- let 菜单句柄=执行宏调用(`CALL("User32","GetMenu","JJ",${窗口句柄})`);
- return 菜单句柄;
- }
- function 获取菜单数(菜单句柄){
- const 执行宏调用=ExecuteExcel4Macro;
- let 菜单数=执行宏调用(`CALL("User32","GetMenuItemCount","JJ",${菜单句柄})`);
- return 菜单数;
- }
- function 获取菜单号(菜单句柄,菜单序号){
- const 执行宏调用=ExecuteExcel4Macro;
- let 菜单号=执行宏调用(`CALL("User32","GetMenuItemID","JJJ",${菜单句柄},${菜单序号})`);
- return 菜单号; //返回-1表示有子菜单
- }
- function 获取子菜单(菜单句柄,菜单序号){
- const 执行宏调用=ExecuteExcel4Macro;
- let 子菜单句柄=执行宏调用(`CALL("User32","GetSubMenu","JJJ",${菜单句柄},${菜单序号})`);
- return 子菜单句柄;
- }
- function 获取菜单文本(菜单句柄,菜单序号,菜单标识){
- const 执行宏调用=ExecuteExcel4Macro;
- let 菜单文本长度=执行宏调用(`CALL("User32","GetMenuStringA","JJJFJJ",${菜单句柄},${菜单序号},"",0,${菜单标识})`);
- let 内存地址=申请虚拟内存(菜单文本长度+1);
- 执行宏调用(`CALL("User32","GetMenuStringA","JJJJJJ",${菜单句柄},${菜单序号},${内存地址},${菜单文本长度+1},${菜单标识})`);
- let 菜单文本=内存读取字符串(内存地址);
- 释放虚拟内存(内存地址);
- return 菜单文本;
- }
- function 申请虚拟内存(字节数){ //返回内存地址
- const 执行宏调用=ExecuteExcel4Macro;
- const 内存地址=执行宏调用(`CALL("Kernel32","VirtualAlloc","JJJJJ",0,${字节数},${0x3000},4)`);
- return 内存地址;
- }
- function 释放虚拟内存(内存地址){
- const 执行宏调用=ExecuteExcel4Macro;
- 执行宏调用(`CALL("Kernel32","VirtualFree","JJJJ",${内存地址},0,${0x8000})`);
- }
- function 内存读取字符串(内存地址){ //返回字符串
- const 执行宏调用=ExecuteExcel4Macro,段长度=127;
- const 总字节=执行宏调用(`CALL("Kernel32","lstrlenA","JJ",${内存地址})`); //内存文本字节数
- let 偏移字节=0,文本字符串=分段文本='';
- while(偏移字节<总字节){ //返回字符串F。 //返回超255字节时,也需要分段操作
- 分段文本=执行宏调用(`CALL("Kernel32","lstrcpynW","FFJJ","",${内存地址+偏移字节},${段长度})`);
- 偏移字节+=分段文本.replace(/[^\x00-\xff]/g,'xx').length; //计算字符串字节数
- 文本字符串+=分段文本;
- }
- return 文本字符串;
- }
复制代码
|
|