标题: [问题求助] vbs如实现无需激活指定窗口也能对该窗口模拟点击按键 [打印本页]
作者: zgh7878788 时间: 2012-12-8 21:03 标题: vbs如实现无需激活指定窗口也能对该窗口模拟点击按键
本帖最后由 pcl_test 于 2016-7-17 21:55 编辑
求一个用VBS写的脚本(纯VBS,网上只有按键精灵版的),后台往t.txt文本里写东西,比如,前台是这样的语句:
Set WshShell=CreateObject("WScript.Shell")
WshShell.AppActivate "t - 记事本"
crt.Screen.Send "it"
crt.sleep 100
crt.Screen.Send " "
crt.sleep 100
crt.Screen.Send "is"
crt.sleep 100
crt.Screen.Send " 9"
crt.sleep 100
crt.Screen.Send "{Enter}"
这个问题困扰我好久了,麻烦各位老师赐教,谢谢!非常感谢!
作者: czjt1234 时间: 2012-12-11 17:44
- Set objFSO = CreateObject("Scripting.FileSystemObject")
- Set objTextStream = objFSO.OpenTextFile("D:\test.txt", 8, True)
- '这里的8代表追加文件内容,要清空原有文件内容换成2
- objTextStream.WriteLine "111"
- objTextStream.WriteLine "222"
- objTextStream.Close
复制代码
作者: czjt1234 时间: 2012-12-11 18:20
Set objTextStream = objFSO.OpenTextFile("D:\test.txt",1|2|8,True|False,-2|-1|0)
'打开文件,返回 TextStream 对象
'可以读写文件内容,不能使用文件属性,不可以复制、移动、删除文件
'True表示文件不存在时自动新建文件,False为不新建(缺省值)
Const ForReading = 1 '只读(缺省值)
Const ForWriting = 2 '清空文件,覆盖写入
Const ForAppending = 8 '在文件末尾追加写入
Const TristateUseDefault = -2 '以系统默认格式打开文件
Const TristateTrue = -1 '以 Unicode 格式打开文件
Const TristateFalse = 0 '以 ASCII 格式打开文件(缺省值)
objTextStream.Skip(3)
'在读取数据时,跳过3个字符,光标位置移到3个字符之后
'每行末尾的回车换行算2个字符
'要求打开方式为只读
objTextStream.SkipLine
'在读取数据时,跳过一行,光标位置移到下一行行首
'要求打开方式为只读
strRead = objTextStream.Read(3)
'从光标位置读取3个字符,光标移到3个字符之后
'要求打开方式为只读
strRead = objTextStream.ReadLine
'从光标位置读取一行,光标移到下一行行首
'要求打开方式为只读
strRead = objTextStream.ReadAll
'从光标位置读取文件所有内容,光标移到文末
'要求打开方式为只读
blnYN = objTextStream.AtEndOfLine
'判断光标位置是否在某一行末尾,返回True|False
'要求打开方式为只读
blnYN = objTextStream.AtEndOfStream
'判断光标位置是否在文末,返回True|False
'要求打开方式为只读
objTextStream.Write "test"
'从光标位置插入字符串
objTextStream.WriteLine "test"
'从光标位置插入字符串,并回车换行
objTextStream.WriteBlankLines 5
'从光标位置插入5个空行
strRead = objTextStream.Line
'返回当前光标所在行号
strRead = objTextStream.Column
'返回当前光标所在列号
objTextStream.Close
'关闭文件对象,立刻保存到磁盘
作者: zgh7878788 时间: 2012-12-12 18:08
回复 2# czjt1234
老师,非常感谢!这个能实现向文件追加内容的目的。现在我想的是用SENDKEY的方式,只是那是前台,我想要后台的。我知道老师要问我有您写那种方式为啥还要后台的SENDKEY?可能我一时也解释不清,但我确实需要那种后台的SENDKEY的例子。不知道老师能不能帮帮忙?占用您宝贵时间,十分过意不去,只能万分感谢!谢谢!!!
作者: zgh7878788 时间: 2012-12-12 19:42
时间我不是用在记事本上,只是把记事本当例子,本是想用在其他软件上,起一个模拟按键操作的作用.谢谢各位老师了,拜托了!
作者: czjt1234 时间: 2012-12-13 09:53
本帖最后由 czjt1234 于 2012-12-13 10:01 编辑
后台发送按键,SendKeys不行
可以考虑调用api
vbs调用api,一个是用第三方软件dynwrap.dll
一个是用Excel,如果你装了Excel
还有你的后台不知道是什么意思
如果你可以在屏幕上看到该窗口,并且该窗口是活动窗口
那么也可以用SendKeys
objwsh.SendKeys strRead '向当前活动窗口发送按键
'下面是操作键的发送代码
退格键 {BACKSPACE}、{BS} 或 {BKSP}
BREAK {BREAK}
CAPS LOCK {CAPSLOCK}
DEL 或 DELETE {DELETE} 或 {DEL}
向下键 {DOWN}
END {END}
ENTER {ENTER} 或 ~
ESC {ESC}
HELP {HELP}
HOME {HOME}
INS 或 INSERT {INSERT} 或 {INS}
向左键 {LEFT}
NUM LOCK {NUMLOCK}
PAGE DOWN {PGDN}
PAGE UP {PGUP}
向右键 {RIGHT}
SCROLL LOCK {SCROLLLOCK}
TAB {TAB}
向上键 {UP}
F1 至 F12 {F1} 至 {F12}
SHIFT +
CTRL ^
ALT %
+ { 等修饰符 {+} {{} {^} {}} {%}
'如果在按 e 和 c 的同时按 SHIFT 键,则发送字符串参数 +(ec)
'可发送一个键的重复键击。如10次x,为{x 10},但不可发送10次组合键,如Ctrl+x
'不能发送 PRINT SCREEN 键 {PRTSC}
'常用 Wscript.Sleep 来延时若干毫秒发送按键,避免程序来不及响应
比如你的代码可以用vbs这么写
- Set objWsh = CreateObject("WScript.Shell")
- objWsh.AppActivate "t - 记事本"
- objwsh.SendKeys "it"
- Wsctipt.Sleep 100
- objwsh.SendKeys " "
- Wsctipt.Sleep 100
- objwsh.SendKeys "is"
- Wsctipt.Sleep 100
- objwsh.SendKeys " 9"
- Wsctipt.Sleep 100
- objwsh.SendKeys "{Enter}"
复制代码
作者: zgh7878788 时间: 2012-12-13 20:35
回复 6# czjt1234
非常感谢老师!我用的是一个模拟显示的程序,它是集显示和按键一体的,我想对这个程序模拟按键进行设置,比如,我按A3,这个模拟按键程序就进入相应菜单,我能看到这个按键过程,但是用SENDKEY是一个前台命令,必须保证电脑没人动,否则就不知道发送到哪去了,所以我就想把它转换成后台命令,这样,我只要开着模拟按键程序就可以用电脑做其他事情了。可我不会后台,网上找了好久,也没有老师帮我。确实太困惑了。网上找了个按键精灵版的后台向记事本发送,也不懂怎么移植到纯VBS上来。老师说的API,具体我的知识有限,所以我也不懂,恳请老师写个简单的实例,小可不剩感激!非常感谢!
作者: zgh7878788 时间: 2012-12-13 20:39
回复 6# czjt1234
主界面[attach]5965[/attach]我按31后变成[attach]5966[/attach]
作者: zgh7878788 时间: 2012-12-13 20:42
这个是按键精灵版的后台向记事本发送按键的例子
'获得符合标题为"t - 记事本"的窗口句柄
HwndEx = Plugin.Window.Find(0, "t - 记事本")
If HwndEx = 0 Then
MsgBox "没有找到符合的窗口,请检查标题是否正确"
End If
'获得记事本子窗口,类名为"Edit"
Hwnd = Plugin.Window.FindEx(HwndEx, 0, "Edit", 0)
'向指定窗口输入一个按键,按键码49为1键
Call Plugin.Bkgnd.KeyPress(Hwnd, 49)
Delay 500
'向指定窗口输入一个按键,按键码65为A键
Call Plugin.Bkgnd.KeyPress(Hwnd, 65)
Delay 500
'向指定窗口输入一个按键,按键码13为回车键
Call Plugin.Bkgnd.KeyPress(Hwnd, 13)
Delay 500
'向指定窗口发送一个文本消息
Call Plugin.Bkgnd.SendString(Hwnd, "我是文本内容,OY!")
作者: czjt1234 时间: 2012-12-14 08:52
6楼的vbs也是前台的,不行
按键精灵我没用过,不过看9楼的代码,用到了句柄,那就是调用了api
我找了个vbs调用api的例子,你研究下,需要用到dynwrap.dll文件
有2个版本,一个36K,一个44K,都可以用
作者: czjt1234 时间: 2012-12-14 09:02
Declare Function keybd_event Lib "user32" Alias "keybd_event" (ByVal bVk As Byte, ByVal bScan As Byte, ByVal dwFlags As Long, ByVal dwExtraInfo As Long)
发送按键用这个api
这里有api原型和vbs调用的格式- Dim UserWrap,hWnd
-
- Set UserWrap = CreateObject("DynamicWrapper")
-
- 'Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
-
- UserWrap.Register "USER32.DLL", "FindWindow", "I=ss", "f=s", "R=l"
-
- 'Declare Function SetWindowPos Lib "user32" Alias "SetWindowPos" (ByVal hwnd As Long, ByVal hWndInsertAfter As Long, ByVal x As Long, ByVal y As Long, ByVal cx As Long, ByVal cy As Long, ByVal wFlags As Long) As Long
-
- UserWrap.Register "USER32.DLL", "SetWindowPos", "I=Hllllll", "f=s", "R=l"
-
- hWnd = UserWrap.FindWindow(vbNullString, "计算器")
-
- UserWrap.SetWindowPos hWnd, -1, 0, 0, 0, 0, 3
-
- MsgBox "现在将鼠标移到左上角!"
-
- 'Declare Function SetCursorPos Lib "user32" (ByVal X As Long, ByVal Y As Long) As Long
-
- UserWrap.Register "USER32.DLL", "SetCursorPos", "I=ll", "f=s", "R=l"
-
- UserWrap.SetCursorPos 0,0
复制代码
作者: czjt1234 时间: 2012-12-14 09:08
REM i: (Argument Type)
REM 'a', sizeof(IDispatch*), VT_DISPATCH} // a IDispatch*
REM 'c', sizeof(unsigned char), VT_I4} // c signed char
REM 'd', sizeof(double), VT_R8} // d 8 byte real
REM 'f', sizeof(float), VT_R4} // f 4 byte real
REM 'k', sizeof(IUnknown*), VT_UNKNOWN} // k IUnknown*
REM 'h', sizeof(long), VT_I4} // h HANDLE
REM 'l', sizeof(long), VT_I4} // l long
REM 'p', sizeof(void*), VT_PTR} // p pointer
REM 's', sizeof(BSTR), VT_LPSTR} // s string
REM 't', sizeof(short), VT_I2} // t short
REM 'u', sizeof(UINT), VT_UINT} // u unsigned int
REM 'w', sizeof(BSTR), VT_LPWSTR} // w wide string
REM f: (Call Method)
REM 'm' - DC_MICROSOFT 0x0000, Default
REM 'b' - DC_BORLAND 0x0001, Borland compat
REM 's' - DC_CALL_STD 0x0020, __stdcall
REM 'c' - DC_CALL_CDECL 0x0010, __cdecl
REM '4' - DC_RETVAL_MATH4 0x0100, Return value in ST
REM '8' - DC_RETVAL_MATH8 0x0200, Return value in ST
REM r: (Return Type)
REM Same as i
上面是"I=ss", "f=s", "R=l"参数
I是输入,s代表一个String类型的参数,
f=s不用管,照抄
R是输出
但是这种调用办法有很多局限,比如指针类型的参数就不行,自定义类型的参数也不行
用excel调用,格式方面比较简单
下面是个例子- Option Explicit
- Dim WshShell, oExcel, strRegKey, strCode, x, y
-
- Set oExcel = CreateObject("Excel.Application")
- set WshShell = CreateObject("wscript.Shell")
-
- strRegKey = "HKEY_CURRENT_USER\Software\Microsoft\Office\$\Excel\Security\AccessVBOM"
- strRegKey = Replace(strRegKey, "$", oExcel.Version)
- '生成注册表路径,oExcel.Version 是当前版本号
- WshShell.RegWrite strRegKey, 1, "REG_DWORD"
- '写如注册表,1表示设置安全级别为低,这样添加宏就不会有安全提示了
-
- strCode = _
- "Private Declare Function SetCursorPos Lib ""user32"" (ByVal x As Long, ByVal y As Long) As Long" & vbCrLf & _
- vbCrLf & _
- "Private Type POINTAPI" & vbCrLf & _
- "X As Long" & vbCrLf & _
- "Y As Long" & vbCrLf & _
- "End Type" & vbCrLf & _
- vbCrLf & _
- "Private Declare Function GetCursorPos Lib ""user32"" (lpPoint As POINTAPI) As Long" & vbCrLf & _
- vbCrLf & _
- "Sub SetCursor(x as Long, y as Long)" & vbCrLf & _
- "SetCursorPos x, y" & vbCrLf & _
- "End Sub" & vbCrLf & _
- vbCrLf & _
- "Public Function GetXCursorPos() As Long" & vbCrLf & _
- "Dim pt As POINTAPI" & vbCrLf & _
- "GetCursorPos pt" & vbCrLf & _
- "GetXCursorPos = pt.X" & vbCrLf & _
- "End Function" & vbCrLf & _
- vbCrLf & _
- "Public Function GetYCursorPos() As Long" & vbCrLf & _
- "Dim pt As POINTAPI" & vbCrLf & _
- "GetCursorPos pt" & vbCrLf & _
- "GetYCursorPos = pt.Y" & vbCrLf & _
- "End Function"
-
- oExcel.Workbooks.Add.VBProject.VBComponents.Add(1).CodeModule.AddFromString strCode
-
- x = oExcel.Run("GetXCursorPos")
- y = oExcel.Run("GetYCursorPos")
- WScript.Echo x, y
-
- oExcel.Run "SetCursor", 1024, 768
-
- oExcel.DisplayAlerts = False
- oExcel.Workbooks.Add.Close
- oExcel.Quit
复制代码
作者: czjt1234 时间: 2012-12-14 09:13
本帖最后由 czjt1234 于 2012-12-14 09:16 编辑
按键精灵屏蔽了具体的api,给你固定格式直接调用,很方便
看它代码,应该是先获取句柄,再向指定句柄发送按键,不知道是哪个api
正好我也想研究“向指定句柄发送按键”,我们一起交流交流
作者: zgh7878788 时间: 2012-12-14 20:14
回复 13# czjt1234
非常感谢老师!给您添麻烦了!我先看看,研究一下再来说说。谢谢!非常感谢!!!!
作者: zgh7878788 时间: 2012-12-14 20:32
回复 12# czjt1234
老师,12L那个例子好像是获取鼠标坐标的,实际应用中不知道该怎么用?11L的Set UserWrap = CreateObject("DynamicWrapper")报错,说ActiveX部件不能创建对象:'DynamicWrapper'
作者: czjt1234 时间: 2012-12-14 20:45
注册10楼的dll文件先
作者: zhangop9 时间: 2021-1-2 15:14
窗口模拟点击按键
欢迎光临 批处理之家 (http://bbs.bathome.net/) |
Powered by Discuz! 7.2 |