多线程独立按键后台发送工具 (五按键版) v5.0 附带AHK源码

文章目录(快捷跳转)

 

工具特点
五按键独立控制:同时控制5个按键,每个按键独立设置内容和间隔
真后台发送:窗口最小化也能发送(ControlSend/PostMessage模式)
三重发送模式:
ControlSend:后台发送(推荐)
PostMessage:底层消息防检测
SendInput:前台模拟
智能窗口绑定:一键锁定目标窗口
实时状态监控:显示每个线程运行状态
完全开源:代码透明无后门


作者:Mr Bean(多年吾爱老坛友)
开发工具:AutoHotkey v2.0
运行平台:Windows 7/10/11

各位坛友大家好!
在吾爱论坛潜水多年,最近在魔兽乌龟服摸鱼时用AHK写了这个后台按键工具,压缩包大小仅2M,

特点就是给指定窗口连续发送后台按键,不干扰咱们前端牛马!现开源分享给大家!

重要提示:必须用管理员权限运行!否则后台发送会失效!

使用说明
第一步:右键以管理员身份运行脚本
第二步:点击【选择窗口】→ 切换到目标窗口 → 确定
第三步:设置按键内容和间隔(建议>100ms)
第四步:点击【启动】开始发送

---

高级功能
一键发送:独立线程,最多发送5个按键
保存配置:下次启动自动加载
紧急熔断:一键停止所有线程

---

下载与运行
成品版:下载附件压缩包→解压→右键管理员运行
源码版:安装AutoHotkey v2.0→保存代码为.ahk文件→右键管理员运行

---

下载点击上面的快捷目录即可跳转到下载地址
---

给坛友的话
> 第一次在吾爱发原创工具,心情激动又紧张
> 边学AHK边写的工具,源码带详细注释
> 郑重承诺:
100%原创无抄袭
无后门无病毒
永久开源免费
> 特别感谢:
吾爱论坛提供的学习平台!
>
热心坛友们的技术分享!
>
管理员大大们的辛苦付出!
>
遇到问题欢迎回帖交流!
觉得好用请给个免费评分鼓励~

完整开源源码

; ===== 多线程独立按键后台发送工具 (五按键版) =====
#SingleInstance Force
#MaxThreadsPerHotkey 5
InstallKeybdHook()
Persistent()
 
; 管理员权限检查
if !A_IsAdmin {
    try Run('*RunAs "' A_AhkPath '" "' A_ScriptFullPath '"')
    ExitApp
}
 
; === 配置 ===
global Config := Map(
    "targetHwnd", 0,       ; 目标窗口句柄
    "targetTitle", "",     ; 目标窗口标题
    "targetClass", "",     ; 目标窗口类名
    "keyToSend1", "1",     ; 按键1
    "keyToSend2", "",      ; 按键2
    "keyToSend3", "",      ; 按键3
    "keyToSend4", "",      ; 按键4
    "keyToSend5", "",      ; 按键5
    "interval1", 500,      ; 按键1发送间隔
    "interval2", 1000,     ; 按键2发送间隔
    "interval3", 1500,     ; 按键3发送间隔
    "interval4", 2000,     ; 按键4发送间隔
    "interval5", 2500,     ; 按键5发送间隔
    "sendMethod", "ControlSend",  ; 发送方法
    "debug", true          ; 启用调试模式
)
 
; 按键线程状态
global KeyThreads := Map(
    "key1", Map("running", false, "timer", 0),
    "key2", Map("running", false, "timer", 0),
    "key3", Map("running", false, "timer", 0),
    "key4", Map("running", false, "timer", 0),
    "key5", Map("running", false, "timer", 0)
)
 
; === GUI 界面 - 优化版 ===
CreateGUI() {
    global
     
    ; 主窗口
    MyGui := Gui("+Resize -MinimizeBox", "多线程后台按键发送工具 v5.0 by Mr Bean")
    MyGui.OnEvent("Close", GuiClose)
    MyGui.SetFont("s9", "Segoe UI")
    MyGui.MarginX := 10, MyGui.MarginY := 10
     
    ; ===== 左侧区域:窗口设置 =====
    leftSection := MyGui.Add("GroupBox", "x10 y10 w300 h150 Section", "目标窗口设置")
     
    ; 窗口选择行
    MyGui.Add("Text", "xs+10 ys+30 w80", "窗口句柄:")
    hwndEdit := MyGui.Add("Edit", "vHwndEdit w100 xs+90 ys+25", Config["targetHwnd"])
    selectBtn := MyGui.Add("Button", "x+5 yp-3 w90", "选择窗口")
    selectBtn.OnEvent("Click", SelectWindow)
     
    ; 窗口信息 (缩小输入框)
    MyGui.Add("Text", "xs+10 ys+65 w80", "窗口标题:")
    titleEdit := MyGui.Add("Edit", "vTitleEdit w200 xs+90 ys+60", Config["targetTitle"])
    MyGui.Add("Text", "xs+10 ys+95 w80", "窗口类名:")
    classEdit := MyGui.Add("Edit", "vClassEdit w200 xs+90 ys+90", Config["targetClass"])
     
    ; 发送方法
    MyGui.Add("Text", "xs+10 ys+125 w80", "发送方法:")
    methodDDL := MyGui.Add("DropDownList", "vMethodDDL w120 xs+90 ys+122 Choose1", ["ControlSend", "PostMessage", "SendInput"])
    methodDDL.Text := Config["sendMethod"]
     
    ; ===== 右侧区域:按键设置 =====
    rightSection := MyGui.Add("GroupBox", "x320 y10 w300 h230 Section", "按键设置")
     
    ; 按键1设置
    MyGui.Add("Text", "xs+10 ys+30 w40", "按键1:")
    keyEdit1 := MyGui.Add("Edit", "vKeyEdit1 w40 xs+50 ys+25", Config["keyToSend1"])
    MyGui.Add("Text", "xs+100 ys+30 w50", "间隔(ms):")  ; 宽度增加避免换行
    intervalEdit1 := MyGui.Add("Edit", "vIntervalEdit1 w50 xs+150 ys+25", Config["interval1"])
    key1ToggleBtn := MyGui.Add("Button", "x+10 yp-3 w80", "启动按键1")
    key1ToggleBtn.OnEvent("Click", (*) => ToggleKeyThread("key1"))
     
    ; 按键2设置
    MyGui.Add("Text", "xs+10 ys+70 w40", "按键2:")
    keyEdit2 := MyGui.Add("Edit", "vKeyEdit2 w40 xs+50 ys+65", Config["keyToSend2"])
    MyGui.Add("Text", "xs+100 ys+70 w50", "间隔(ms):")
    intervalEdit2 := MyGui.Add("Edit", "vIntervalEdit2 w50 xs+150 ys+65", Config["interval2"])
    key2ToggleBtn := MyGui.Add("Button", "x+10 yp-3 w80", "启动按键2")
    key2ToggleBtn.OnEvent("Click", (*) => ToggleKeyThread("key2"))
     
    ; 按键3设置
    MyGui.Add("Text", "xs+10 ys+110 w40", "按键3:")
    keyEdit3 := MyGui.Add("Edit", "vKeyEdit3 w40 xs+50 ys+105", Config["keyToSend3"])
    MyGui.Add("Text", "xs+100 ys+110 w50", "间隔(ms):")
    intervalEdit3 := MyGui.Add("Edit", "vIntervalEdit3 w50 xs+150 ys+105", Config["interval3"])
    key3ToggleBtn := MyGui.Add("Button", "x+10 yp-3 w80", "启动按键3")
    key3ToggleBtn.OnEvent("Click", (*) => ToggleKeyThread("key3"))
     
    ; 按键4设置
    MyGui.Add("Text", "xs+10 ys+150 w40", "按键4:")
    keyEdit4 := MyGui.Add("Edit", "vKeyEdit4 w40 xs+50 ys+145", Config["keyToSend4"])
    MyGui.Add("Text", "xs+100 ys+150 w50", "间隔(ms):")
    intervalEdit4 := MyGui.Add("Edit", "vIntervalEdit4 w50 xs+150 ys+145", Config["interval4"])
    key4ToggleBtn := MyGui.Add("Button", "x+10 yp-3 w80", "启动按键4")
    key4ToggleBtn.OnEvent("Click", (*) => ToggleKeyThread("key4"))
     
    ; 按键5设置 (独立一行,位置下移)
    MyGui.Add("Text", "xs+10 ys+190 w40", "按键5:")
    keyEdit5 := MyGui.Add("Edit", "vKeyEdit5 w40 xs+50 ys+185", Config["keyToSend5"])
    MyGui.Add("Text", "xs+100 ys+190 w50", "间隔(ms):")
    intervalEdit5 := MyGui.Add("Edit", "vIntervalEdit5 w50 xs+150 ys+185", Config["interval5"])
    key5ToggleBtn := MyGui.Add("Button", "x+10 yp-3 w80", "启动按键5")
    key5ToggleBtn.OnEvent("Click", (*) => ToggleKeyThread("key5"))
     
    ; ===== 底部区域:控制按钮 =====
    btnSection := MyGui.Add("GroupBox", "x10 y250 w610 h80 Section", "控制面板")
     
    ; 按钮行
    sendBtn := MyGui.Add("Button", "xs+10 ys+25 w90 h30", "发送一次")
    sendBtn.SetFont("s10")
    sendBtn.OnEvent("Click", SendKeyOnce)
     
    saveBtn := MyGui.Add("Button", "x+20 yp w90 h30", "保存配置")
    saveBtn.SetFont("s10")
    saveBtn.OnEvent("Click", SaveConfig)
     
    stopAllBtn := MyGui.Add("Button", "x+20 yp w100 h30", "全部停止")
    stopAllBtn.SetFont("s10")
    stopAllBtn.OnEvent("Click", StopAllThreads)
     
    ; 状态指示器 (多行显示所有线程状态)
    statusGroup := MyGui.Add("GroupBox", "x10 y340 w610 h100", "线程状态")
    statusText := MyGui.Add("Text", "x20 y360 w590 h80", "就绪 - 请选择目标窗口")
     
    ; 显示GUI
    MyGui.Show("w630 h450")
     
    ; 保存控件引用
    global GuiControls := Map(
        "hwndEdit", hwndEdit,
        "titleEdit", titleEdit,
        "classEdit", classEdit,
        "keyEdit1", keyEdit1,
        "keyEdit2", keyEdit2,
        "keyEdit3", keyEdit3,
        "keyEdit4", keyEdit4,
        "keyEdit5", keyEdit5,
        "intervalEdit1", intervalEdit1,
        "intervalEdit2", intervalEdit2,
        "intervalEdit3", intervalEdit3,
        "intervalEdit4", intervalEdit4,
        "intervalEdit5", intervalEdit5,
        "methodDDL", methodDDL,
        "statusText", statusText,
        "key1ToggleBtn", key1ToggleBtn,
        "key2ToggleBtn", key2ToggleBtn,
        "key3ToggleBtn", key3ToggleBtn,
        "key4ToggleBtn", key4ToggleBtn,
        "key5ToggleBtn", key5ToggleBtn
    )
}
 
; === 窗口选择功能 ===
SelectWindow(*) {
    global Config, GuiControls
     
    MsgBox("请切换到目标窗口,然后点击确定", "选择窗口", "Iconi T5")
     
    try {
        Config["targetHwnd"] := WinGetID("A")
        Config["targetTitle"] := WinGetTitle("A")
        Config["targetClass"] := WinGetClass("A")
         
        GuiControls["hwndEdit"].Value := Config["targetHwnd"]
        GuiControls["titleEdit"].Value := Config["targetTitle"]
        GuiControls["classEdit"].Value := Config["targetClass"]
         
        UpdateStatus("窗口已选择: " Config["targetTitle"])
    } catch {
        UpdateStatus("错误: 无法获取窗口信息")
    }
}
 
; === 发送功能 ===
SendKeyOnce(*) {
    global Config, GuiControls
     
    ; 从GUI获取当前设置
    UpdateConfigFromGUI()
     
    ; 发送按键序列
    if (Config["keyToSend1"] != "")
        SendKeyToWindow(Config["keyToSend1"])
    if (Config["keyToSend2"] != "")
        SendKeyToWindow(Config["keyToSend2"])
    if (Config["keyToSend3"] != "")
        SendKeyToWindow(Config["keyToSend3"])
    if (Config["keyToSend4"] != "")
        SendKeyToWindow(Config["keyToSend4"])
    if (Config["keyToSend5"] != "")
        SendKeyToWindow(Config["keyToSend5"])
     
    UpdateStatus("按键序列发送完成!")
}
 
; === 按键线程控制 ===
ToggleKeyThread(keyName) {
    global KeyThreads, Config, GuiControls
     
    ; 更新配置
    UpdateConfigFromGUI()
     
    ; 获取按钮引用
    btnRef := GuiControls[keyName . "ToggleBtn"]
     
    ; 获取线程状态
    threadState := KeyThreads[keyName]
     
    if (threadState["running"]) {
        ; 停止线程
        if (threadState["timer"] != 0 && IsObject(threadState["timer"])) {
            SetTimer(threadState["timer"], 0)
            threadState["timer"] := 0
        }
        threadState["running"] := false
        btnRef.Text := "启动" . SubStr(keyName, 4)
        UpdateStatus()
    } else {
        ; 启动线程
        threadState["running"] := true
        btnRef.Text := "停止" . SubStr(keyName, 4)
         
        ; 获取间隔时间
        keyNum := SubStr(keyName, 4)
        interval := Config["interval" . keyNum]
         
        ; 创建线程
        threadState["timer"] := SetTimer((*) => KeyThreadFunction(keyName), interval)
         
        UpdateStatus()
    }
}
 
; 按键线程函数
KeyThreadFunction(keyName) {
    global Config, KeyThreads
     
    threadState := KeyThreads[keyName]
    if (!threadState["running"])
        return
     
    keyNum := SubStr(keyName, 4)
    key := Config["keyToSend" . keyNum]
    if (key != "") {
        SendKeyToWindow(key)
    }
}
 
; 停止所有线程
StopAllThreads(*) {
    global KeyThreads, GuiControls
     
    for keyName, threadState in KeyThreads {
        if (threadState["running"]) {
            if (threadState["timer"] != 0 && IsObject(threadState["timer"])) {
                SetTimer(threadState["timer"], 0)
                threadState["timer"] := 0
            }
            threadState["running"] := false
             
            ; 更新按钮文本
            btnRef := GuiControls[keyName . "ToggleBtn"]
            btnRef.Text := "启动" . SubStr(keyName, 4)
        }
    }
     
    UpdateStatus()
}
 
; === 发送按键功能 ===
SendKeyToWindow(key) {
    global Config
     
    if (!Config["targetHwnd"] || !WinExist("ahk_id " Config["targetHwnd"])) {
        UpdateStatus("错误: 目标窗口不存在!")
        return false
    }
     
    try {
        switch (Config["sendMethod"]) {
            case "ControlSend":
                ControlSend key, , "ahk_id " Config["targetHwnd"]
                LogAction("ControlSend: " key " to " Config["targetTitle"])
                return true
                 
            case "PostMessage":
                vk := GetKeyVK(key)
                if (vk) {
                    PostMessage(0x100, vk, 0, , "ahk_id " Config["targetHwnd"])  ; WM_KEYDOWN
                    PostMessage(0x101, vk, 0xC0000001, , "ahk_id " Config["targetHwnd"]) ; WM_KEYUP
                    LogAction("PostMessage: " key " to " Config["targetTitle"])
                    return true
                }
                return false
                 
            case "SendInput":
                WinActivate "ahk_id " Config["targetHwnd"]
                WinWaitActive("ahk_id " Config["targetHwnd"], , 0.5)
                Send key
                LogAction("SendInput: " key " to " Config["targetTitle"])
                return true
        }
    } catch as e {
        LogAction("错误: " e.Message)
        return false
    }
}
 
; 获取按键虚拟键码
GetKeyVK(key) {
    static map := Map(
        "1", 0x31, "2", 0x32, "3", 0x33, "4", 0x34, "5", 0x35,
        "f", 0x46, "e", 0x45, "g", 0x47, "q", 0x51, "v", 0x56,
        "x", 0x58, "z", 0x5A, "c", 0x43, "r", 0x52, "t", 0x54, "h", 0x48,
        "a", 0x41, "s", 0x53, "d", 0x44, "w", 0x57, "Space", 0x20,
        "Enter", 0x0D, "Tab", 0x09, "Esc", 0x1B, "Backspace", 0x08,
        "Up", 0x26, "Down", 0x28, "Left", 0x25, "Right", 0x27,
        "F1", 0x70, "F2", 0x71, "F3", 0x72, "F4", 0x73, "F5", 0x74,
        "F6", 0x75, "F7", 0x76, "F8", 0x77, "F9", 0x78, "F10", 0x79,
        "Ctrl+C", "CtrlC", "Ctrl+V", "CtrlV", "Alt+Tab", "AltTab"
    )
    return map.Get(key, 0)
}
 
; === 配置管理 ===
UpdateConfigFromGUI() {
    global Config, GuiControls
     
    ; 保存当前配置
    Config["targetHwnd"] := GuiControls["hwndEdit"].Value
    Config["targetTitle"] := GuiControls["titleEdit"].Value
    Config["targetClass"] := GuiControls["classEdit"].Value
    Config["keyToSend1"] := GuiControls["keyEdit1"].Value
    Config["keyToSend2"] := GuiControls["keyEdit2"].Value
    Config["keyToSend3"] := GuiControls["keyEdit3"].Value
    Config["keyToSend4"] := GuiControls["keyEdit4"].Value
    Config["keyToSend5"] := GuiControls["keyEdit5"].Value
    Config["sendMethod"] := GuiControls["methodDDL"].Text
     
    ; 处理按键间隔
    Config["interval1"] := ValidateInterval(GuiControls["intervalEdit1"].Value, 1)
    Config["interval2"] := ValidateInterval(GuiControls["intervalEdit2"].Value, 2)
    Config["interval3"] := ValidateInterval(GuiControls["intervalEdit3"].Value, 3)
    Config["interval4"] := ValidateInterval(GuiControls["intervalEdit4"].Value, 4)
    Config["interval5"] := ValidateInterval(GuiControls["intervalEdit5"].Value, 5)
}
 
; 验证间隔时间
ValidateInterval(value, keyNum) {
    try {
        interval := Integer(value)
        if (interval >= 50 && interval <= 5000) {
            return interval
        }
    } catch {
        ; 捕获转换错误
    }
     
    ; 无效值重置为默认
    defaultIntervals := [500, 1000, 1500, 2000, 2500]
    defaultInterval := defaultIntervals[keyNum-1]
     
    GuiControls["intervalEdit" . keyNum].Value := defaultInterval
    UpdateStatus("警告: 按键" keyNum "间隔无效,已重置为" defaultInterval "ms")
    return defaultInterval
}
 
SaveConfig(*) {
    global Config, GuiControls
     
    ; 更新配置
    UpdateConfigFromGUI()
     
    ; 保存到INI文件
    IniWrite(Config["targetHwnd"], "SendKeys.ini", "Config", "targetHwnd")
    IniWrite(Config["targetTitle"], "SendKeys.ini", "Config", "targetTitle")
    IniWrite(Config["targetClass"], "SendKeys.ini", "Config", "targetClass")
    IniWrite(Config["keyToSend1"], "SendKeys.ini", "Config", "keyToSend1")
    IniWrite(Config["keyToSend2"], "SendKeys.ini", "Config", "keyToSend2")
    IniWrite(Config["keyToSend3"], "SendKeys.ini", "Config", "keyToSend3")
    IniWrite(Config["keyToSend4"], "SendKeys.ini", "Config", "keyToSend4")
    IniWrite(Config["keyToSend5"], "SendKeys.ini", "Config", "keyToSend5")
    IniWrite(Config["interval1"], "SendKeys.ini", "Config", "interval1")
    IniWrite(Config["interval2"], "SendKeys.ini", "Config", "interval2")
    IniWrite(Config["interval3"], "SendKeys.ini", "Config", "interval3")
    IniWrite(Config["interval4"], "SendKeys.ini", "Config", "interval4")
    IniWrite(Config["interval5"], "SendKeys.ini", "Config", "interval5")
    IniWrite(Config["sendMethod"], "SendKeys.ini", "Config", "sendMethod")
     
    UpdateStatus("配置已保存!")
}
 
LoadConfig() {
    global Config
     
    ; 从INI文件加载
    if (FileExist("SendKeys.ini")) {
        Config["targetHwnd"] := IniRead("SendKeys.ini", "Config", "targetHwnd", 0)
        Config["targetTitle"] := IniRead("SendKeys.ini", "Config", "targetTitle", "")
        Config["targetClass"] := IniRead("SendKeys.ini", "Config", "targetClass", "")
        Config["keyToSend1"] := IniRead("SendKeys.ini", "Config", "keyToSend1", "1")
        Config["keyToSend2"] := IniRead("SendKeys.ini", "Config", "keyToSend2", "")
        Config["keyToSend3"] := IniRead("SendKeys.ini", "Config", "keyToSend3", "")
        Config["keyToSend4"] := IniRead("SendKeys.ini", "Config", "keyToSend4", "")
        Config["keyToSend5"] := IniRead("SendKeys.ini", "Config", "keyToSend5", "")
        Config["interval1"] := IniRead("SendKeys.ini", "Config", "interval1", 500)
        Config["interval2"] := IniRead("SendKeys.ini", "Config", "interval2", 1000)
        Config["interval3"] := IniRead("SendKeys.ini", "Config", "interval3", 1500)
        Config["interval4"] := IniRead("SendKeys.ini", "Config", "interval4", 2000)
        Config["interval5"] := IniRead("SendKeys.ini", "Config", "interval5", 2500)
        Config["sendMethod"] := IniRead("SendKeys.ini", "Config", "sendMethod", "ControlSend")
    }
}
 
; === 实用函数 ===
UpdateStatus(message := "") {
    global GuiControls, KeyThreads, Config
    if (message != "") {
        GuiControls["statusText"].Value := message
        return
    }
     
    ; 构建多线程状态信息
    status := ""
    status .= "按键1: " (KeyThreads["key1"]["running"] ? "运行中 (" Config["interval1"] "ms)" : "停止") "`n"
    status .= "按键2: " (KeyThreads["key2"]["running"] ? "运行中 (" Config["interval2"] "ms)" : "停止") "`n"
    status .= "按键3: " (KeyThreads["key3"]["running"] ? "运行中 (" Config["interval3"] "ms)" : "停止") "`n"
    status .= "按键4: " (KeyThreads["key4"]["running"] ? "运行中 (" Config["interval4"] "ms)" : "停止") "`n"
    status .= "按键5: " (KeyThreads["key5"]["running"] ? "运行中 (" Config["interval5"] "ms)" : "停止")
     
    GuiControls["statusText"].Value := status
}
 
LogAction(message) {
    global Config
    if (Config["debug"]) {
        FileAppend FormatTime(, "yyyy-MM-dd HH:mm:ss") " - " message "`n", "SendKeys.log"
    }
}
 
GuiClose(*) {
    ; 停止所有线程
    StopAllThreads()
    Sleep 100
    ExitApp
}
 
; === 启动 ===
LoadConfig()
CreateGUI()

下载地址
https://pan.baidu.com/s/1uCLC64C7Nm1PQ18JRS-nWg?pwd=mc63 提取码: mc63
https://pan.quark.cn/s/43661ec4217d

转载自
https://www.52pojie.cn/thread-2039403-1-1.html

未经允许不得转载:今夕资源网 » 多线程独立按键后台发送工具 (五按键版) v5.0 附带AHK源码
扫二维码手机阅读本页
赞(0)

评论抢沙发

评论前必须登录!