给 AutoHotkey 添加通用的批量输入 Gui(代替inputbox)

写脚本中不可避免需要很多用户输入的情况,自带的inputbox只支持一项输入,不断地弹框输入体验太差,
而每次要输入的需求不统一,总是写gui代码更麻烦,

于是想着写个通用的批量输入的Gui,每次只要传入一个二维数组即可

例子如下:

arr2 := [
 ["姓名", "name", "hy"],
 ["性别", "gender", ["男","女"], 2],
 ["年龄", "age", "20", "n"],
 ["是否党员", "dangyuan", 0, "b"],
 ["备注", "beizhu", "", "2"],
]
objOpt := hyf_inputOption(arr2, "提示")
msgbox(json.stringify(objOpt, 4))

每行的数组都代表1个输入值的定义,见下方源代码说明

运行后效果如图:

image

返回值为一个以变量名keymap

{
    "age": 20,
    "beizhu": "text",
    "dangyuan": 0,
    "gender": "女",
    "name": "hy"
}

附上 AutoHotkey v2-beta 代码

;arr2的子数组各项说明:
;   1.提示文字
;   2.变量名
;   3.默认值|数据范围(可选)
;      数组,则为 ComboBox
;   4.opt(可选)
;      "n" Edit只能输入数字,返回为数字类型
;      "f" Edit为浮点数
;      "b" 是否的 Checkbox
;      数字 多行Edit|ComboBox的默认项
;   5.focus和disable
;      focus 默认控件
;      0 禁用(用得少)
;bOne 表示限制单结果,则会在 Edit内容改变时,清空其他控件
*/
hyf_inputOption(arr2, title:="", bTrim:=false, bOne:=false) {
    if (arr2 is map) {
        for k, v in arr2.clone()
            arr2.push([k,k,v])
    }
    oGui := gui("+resize +AlwaysOnTop +Border +LastFound +ToolWindow")
    if (title != "")
        oGui.title := title
    oGui.OnEvent("escape", doEscape)
    oGui.OnEvent("close", doEscape)
    oGui.SetFont("cRed s22")
    oGui.SetFont("cDefault s11")
    funOpt := (x,w:=600)=>format("ys v{1} w{2}", x,w) ;默认宽
    focusCtl := ""
    for arr in arr2 {
        oGui.AddText("x10 section", arr[1])
        if (arr.length >= 5 && arr[5]==0)
            continue
        varName := arr[2]
        ;设置 opt
        ctl := ""
        if (arr.length >= 3) {
            if (arr[3] is array) {
                ctl := "ComboBox"
                lMax := max(arr[3].map(x=>strlen(x))*)
                opt := funOpt(varName, max(lMax*30, 50))
                if (arr.length >= 4)
                    opt .= format(" choose{1}", arr[4])
            } else if (arr.length>=4 && arr[4] == "b") { ;boolean
                ctl := "Checkbox"
                opt := funOpt(varName, 100)
            }
        }
        ;其他为Edit
        if (ctl == "") {
            ctl := "Edit"
            opt := funOpt(varName)
            if (arr.length >= 4) {
                switch arr[4] {
                    case "n","f": ;限制为数字
                        opt .= " number"
                    default:
                        if (arr[4] is integer)
                            opt .= format(" r{1}", arr[4])
                }
            }
        }
        switch ctl {
            case "ComboBox":
                oGui.AddComboBox(opt, arr[3])
            case "Checkbox":
                oGui.SetFont("cRed")
                if (arr[3])
                    opt .= " checked"
                oGui.AddCheckbox(opt)
                oGui.SetFont("cDefault")
            case "Edit":
                if (arr.length >= 3 && arr[3] != "")
                    oGui.AddEdit(opt, arr[3]).OnEvent("change", editChange)
                else
                    oGui.AddEdit(opt).OnEvent("change", editChange)
        }
        ;默认激活字段
        if (arr.length >= 5 && arr[5]=="focus")
            focusCtl := varName
    }
    oBtn := oGui.AddButton("default center", "确定")
    oBtn.OnEvent("click", btnClick)
    if (focusCtl != "") {
        oGui[focusCtl].focus()
    }
    objRes := map() ;空白值不返回
    objRes.default := ""
    oGui.show()
    WinWaitClose(oGui)
    return objRes
    editChange(ctl, p*) {
        if (bOne) {
            for hwnd, ctlLoop in ctl.gui {
                if (ctlLoop.ClassNN ~= "^Edit\d+$" && hwnd != ctl.hwnd)
                    ctlLoop.text := ""
            }
        }
    }
    btnClick(ctl, p*) {
        o := ctl.gui.submit()
        ;msgbox(type(o) . "`n" . json.stringify(hyf_props(o), 4))
        for arr in arr2 {
            v := o[arr[2]]
            ;记录
            if (v != "") { ;过滤空值
                ;输出结果二次加工
                if (bTrim)
                    v := trim(v) ;TODO 是否trim(比如每行前加"- "转成无序列表)
                if (arr.length >=4 && arr[4]~="n|f")
                    objRes[arr[2]] := number(v)
                else
                    objRes[arr[2]] := v
            }
        }
        ctl.gui.destroy()
    }
    doEscape(oGui, p*) => oGui.destroy()
}

arr2 := [
 ["姓名", "name", "hy"],
 ["性别", "gender", ["男","女"], 2],
 ["年龄", "age", "20", "n"],
 ["是否党员", "dangyuan", 0, "b"],
 ["备注", "beizhu", "", "2"],
]
posted @ 2022-01-06 23:01  火冷  阅读(921)  评论(0编辑  收藏  举报