|
|
办公软件WPS的表格:通过ExecuteExcel4Macro调用WinAPI实现
函数:
- function 操作鼠标(操作数组){
- let 操作组数=操作数组.length;
- let 结构字节数=对象字节数(操作数组[0]); /*****计算结构对象字节数*****/
- let 总字节=结构字节数*操作组数;
- const 数组缓冲=new ArrayBuffer(总字节);
- for(let i=0;i<操作组数;i++){
- 结构对象填入数组缓冲(数组缓冲,i*结构字节数,操作数组[i]); /*****对象转数组缓冲*****/
- }
- const 执行宏调用=ExecuteExcel4Macro; //申请内存
- const 内存地址=执行宏调用(`CALL("Kernel32","VirtualAlloc","JJJJJ",0,${总字节},${0x3000},4)`);
- 数据写入内存(内存地址,数组缓冲,总字节); /*****写入鼠标操作结构*****/ //执行鼠标操作
- 鼠标操作结果=执行宏调用(`CALL("User32","SendInput","JJJJ",${操作组数},${内存地址},${结构字节数})`);
- if(!鼠标操作结果){console.log("错误代码:"+执行宏调用(`CALL("Kernel32","GetLastError","I")`));}
- 执行宏调用(`CALL("Kernel32", "VirtualFree", "JJJJ", ${内存地址}, 0, ${0x8000})`); //释放内存
- }
复制代码
测试函数:
- function 鼠标单击测试(){
- let 左键按下=鼠标操作对象(2),左键松开=鼠标操作对象(4); /*****生成单个对象*****/
- let 点击=鼠标操作对象(2|4),右击=鼠标操作对象(8|0x10);
- alert("移动鼠标指针到将要点击的位置,按【空格】或【回车】记下坐标。");
- var 鼠标指针坐标=获取鼠标位置(); /*****获取鼠标指针坐标*****/
- var 水平=鼠标指针坐标[0],垂直=鼠标指针坐标[1];
- alert("将点击的鼠标位置:("+水平+","+垂直+"),确定则进行点击操作。");
- 设置鼠标位置(水平,垂直); /*****移动鼠标指针*****/
- let 单击=[点击];
- 操作鼠标(单击); /*****鼠标单击操作*****/
- }
- function 鼠标双击测试(){
- alert("移动鼠标指针到将要双击的位置,按【空格】或【回车】记下坐标。");
- var 鼠标指针坐标=获取鼠标位置(); /*****获取鼠标指针坐标*****/
- var 水平=鼠标指针坐标[0],垂直=鼠标指针坐标[1];
- alert("将双击的鼠标位置:("+水平+","+垂直+"),确定则进行双击操作。");
- 设置鼠标位置(水平,垂直); /*****移动鼠标指针*****/
-
- let 点击=鼠标操作对象(2|4);
- let 双击=[点击,点击];
- 操作鼠标(双击); /*****鼠标双击操作*****/
- }
- function 鼠标右键测试(){
- let 右击=鼠标操作对象(8|0x10);
- 操作鼠标([右击]); /*****鼠标右击操作*****/
- }
- function 鼠标拖拽测试(){
- console.clear();console.log("移动鼠标指针到将要拖拽的位置(如标题栏),再按F5执行函数。");
- let 左键按下=鼠标操作对象(2),左键松开=鼠标操作对象(4);
- //let 移动鼠标=鼠标移动对象(50,-20,1); //相对右移上移 //测试无效
- //let 拖拽=[左键按下,移动鼠标,左键松开]; //测试无效
- 操作鼠标([左键按下]); /*****鼠标操作*****/
- var 鼠标指针坐标=获取鼠标位置(); /*****获取鼠标指针坐标*****/
- var 水平=鼠标指针坐标[0],垂直=鼠标指针坐标[1];
- 设置鼠标位置(水平+50,垂直-20); /*****移动鼠标指针*****/
- 操作鼠标([左键松开]); /*****鼠标操作*****/
- }
复制代码
调用函数:
- function 数据写入内存(内存地址,数组缓冲,字节数){
- const 数据操作=new DataView(数组缓冲);
- let 偏移=i=0,待写数据=[],写入字节=[];
- while(字节数>偏移){
- if(字节数-偏移>=4){待写数据[i]=数据操作.getInt32(偏移,true);写入字节[i]=4;i++;偏移+=4;}
- else{if(字节数-偏移>=2){待写数据[i]=数据操作.getInt16(偏移,true);写入字节[i]=2;i++;偏移+=2;}
- else{if(字节数-偏移==1){待写数据[i]=数据操作.getInt8(偏移,true);写入字节[i]=1;i++;偏移++;}}}
- }
- const 执行宏调用=ExecuteExcel4Macro;
- for(偏移=i=0;i<写入字节.length;i++){ //写入
- 执行宏调用(`CALL("Kernel32","RtlMoveMemory","2JNJ",${内存地址+偏移},${待写数据[i]},${写入字节[i]})`);
- 偏移+=写入字节[i];
- }
- }
- function 设置鼠标位置(水平,垂直){
- const 执行宏调用=ExecuteExcel4Macro;
- var 结果=执行宏调用(`CALL("User32","SetCursorPos","AJJ",${水平},${垂直})`);
- return 结果; //成功返回true
- }
- function 获取鼠标位置(){ //返回坐标数组[x,y]
- const 执行宏调用=ExecuteExcel4Macro;
- //逻辑值 GetCursorPos([输出]结构 屏幕坐标指针)
- var 坐标结构=执行宏调用(`CALL("User32","GetCursorPos","1E",0)`); //参数:4+4字节坐标结构
- const 缓冲区=new ArrayBuffer(8); //8字节对应64位
- const 数据操作=new DataView(缓冲区); //操作对象
- 数据操作.setFloat64(0,坐标结构); //(操作)写入64位数
- let 坐标=[];
- 坐标[0]=数据操作.getInt32(4); //取32位坐标x
- 坐标[1]=数据操作.getInt32(0); //取32位坐标y
- return 坐标;
- }
- function 鼠标操作对象(操作){
- class 鼠标操作 { //类
- constructor(动作){ //类的构造方法,用于构造属性
- this.输入类型1 = [4,0], //鼠标0 //字节数,数据
- this.水平坐标2 = [4,0], //相对坐标,即移动量
- this.垂直坐标3 = [4,0],
- this.滚轮转量4 = [4,0],
- this.输入操作5 = [4,动作], //右键按下8 绝对坐标0x8000
- this.时间戳值6 = [4,0], //系统确定
- this.扩展数据7 = [4,0]
- }
- };
- let 鼠标对象 = new 鼠标操作(操作);
- return 鼠标对象;
- }
- function 对象字节数(结构对象){
- let 对象数据字节数=0;
- for (let 属性名 in 结构对象) {
- if (结构对象.hasOwnProperty(属性名)) {
- 对象数据字节数+=结构对象[属性名][0]; //累加字节数
- }
- }
- return 对象数据字节数;
- }
- function 结构对象填入数组缓冲(数组缓冲,偏移,结构对象){
- const 数据操作=new DataView(数组缓冲);
- let 字节数,待填数据;
- for (let 属性名 in 结构对象) {
- if (结构对象.hasOwnProperty(属性名)) {
- 字节数=结构对象[属性名][0],待填数据=结构对象[属性名][1];
- if(字节数==4){数据操作.setInt32(偏移,待填数据,true);} //小端序
- else{if(字节数==2){数据操作.setInt32(偏移,待填数据,true);}
- else{if(字节数==1){数据操作.setInt32(偏移,待填数据,true);}}}
- 偏移+=字节数;
- }
- }
- }
复制代码
主要是为了验证JSA中调用WinAPI时 输出型结构参数 是否可获取,输入型结构参数 是否也可以通过内存来引用! |
|