#NoEnv FileSelectFile, jfile, S, , 请选择json文件, json文件(*.*) if !jfile ExitApp FileRead, str, %jfile% menu := json_toobj(str) for k,v in menu { tabs .= tabs ? "|" k : k } Gui, Add, text, x0 y0 w80 h20, 分类(可输入) gui, add, ComboBox, x80 y0 w320 vid gchange_tab, % tabs Gui, Add, text, x0 y20 w40 h20, 名称 gui, add, edit, x40 y20 w360 h20 vname, Gui, Add, text, x0 y40 w40 h20, 命令 gui, add, edit, x40 y40 w320 h20 vpath, gui, add, button, x360 y40 w40 h20 gsf, 浏览 Gui, Add, text, x0 y60 w40 h20, 图标 gui, add, edit, x40 y60 w320 h20 vicon, gui, add, button, x360 y60 w40 h20 gsi, 浏览 Gui, Add, text, x0 y80 w40 h20, 窗口 gui, add, edit, x40 y80 w360 h20 vwin, Gui, Add, text, x0 y100 w40 h20, 版本 gui, add, edit, x40 y100 w360 h20 vversion, Gui, Add, text, x0 y120 w200 h20, 更新方式(i安装/c覆盖主程序) gui, add, DropDownList, x200 y120 w200 vupdate_way,c|i Gui, Add, text, x0 y140 w40 h20, URL gui, add, edit, x40 y140 w360 h20 vurl, Gui, add, button, x0 y160 w200 h20 gadd, 添加 Gui, add, button, x200 y160 w200 h20 gdel, 删除选中项 Gui, add, button, x0 y180 w200 h20 gchange, 修改选中项 Gui, add, button, x200 y180 w200 h20 gsavechange, 保存修改 Gui, add, ListView, x0 y200 w400 h200 vlv, ID|名称|版本|命令|图标|窗口|升级方式|升级URL Gui, add, button, x0 y400 w400 h20 gsave, 保存文件 Gui, Show, , JSON快速启动菜单配套编辑工具 GuiControl, Choose, id, 1 GuiControlGet, id show_lv(menu[id]) return change_tab: GuiControlGet, id show_lv(menu[id]) GuiControl, , name, GuiControl, , icon, GuiControl, , path, GuiControl, , version, GuiControl, , url, GuiControl, , win, GuiControl, Choose, update_way, 0 Return sf: FileSelectFile, file, , , 选择程序, (*.exe) GuiControl, , path, %file% Return si: FileSelectFile, file, , , 选择图标, (*.exe;*.ico) GuiControl, , icon, %file% Return show_lv(obj){ LV_Delete() rid=0 for k,v in obj { rid++ LV_Add("",rid,v["name"],v["version"],v["path"],v["icon"],v["win"],v["update_way"],v["url"]) } LV_ModifyCol() } add: Gui, Submit, NoHide if !isobject(menu[id]) menu[id] := {} menu[id].insert({name:name,icon:icon,path:path,url:url,version:version,win:win,update_way:update_way}) GuiControl, , name, GuiControl, , icon, GuiControl, , path, GuiControl, , version, GuiControl, , url, GuiControl, , win, GuiControl, Choose, update_way, 0 show_lv(menu[id]) Return del: FocusedRowNumber := LV_GetNext(0, "F") if not FocusedRowNumber { MsgBox, 4144, 提示, 您未选择任何已添加菜单数据! Return } LV_GetText(rid, FocusedRowNumber, 1) GuiControlGet, id menu[id].Remove(rid) show_lv(menu[id]) Return change: FocusedRowNumber := LV_GetNext(0, "F") if not FocusedRowNumber { MsgBox, 4144, 提示, 您未选择任何已添加菜单数据! Return } LV_GetText(rid, FocusedRowNumber, 1) GuiControlGet, id GuiControl, , name, % menu[id][rid]["name"] GuiControl, , icon, % menu[id][rid]["icon"] GuiControl, , path, % menu[id][rid]["path"] GuiControl, , version, % menu[id][rid]["version"] GuiControl, , url, % menu[id][rid]["url"] GuiControl, , win, % menu[id][rid]["win"] if (menu[id][rid]["update_way"]="c") GuiControl, Choose, update_way, 1 Else GuiControl, Choose, update_way, 2 Return savechange: Gui, Submit, NoHide if !isobject(menu[id]) menu[id] := {} menu[id][rid] := {name:name,icon:icon,path:path,url:url,version:version,win:win,update_way:update_way} show_lv(menu[id]) GuiControl, , name, GuiControl, , icon, GuiControl, , path, GuiControl, , version, GuiControl, , url, GuiControl, Choose, update_way, 0 Return save: FileDelete, %jfile% FileAppend, % json_fromobj(menu), %jfile% MsgBox, 64, 提示, 已保存! Return GuiClose: ExitApp json_fromobj( obj ) { If IsObject( obj ) { isarray := 0 ; an empty object could be an array... but it ain't, says I for key in obj if ( key != ++isarray ) { isarray := 0 Break } for key, val in obj str .= ( A_Index = 1 ? "" : "," ) ( isarray ? "" : json_fromObj( key ) ":" ) json_fromObj( val ) return isarray ? "[" str "]" : "{" str "}" } else if obj IS NUMBER return obj ; else if obj IN null,true,false ; AutoHotkey does not natively distinguish these ; return obj ; Encode control characters, starting with backslash. StringReplace, obj, obj, , \, A StringReplace, obj, obj, % Chr(08), b, A StringReplace, obj, obj, % A_Tab, t, A StringReplace, obj, obj, `n, n, A StringReplace, obj, obj, % Chr(12), f, A StringReplace, obj, obj, `r, r, A StringReplace, obj, obj, ", ", A StringReplace, obj, obj, /, /, A While RegexMatch( obj, "[^x20-x7e]", key ) { str := Asc( key ) val := "u" . Chr( ( ( str >> 12 ) & 15 ) + ( ( ( str >> 12 ) & 15 ) > 8 ) & 15 ) + ( ( ( str >> 8 ) & 15 ) > 4 ) & 15 ) + ( ( ( str >> 4 ) & 15 ) 1 } ; Loop Parse, str, % "[{" If !--nest Break ; Insert the newly closed object into the one on top of the stack, then pop the stack pbj := obj obj := objs.remove() obj[key := keys.remove()] := pbj If ( isarray := isarrays.remove() ) key++ } ; Loop Parse, str, % "]}" Return obj } ;调试用的显示数组的函数 show_obj(obj,menu_name:=""){ static id if menu_name = { main = 1 id++ menu_name := id } Menu, % menu_name, add, Menu, % menu_name, DeleteAll for k,v in obj { if (IsObject(v)) { id++ submenu_name := id Menu, % submenu_name, add, Menu, % submenu_name, DeleteAll Menu, % menu_name, add, % k ? "【" k "】[obj]" : "", :%submenu_name% show_obj(v,submenu_name) } Else { Menu, % menu_name, add, % k ? "【" k "】" v: "", MenuHandler } } if main = 1 menu,% menu_name, show } MenuHandler: return
远端JSON快速菜单配套编辑工具
#NoEnv FileSelectFile, jfile, S, , 请选择json文件, json文件(*.*) if !jfile ExitApp FileRead, str, %jfile% menu := json_toobj(str) for k,v in menu { tabs .= tabs ? "|" k : k } Gui, Add, text, x0 y0 w80 h20, 分类(可输入) gui, add, ComboBox, x80 y0 w320 vid gchange_tab, % tabs Gui, Add, text, x0 y20 w40 h20, 名称 gui, add, edit, x40 y20 w360 h20 vname, Gui, Add, text, x0 y40 w40 h20, 命令 gui, add, edit, x40 y40 w320 h20 vpath, gui, add, button, x360 y40 w40 h20 gsf, 浏览 Gui, Add, text, x0 y60 w40 h20, 图标 gui, add, edit, x40 y60 w320 h20 vicon, gui, add, button, x360 y60 w40 h20 gsi, 浏览 Gui, Add, text, x0 y80 w40 h20, 窗口 gui, add, edit, x40 y80 w360 h20 vwin, Gui, Add, text, x0 y100 w40 h20, 版本 gui, add, edit, x40 y100 w360 h20 vversion, Gui, Add, text, x0 y120 w200 h20, 更新方式(i安装/c覆盖主程序) gui, add, DropDownList, x200 y120 w200 vupdate_way,c|i Gui, Add, text, x0 y140 w40 h20, URL gui, add, edit, x40 y140 w360 h20 vurl, Gui, add, button, x0 y160 w200 h20 gadd, 添加 Gui, add, button, x200 y160 w200 h20 gdel, 删除选中项 Gui, add, button, x0 y180 w200 h20 gchange, 修改选中项 Gui, add, button, x200 y180 w200 h20 gsavechange, 保存修改 Gui, add, ListView, x0 y200 w400 h200 vlv, ID|名称|版本|命令|图标|窗口|升级方式|升级URL Gui, add, button, x0 y400 w400 h20 gsave, 保存文件 Gui, Show, , JSON快速启动菜单配套编辑工具 GuiControl, Choose, id, 1 GuiControlGet, id show_lv(menu[id]) return change_tab: GuiControlGet, id show_lv(menu[id]) GuiControl, , name, GuiControl, , icon, GuiControl, , path, GuiControl, , version, GuiControl, , url, GuiControl, , win, GuiControl, Choose, update_way, 0 Return sf: FileSelectFile, file, , , 选择程序, (*.exe) GuiControl, , path, %file% Return si: FileSelectFile, file, , , 选择图标, (*.exe;*.ico) GuiControl, , icon, %file% Return show_lv(obj){ LV_Delete() rid=0 for k,v in obj { rid++ LV_Add("",rid,v["name"],v["version"],v["path"],v["icon"],v["win"],v["update_way"],v["url"]) } LV_ModifyCol() } add: Gui, Submit, NoHide if !isobject(menu[id]) menu[id] := {} menu[id].insert({name:name,icon:icon,path:path,url:url,version:version,win:win,update_way:update_way}) GuiControl, , name, GuiControl, , icon, GuiControl, , path, GuiControl, , version, GuiControl, , url, GuiControl, , win, GuiControl, Choose, update_way, 0 show_lv(menu[id]) Return del: FocusedRowNumber := LV_GetNext(0, "F") if not FocusedRowNumber { MsgBox, 4144, 提示, 您未选择任何已添加菜单数据! Return } LV_GetText(rid, FocusedRowNumber, 1) GuiControlGet, id menu[id].Remove(rid) show_lv(menu[id]) Return change: FocusedRowNumber := LV_GetNext(0, "F") if not FocusedRowNumber { MsgBox, 4144, 提示, 您未选择任何已添加菜单数据! Return } LV_GetText(rid, FocusedRowNumber, 1) GuiControlGet, id GuiControl, , name, % menu[id][rid]["name"] GuiControl, , icon, % menu[id][rid]["icon"] GuiControl, , path, % menu[id][rid]["path"] GuiControl, , version, % menu[id][rid]["version"] GuiControl, , url, % menu[id][rid]["url"] GuiControl, , win, % menu[id][rid]["win"] if (menu[id][rid]["update_way"]="c") GuiControl, Choose, update_way, 1 Else GuiControl, Choose, update_way, 2 Return savechange: Gui, Submit, NoHide if !isobject(menu[id]) menu[id] := {} menu[id][rid] := {name:name,icon:icon,path:path,url:url,version:version,win:win,update_way:update_way} show_lv(menu[id]) GuiControl, , name, GuiControl, , icon, GuiControl, , path, GuiControl, , version, GuiControl, , url, GuiControl, Choose, update_way, 0 Return save: FileDelete, %jfile% FileAppend, % json_fromobj(menu), %jfile% MsgBox, 64, 提示, 已保存! Return GuiClose: ExitApp json_fromobj( obj ) { If IsObject( obj ) { isarray := 0 ; an empty object could be an array... but it ain't, says I for key in obj if ( key != ++isarray ) { isarray := 0 Break } for key, val in obj str .= ( A_Index = 1 ? "" : "," ) ( isarray ? "" : json_fromObj( key ) ":" ) json_fromObj( val ) return isarray ? "[" str "]" : "{" str "}" } else if obj IS NUMBER return obj ; else if obj IN null,true,false ; AutoHotkey does not natively distinguish these ; return obj ; Encode control characters, starting with backslash. StringReplace, obj, obj, , \, A StringReplace, obj, obj, % Chr(08), b, A StringReplace, obj, obj, % A_Tab, t, A StringReplace, obj, obj, `n, n, A StringReplace, obj, obj, % Chr(12), f, A StringReplace, obj, obj, `r, r, A StringReplace, obj, obj, ", ", A StringReplace, obj, obj, /, /, A While RegexMatch( obj, "[^x20-x7e]", key ) { str := Asc( key ) val := "u" . Chr( ( ( str >> 12 ) & 15 ) + ( ( ( str >> 12 ) & 15 ) > 8 ) & 15 ) + ( ( ( str >> 8 ) & 15 ) > 4 ) & 15 ) + ( ( ( str >> 4 ) & 15 ) 1 } ; Loop Parse, str, % "[{" If !--nest Break ; Insert the newly closed object into the one on top of the stack, then pop the stack pbj := obj obj := objs.remove() obj[key := keys.remove()] := pbj If ( isarray := isarrays.remove() ) key++ } ; Loop Parse, str, % "]}" Return obj } ;调试用的显示数组的函数 show_obj(obj,menu_name:=""){ static id if menu_name = { main = 1 id++ menu_name := id } Menu, % menu_name, add, Menu, % menu_name, DeleteAll for k,v in obj { if (IsObject(v)) { id++ submenu_name := id Menu, % submenu_name, add, Menu, % submenu_name, DeleteAll Menu, % menu_name, add, % k ? "【" k "】[obj]" : "", :%submenu_name% show_obj(v,submenu_name) } Else { Menu, % menu_name, add, % k ? "【" k "】" v: "", MenuHandler } } if main = 1 menu,% menu_name, show } MenuHandler: return