;多级字符输入菜单 by Thinkai @2014-09-23 EscapeChar := "`t" ;菜单分隔符。不建议用中文字符,可能会导致显示错误。默认为“,” ;加载文件到数组 SplashTextOn, 100, 40, 提示, 加载中 q := file_menu_2_obj("q.txt") w := file_menu_2_obj("w.txt") e := file_menu_2_obj("e.txt") t := file_menu_2_obj("t.txt") SplashTextOff Return ;写你的热键并调用函数 ::c:: ;复制时注意改 #e:: ;复制时注意改 menu = e ;复制时注意改 if (!show_%menu%) TrayTip, 提示, 加载中 show_%menu% := show_%menu% ? show_menu(menu) 1 : create_menu(e,menu,,1) 1 TrayTip return ;增加一个显示函数 show_menu(menu){ menu, %menu%, Show } file_menu_2_obj(file){ ;加载菜单文件到数组 if !file { MsgBox, 4112, 错误, 文件%file%不存在! return "Error:No file" } Else { FileRead, content, %file% Return csv2obj(content) } } csv2obj(string){ ;csv分隔符格式文本转object函数 obj := Object() ;初始化 StringReplace, string, string, `r, , All ;去回车 StringSplit, var, string, `n ;按行分割 Loop % var0 ;循环读取 { tmp_line := var%A_Index% ;赋值临时行 if tmp_line { tmp_obj := string_2_obj(tmp_line) ;文本转object函数 obj := combine_obj(tmp_obj,obj) ;合并数组 } } return obj } ;文本转object函数 string_2_obj(string){ ;全局分隔符 global EscapeChar if (!EscapeChar) EscapeChar = , obj := object() ;初始化 StringSplit, var, string, %EscapeChar% ;按分隔符分割 if var0 > 1 { ;下级成为上级的一个key Loop % var0-1 { index := var0-A_index index2 := index+1 obj%index% := object() obj%index%[var%index2%] := 0 } ;下级数组成为上级数组的一个key Loop % var0-2 { index := var0-A_index-1 index2 := index+1 obj%index%[var%index2%] := obj%index2% } ;定义根数组 obj[var1] := obj1 return obj } Else { ;只有一个值 obj[var1] := 0 return obj } } combine_obj(obj1,obj2){ ;联合数组函数 for k,v in obj1 { if obj2[k] ;两个数组有相同键 { if (isobject(obj1[k]) && isobject(obj2[k])) ;都是数组 合并 obj2[k] := combine_obj(obj1[k],obj2[k]) Else if (isobject(obj1[k]) && !isobject(obj2[k])) ; 数组2的相应键不是数组 赋值为数组1的对应键 obj2[k] := obj1[k] } Else { obj2[k] := v ;数组2没有该键 添加 } } Return obj2 } create_menu(obj,menu_name:="main",index:=1,mainmenu:=0){ ;创建并显示菜单函数 keys := ["",1,2,3,4,5,6,7,8,9,0,"a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"] ;创建主菜单 Menu, % menu_name, add, Menu, % menu_name, DeleteAll ;枚举数组 for k,v in obj { index += 1 ;如果该项是数组 if (IsObject(v)) { submenu_name = %menu_name%_%k% ;定义子菜单菜单名 ;预创建子菜单 不然报错 Menu, % submenu_name, add, Menu, % submenu_name, DeleteAll ;添加子菜单 Menu, % menu_name, add, % k ? "(&" keys[index] ") " k : "", :%submenu_name% create_menu(v,submenu_name) } Else { ;单独项 Menu, % menu_name, add, % k ? "(&" keys[index] ") " k : "", MenuHandler } } ;如果是根菜单,显示它 if mainmenu = 1 menu,% menu_name, show } MenuHandler: ;点击菜单句柄 ;转存剪切板 直接粘贴 支持中文 clip := ClipboardAll ;发送括号后面的内容 ;应jem要求加入父级 StringSplit, father, A_ThisMenu, _ father = % father%father0% current := RegExReplace(A_ThisMenuItem,"(.*)s*(.*)","$1") result := father0>2 ? father "/" current : current StringReplace, result, result, `r, , All Clipboard := result Send, ^v ;加等待时间 以防部分程序反应慢获取到原剪切板数据 Sleep,200 Clipboard := clip return