UID 418
精华
积分 3994
威望 点
宅币 个
贡献 次
宅之契约 份
最后登录 1970-1-1
在线时间 小时
来来来,让我们做一个“按键精灵”
这第一步嘛,确定软件功能及架构
什么样的按键精灵呢?因为咱们都是vb初学者,先来个简单的
能模拟大部分键盘按键,和鼠标按键即可---目标确定
然后是架构问题,大家不要小看架构这两个字。
虽然老C木有学过《软件工程》但是凭开发经验一个软件的架构决定了软件生存周期的长短
一个好的架构,可以使软件可维护性大大增强。
我是这样决定的:制作一个脚本解释器,用来解释按键脚本。然后做一个界面友好的编辑器
将按键方式以脚本保存在文件中,编辑器的运行功能来调用解释器将按键脚本加以解释。
好的,既然涉及到脚本,我们不妨先来想想用何种脚本语言
那都说了,我们是初学者,老C不会让大家制作一个vbs或者js的解释器,我所想象的脚本,大概是这样:
命令 参数规定 例
: 一个字符串加“:”即为 a:
行号
fc 为一个窗口标题,程序运行 fc 无标题 - 记事本
时会激活这个窗口。
cl 设置一个运算器的值
“==”初始化cl的值 cl == 1
“-=”cl = cl - 值 cl += 2
“*=”cl = cl * 值 cl -= 5
“/=”cl = cl / 值 cl /= 5
sk 为一个或多个按键。
特殊功能键:对于 sk a
需要与Shift、Ctrl、Alt sk abc
三个控制键组合的按键, sk ^
XSendKeys使用特殊字符 sk ^({f4})
来表示:Shift - +; sk {down}
Ctrl - ^;Alt - %。 sk {a 10}
如要发送的组合按键是同 sk {cl}
时按下Ctrl+E,用 ^e
表示,如果要发送的组合
按键是按住Ctrl键的同时
按下E与C两个键,这时应
使用小括号把字母键括起
来,书写格式为 ^(ec)。
注意 ^(ec)与 ^ec 的区
别,后者表示组合按键是
同时按住Ctrl和E键,然
后松开Ctrl键,单独按下
“C”字母键。
由于“+”、“^”这些字
符用来表示特殊的控制按
键了,如何表示这些按键
呢?只要用大括号括住这
些字符即可。例如,要发
送加号“+”,
可使用 {+}
对于一些不会生成字符的
控制功能按键,也同样需
要使用大括号括起来按键
的名称,例如要发送回车
键,需要用 {ENTER} 表
示,发送向下的方向键用
{DOWN} 表示。
如果需要发送多个重复的
单字母按键,不必重复输
入该字母,XSendKeys允
许使用简化格式进行描述
,使用格式为
“{按键 数字}”,例如要
发送10个字母“x”,则
输入 {x 10} 即可。
若要发送一个运算器的值
则输入{cl}即可。
sl sl加一个数字是暂停几个 sl 100
毫秒
mp 该命令将鼠标移至某位置 mp 1000,200
第一个参数是鼠标的x 值
第二个参数是鼠标的y 值
mc 模拟鼠标按键,l是鼠标 mc l
左键,r是鼠标右键 mc r
if goto if 整数 goto 行号
如果循环次数小于整数就
转至行号,否则执行下面
的语句。如果整数为零则
执行死循环。
例子
begin:
fc a.xss - 记事本
cl == 5
sk ^({f4})
a:
cl += 1
sk {cl}
sl 2000
mp 2000,3
mc l
if 3 goto a:
end:
这个例子表示:激或标题为“a.xss - 记事本”的窗体,将运算器的初值设为“5”
然后发送按键Alt + F4,再将运算器的值加一,发送运算器的值,接着暂停2000毫秒(2秒)
将鼠标移至x为2000,y为3之处按下鼠标左键,如果循环次数小于3就转到“a:”处执行
好了,有了详尽的语法规定,我们可以来写解释器了(有没有发现老C在偷懒:sk就是vb sendkeys的用法:P)
Attribute VB_Name = "XSSMain"
Option Explicit
'定义要用到的api
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Private Declare Function SetCursorPos Lib "user32" (ByVal x As Long, ByVal y As Long) As Long
Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
Private Declare Sub mouse_event Lib "user32" (ByVal dwFlags As Long, ByVal dx As Long, ByVal dy As Long, ByVal cButtons As Long, ByVal dwExtraInfo As Long)
Private Declare Function SetForegroundWindow Lib "user32" (ByVal hwnd As Long) As Long
Private Const MOUSEEVENTF_LEFTDOWN = &H2
Private Const MOUSEEVENTF_LEFTUP = &H4
Private Const MOUSEEVENTF_RIGHTDOWN = &H8
Private Const MOUSEEVENTF_RIGHTUP = &H10
Dim fso As FileSystemObject
Dim fNameS As String
Sub Main()
On Error GoTo ErrH
Dim f As Object
Dim prog() As String
Dim cL As Double
Dim ctr() As Long
Dim loopCtr As Long
Dim ifShowLine() As Long
'用fso来读取文件
Set fso = CreateObject("Scripting.FileSystemObject")
'将传入的文件位置给fnames变量
fNameS = Command$
If Not fso.FileExists(fNameS) Then
ErrorMsg "文件未找到", 101
End
End If
Dim i As Long
Dim s1 As String
Dim s3 As String
i = 0
loopCtr = 0
'以下是解释器错误处理
Set f = fso.OpenTextFile(fNameS, ForReading, False)
Do Until f.AtEndOfStream
ReDim Preserve prog(i) As String
prog(i) = f.ReadLine
s1 = LCase(prog(i))
Select Case Mid(s1, 1, 2)
Case "fc"
If FindWindow(vbNullString, Mid(s1, InStr(s1, " ") + 1)) = 0 Then
ErrorMsg "未找到标题为 " & Mid(s1, InStr(s1, " ") + 1) & " 的窗口" & vbCrLf & "行:" & i + 1 & vbCrLf & "源:" & fNameS, 102
End
End If
Case "cl"
s3 = Mid(s1, InStr(s1, " ") + 1, 2)
If (s3 <> "+=") And (s3 <> "-=") And (s3 <> "*=") And (s3 <> "/=") And (s3 <> "==") Then
ErrorMsg "运算符错误" & vbCrLf & "行:" & i + 1 & vbCrLf & "源:" & fNameS, 103
End
End If
If Not IsNumeric(Mid(s1, InStr(s1, " ") + 3)) Then
ErrorMsg "非法赋值" & vbCrLf & "行:" & i + 1 & vbCrLf & "源:" & fNameS, 104
End
End If
Case "sl"
If Not IsNumeric(Mid(s1, 3)) Then
ErrorMsg "非有效数字" & vbCrLf & "行:" & i + 1 & vbCrLf & "源:" & fNameS, 105
End
End If
Case "mp"
If (Not IsNumeric(Mid(s1, InStr(s1, " "), InStr(s1, ",") - 3))) Or (Not IsNumeric(Mid(s1, InStr(s1, ",") + 1))) Then
ErrorMsg "非有效数字" & vbCrLf & "行:" & i + 1 & vbCrLf & "源:" & fNameS, 105
End
End If
Case "mc"
If (Mid(s1, 4) <> "l") And (Mid(s1, 4) <> "r") Then
ErrorMsg "非可用的鼠标按键" & vbCrLf & "行:" & i + 1 & vbCrLf & "源:" & fNameS, 106
End
End If
Case "if"
ReDim ctr(loopCtr) As Long
ReDim Preserve ifShowLine(loopCtr) As Long
ifShowLine(loopCtr) = i
loopCtr = loopCtr + 1
s3 = Mid(s1, 4)
If Not IsNumeric(Mid(s3, 1, InStr(1, s3, " ") - 1)) Then
ErrorMsg "非有效数字" & vbCrLf & "行:" & i + 1 & vbCrLf & "源:" & fNameS, 105
End
End If
End Select
i = i + 1
Loop
f.Close
loopCtr = 0
Dim j As Long
'这是解释器执行核心,原理很简单,大家应该看得懂
For i = 0 To UBound(prog)
s1 = LCase(prog(i))
Select Case Mid(s1, 1, 2)
Case "sk"
SendKeys Replace(Mid(s1, InStr(s1, " ") + 1), "{cl}", cL), True
Case "fc"
Dim hwndA As Long
hwndA = FindWindow(vbNullString, Mid(s1, InStr(s1, " ") + 1))
If hwndA <> 0 Then
SetForegroundWindow hwndA
Else
ErrorMsg "未找到标题为 " & Mid(s1, InStr(s1, " ") + 1) & " 的窗口" & vbCrLf & "行:" & i + 1 & vbCrLf & "源:" & fNameS, 102
End
End If
Case "sl"
Sleep (CLng(Mid(s1, 3)))
Case "mp"
SetCursorPos CLng(Mid(s1, InStr(s1, " "), InStr(s1, ",") - 3)), CLng(Mid(s1, InStr(s1, ",") + 1))
Case "mc"
If Mid(s1, 4) = "l" Then
mouse_event MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0
mouse_event MOUSEEVENTF_LEFTUP, 0, 0, 0, 0
ElseIf Mid(s1, 4) = "r" Then
mouse_event MOUSEEVENTF_RIGHTDOWN, 0, 0, 0, 0
mouse_event MOUSEEVENTF_RIGHTUP, 0, 0, 0, 0
End If
Case "if"
s3 = Mid(s1, 4)
If Val(Mid(s3, 1, InStr(1, s3, " ") - 1)) <> 0 Then
If ctr(loopCtr) + 1 < Val(Mid(s3, 1, InStr(1, s3, " ") - 1)) Then
For j = 0 To UBound(prog)
If prog(j) = Mid(s1, InStr(1, s1, "goto") + 5) Then
i = j
End If
Next
Else
If i <> ifShowLine(loopCtr) Then
loopCtr = loopCtr + 1
ctr(loopCtr - 1) = 0
End If
End If
ctr(loopCtr) = ctr(loopCtr) + 1
Else
MsgBox Mid(s1, InStr(1, s1, "goto") + 5)
For j = 0 To UBound(prog)
If prog(j) = Mid(s1, InStr(1, s1, "goto") + 5) Then
i = j
End If
Next
End If
Case "cl"
s3 = Mid(s1, InStr(s1, " ") + 1, 2)
Select Case s3
Case "=="
cL = Val(Mid(s1, InStr(s1, " ") + 3))
Case "+="
cL = cL + Val(Mid(s1, InStr(s1, " ") + 3))
Case "-="
cL = cL - Val(Mid(s1, InStr(s1, " ") + 3))
Case "*="
cL = cL * Val(Mid(s1, InStr(s1, " ") + 3))
Case "/="
cL = cL / Val(Mid(s1, InStr(s1, " ") + 3))
End Select
End Select
Next
ErrH:'未知错误处理
If Err <> 0 Then ErrorMsg vbCrLf & Err.Description, Err.Number
End Sub
Function ErrorMsg(inpStr As String, errNum As Integer)
ErrorMsg = MsgBox("错误:" & errNum & vbCrLf & inpStr, vbOKOnly + vbCritical, "XSendKeys")
End Function
复制代码
接下来的任务是做一个脚本编辑器:
关于怎样用vb编写一个记事本,老C在这篇帖子有详尽细数,
【入门向】Counterfeit Notepad
http://www.0xaa55.com/forum.php? ... 109&fromuid=418
(出处: 技术宅的结界)
脚本编辑器,无非是在记事本中添加运行功能,这里不再赘述
界面大致做成这样即可:
好了,在编辑器中写一个自己的脚本试试吧
源码回复可见下载地址: