找回密码
 立即注册→加入我们

QQ登录

只需一步,快速开始

搜索
热搜: 下载 VB C 实现 编写
查看: 19027|回复: 32

【vb】老C带你写一个“按键精灵”

[复制链接]
发表于 2015-5-2 01:17:01 | 显示全部楼层 |阅读模式

欢迎访问技术宅的结界,请注册或者登录吧。

您需要 登录 才可以下载或查看,没有账号?立即注册→加入我们

×
来来来,让我们做一个“按键精灵”
这第一步嘛,确定软件功能及架构
什么样的按键精灵呢?因为咱们都是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)
  1. Attribute VB_Name = "XSSMain"
  2. Option Explicit

  3. '定义要用到的api
  4. Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
  5. Private Declare Function SetCursorPos Lib "user32" (ByVal x As Long, ByVal y As Long) As Long
  6. Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
  7. 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)
  8. Private Declare Function SetForegroundWindow Lib "user32" (ByVal hwnd As Long) As Long

  9. Private Const MOUSEEVENTF_LEFTDOWN = &H2
  10. Private Const MOUSEEVENTF_LEFTUP = &H4
  11. Private Const MOUSEEVENTF_RIGHTDOWN = &H8
  12. Private Const MOUSEEVENTF_RIGHTUP = &H10

  13. Dim fso As FileSystemObject
  14. Dim fNameS As String

  15. Sub Main()
  16.     On Error GoTo ErrH
  17.     Dim f As Object
  18.     Dim prog() As String
  19.     Dim cL As Double

  20.     Dim ctr() As Long
  21.     Dim loopCtr As Long
  22.     Dim ifShowLine() As Long
  23.     '用fso来读取文件
  24.     Set fso = CreateObject("Scripting.FileSystemObject")
  25.     '将传入的文件位置给fnames变量
  26.     fNameS = Command$
  27.    
  28.     If Not fso.FileExists(fNameS) Then
  29.         ErrorMsg "文件未找到", 101
  30.         End
  31.     End If
  32.    
  33.     Dim i As Long
  34.     Dim s1 As String
  35.     Dim s3 As String
  36.    
  37.     i = 0
  38.     loopCtr = 0
  39.     '以下是解释器错误处理
  40.     Set f = fso.OpenTextFile(fNameS, ForReading, False)
  41.         Do Until f.AtEndOfStream
  42.             ReDim Preserve prog(i) As String
  43.             prog(i) = f.ReadLine
  44.             s1 = LCase(prog(i))
  45.             
  46.             Select Case Mid(s1, 1, 2)
  47.             
  48.             Case "fc"
  49.                 If FindWindow(vbNullString, Mid(s1, InStr(s1, " ") + 1)) = 0 Then
  50.                     ErrorMsg "未找到标题为 " & Mid(s1, InStr(s1, " ") + 1) & " 的窗口" & vbCrLf & "行:" & i + 1 & vbCrLf & "源:" & fNameS, 102
  51.                     End
  52.                 End If
  53.             Case "cl"
  54.                 s3 = Mid(s1, InStr(s1, " ") + 1, 2)
  55.                 If (s3 <> "+=") And (s3 <> "-=") And (s3 <> "*=") And (s3 <> "/=") And (s3 <> "==") Then
  56.                     ErrorMsg "运算符错误" & vbCrLf & "行:" & i + 1 & vbCrLf & "源:" & fNameS, 103
  57.                     End
  58.                 End If
  59.                 If Not IsNumeric(Mid(s1, InStr(s1, " ") + 3)) Then
  60.                     ErrorMsg "非法赋值" & vbCrLf & "行:" & i + 1 & vbCrLf & "源:" & fNameS, 104
  61.                     End
  62.                 End If
  63.             Case "sl"
  64.                 If Not IsNumeric(Mid(s1, 3)) Then
  65.                     ErrorMsg "非有效数字" & vbCrLf & "行:" & i + 1 & vbCrLf & "源:" & fNameS, 105
  66.                     End
  67.                 End If
  68.             Case "mp"
  69.                 If (Not IsNumeric(Mid(s1, InStr(s1, " "), InStr(s1, ",") - 3))) Or (Not IsNumeric(Mid(s1, InStr(s1, ",") + 1))) Then
  70.                     ErrorMsg "非有效数字" & vbCrLf & "行:" & i + 1 & vbCrLf & "源:" & fNameS, 105
  71.                     End
  72.                 End If
  73.             Case "mc"
  74.                 If (Mid(s1, 4) <> "l") And (Mid(s1, 4) <> "r") Then
  75.                     ErrorMsg "非可用的鼠标按键" & vbCrLf & "行:" & i + 1 & vbCrLf & "源:" & fNameS, 106
  76.                     End
  77.                 End If
  78.             Case "if"
  79.                
  80.                 ReDim ctr(loopCtr) As Long
  81.                 ReDim Preserve ifShowLine(loopCtr) As Long
  82.                 ifShowLine(loopCtr) = i
  83.                 loopCtr = loopCtr + 1
  84.                
  85.                 s3 = Mid(s1, 4)
  86.                 If Not IsNumeric(Mid(s3, 1, InStr(1, s3, " ") - 1)) Then
  87.                     ErrorMsg "非有效数字" & vbCrLf & "行:" & i + 1 & vbCrLf & "源:" & fNameS, 105
  88.                     End
  89.                 End If
  90.             End Select
  91.             i = i + 1
  92.         Loop
  93.     f.Close
  94.     loopCtr = 0
  95.     Dim j  As Long
  96.     '这是解释器执行核心,原理很简单,大家应该看得懂
  97.     For i = 0 To UBound(prog)
  98.         s1 = LCase(prog(i))
  99.         Select Case Mid(s1, 1, 2)
  100.         Case "sk"
  101.             SendKeys Replace(Mid(s1, InStr(s1, " ") + 1), "{cl}", cL), True
  102.         Case "fc"
  103.             Dim hwndA As Long
  104.             hwndA = FindWindow(vbNullString, Mid(s1, InStr(s1, " ") + 1))
  105.             If hwndA <> 0 Then
  106.                 SetForegroundWindow hwndA
  107.             Else
  108.                 ErrorMsg "未找到标题为 " & Mid(s1, InStr(s1, " ") + 1) & " 的窗口" & vbCrLf & "行:" & i + 1 & vbCrLf & "源:" & fNameS, 102
  109.                 End
  110.             End If
  111.         Case "sl"
  112.             Sleep (CLng(Mid(s1, 3)))
  113.         Case "mp"
  114.             SetCursorPos CLng(Mid(s1, InStr(s1, " "), InStr(s1, ",") - 3)), CLng(Mid(s1, InStr(s1, ",") + 1))
  115.         Case "mc"
  116.             If Mid(s1, 4) = "l" Then
  117.                 mouse_event MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0
  118.                 mouse_event MOUSEEVENTF_LEFTUP, 0, 0, 0, 0
  119.             ElseIf Mid(s1, 4) = "r" Then
  120.                 mouse_event MOUSEEVENTF_RIGHTDOWN, 0, 0, 0, 0
  121.                 mouse_event MOUSEEVENTF_RIGHTUP, 0, 0, 0, 0
  122.             End If
  123.         Case "if"
  124.             
  125.             s3 = Mid(s1, 4)
  126.             If Val(Mid(s3, 1, InStr(1, s3, " ") - 1)) <> 0 Then
  127.                 If ctr(loopCtr) + 1 < Val(Mid(s3, 1, InStr(1, s3, " ") - 1)) Then
  128.                     For j = 0 To UBound(prog)
  129.                         If prog(j) = Mid(s1, InStr(1, s1, "goto") + 5) Then
  130.                             i = j
  131.                         End If
  132.                     Next
  133.                 Else
  134.                     If i <> ifShowLine(loopCtr) Then
  135.                         loopCtr = loopCtr + 1
  136.                         ctr(loopCtr - 1) = 0
  137.                     End If
  138.                 End If
  139.                
  140.                 ctr(loopCtr) = ctr(loopCtr) + 1
  141.             Else
  142.                 MsgBox Mid(s1, InStr(1, s1, "goto") + 5)
  143.                 For j = 0 To UBound(prog)
  144.                     If prog(j) = Mid(s1, InStr(1, s1, "goto") + 5) Then
  145.                         i = j
  146.                     End If
  147.                 Next
  148.             End If
  149.         Case "cl"
  150.             s3 = Mid(s1, InStr(s1, " ") + 1, 2)
  151.             Select Case s3
  152.             Case "=="
  153.                 cL = Val(Mid(s1, InStr(s1, " ") + 3))
  154.             Case "+="
  155.                 cL = cL + Val(Mid(s1, InStr(s1, " ") + 3))
  156.             Case "-="
  157.                 cL = cL - Val(Mid(s1, InStr(s1, " ") + 3))
  158.             Case "*="
  159.                 cL = cL * Val(Mid(s1, InStr(s1, " ") + 3))
  160.             Case "/="
  161.                 cL = cL / Val(Mid(s1, InStr(s1, " ") + 3))
  162.             End Select
  163.         End Select
  164.     Next
  165. ErrH:'未知错误处理
  166.     If Err <> 0 Then ErrorMsg vbCrLf & Err.Description, Err.Number
  167. End Sub

  168. Function ErrorMsg(inpStr As String, errNum As Integer)
  169.     ErrorMsg = MsgBox("错误:" & errNum & vbCrLf & inpStr, vbOKOnly + vbCritical, "XSendKeys")
  170. End Function
复制代码


接下来的任务是做一个脚本编辑器:
关于怎样用vb编写一个记事本,老C在这篇帖子有详尽细数,
【入门向】Counterfeit Notepad
http://www.0xaa55.com/forum.php? ... 109&fromuid=418
(出处: 技术宅的结界)

脚本编辑器,无非是在记事本中添加运行功能,这里不再赘述
界面大致做成这样即可:
捕获.PNG

好了,在编辑器中写一个自己的脚本试试吧

源码回复可见下载地址:

游客,如果您要查看本帖隐藏内容请回复

本帖被以下淘专辑推荐:

回复

使用道具 举报

发表于 2015-12-18 02:51:53 | 显示全部楼层
  謝謝大大的教學  讓我又多學了一課
回复 赞! 靠!

使用道具 举报

发表于 2016-7-11 11:41:02 | 显示全部楼层
】老C带你写一个“按键精灵”
回复 赞! 靠!

使用道具 举报

发表于 2017-1-5 10:45:26 | 显示全部楼层
感谢大神,学习了。
回复 赞! 靠!

使用道具 举报

发表于 2017-1-5 10:46:03 | 显示全部楼层
感谢大神,在此学习了。
回复 赞! 靠!

使用道具 举报

发表于 2017-2-25 19:43:51 | 显示全部楼层
学习学习,再学习
回复 赞! 靠!

使用道具 举报

发表于 2017-6-20 16:09:37 | 显示全部楼层
Very Nice!很感谢分享代码!
回复 赞! 靠!

使用道具 举报

发表于 2017-6-28 21:56:00 | 显示全部楼层
新人想问一下,要是写一个脚本的话,是在计事本上运行?那怎么做出一个应用般的界面?
回复 赞! 靠!

使用道具 举报

发表于 2017-9-8 22:29:07 | 显示全部楼层
6666666666666666666666666666
回复 赞! 靠!

使用道具 举报

发表于 2017-10-16 12:18:24 | 显示全部楼层

感谢大神,在此学习了。
回复 赞! 靠!

使用道具 举报

发表于 2017-10-18 12:30:42 | 显示全部楼层
太牛了,谢谢分享
回复 赞! 靠!

使用道具 举报

发表于 2017-11-26 09:51:01 | 显示全部楼层
求大神代码研究
回复 赞! 靠!

使用道具 举报

发表于 2017-11-26 09:52:48 | 显示全部楼层
我想问下下载密码多少?
回复 赞! 靠!

使用道具 举报

发表于 2017-12-23 17:30:05 | 显示全部楼层
受教了。谢谢
回复 赞! 靠!

使用道具 举报

发表于 2018-1-14 12:54:58 | 显示全部楼层
支持楼主!!
回复

使用道具 举报

发表于 2018-4-3 10:09:09 | 显示全部楼层
学习学习
回复

使用道具 举报

发表于 2018-5-6 07:19:19 | 显示全部楼层
前台按键.哈哈.有点用
回复 赞! 靠!

使用道具 举报

发表于 2018-5-28 15:11:09 | 显示全部楼层
想學一下,謝謝大大
回复 赞! 靠!

使用道具 举报

发表于 2018-9-3 09:07:43 | 显示全部楼层
学习了,谢谢大佬
回复 赞! 靠!

使用道具 举报

发表于 2018-9-15 00:09:21 | 显示全部楼层
这个我之前看人写过
回复 赞! 靠!

使用道具 举报

本版积分规则

QQ|Archiver|小黑屋|技术宅的结界 ( 滇ICP备16008837号 )|网站地图

GMT+8, 2024-11-22 06:03 , Processed in 0.041846 second(s), 25 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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