ahk实现自动根据程序自动切换输入法!
使用方法
首先鼠标在行上右键选择输入法
在选择行前复选框启用次窗口配置
源码分享
;操作系统: Winxp ;作者: 小猛<skc2015@163.com> ;脚本说明: 根据程序设置输入法 ;脚本版本: 2014年7月30日12:25:20 AHKCN群修正版 #Persistent #SingleInstance force Menu, Tray, Click, 1 Menu, Tray, Tip, By,小死猛 Menu, Tray, Add, By,小死猛, Menu_Show Menu, Tray, Add, 反馈更新, Menu_Tray_Feedback Menu, Tray, Add, 使用说明, Menu_Tray_illustrate Menu, Tray, Add, 版本信息, Menu_Tray_Version Menu, Tray, Add, 清空配置, Menu_Tray_Empty Menu, Tray, Add, 重启脚本, Menu_Tray_Reload Menu, Tray, Add, 退出脚本, Menu_Tray_Exit Menu, Tray, Default, By,小死猛 Menu, tray, NoStandard Gui, Add, Hotkey, Limit1 vChosenHotkey gMySubroutine w60 Gui, Add, Text, +y10 ,设置程序为配置输入法 Gui, Add, ListView, AltSubmit Checked -HScroll r14 x10 w208 vMyListView gMyListView ,进程名|输入状态|编号|路径| IniRead, ChosenHotkey, %A_WorkingDir%\其他配置.ini, 热键, key if ChosenHotkey is alpha { } else { Hotkey, %ChosenHotkey%, MyLabel GuiControl,, ChosenHotkey,%ChosenHotkey% } ImageListID1 := IL_Create(10) ImageListID2 := IL_Create(10, 10, true) ; 大图标列表和小图标列表. ; 关联图像列表到 ListView, 然而它就可以显示图标了: LV_SetImageList(ImageListID1) LV_SetImageList(ImageListID2) Gui, Add, Button, gMshiqh vMshiqh,开启自动模式 Gui, Add, Button, x+10 gTxck,更新程序到列表 Gui +LastFound +AlwaysOnTop -Caption +ToolWindow ; +ToolWindow 避免显示任务栏按钮和 WinSet, TransColor, EEAA99 230, %WindowColor% Gui,Show, ,输入法配置 GuiControl, -Redraw, MyListView ;;;;;;;;;;;;;创建ListView内容;;;;;;;;;;;;; Txck: sfi_size := A_PtrSize + 8 + (A_IsUnicode ? 680 : 340) VarSetCapacity(sfi, sfi_size) LV_Delete() WinGet, WinList, list,,, Program Manager WinAll:= Object() WinAll.Conut:=WinList loop,%WinList% { id:=WinList%A_Index% WinGet, win_ex, ProcessName, ahk_id %id%, StringReplace, win_exe, win_ex,.exe , , WinGet, win_cklj, ProcessPath , ahk_id %id%, if (win_exe = win_cf) { continue } win_cf = %win_exe% loop ;排除配置中进程被添加 { IniRead, win_dq, %A_WorkingDir%\设定.ini, 用户配置, %A_Index% if win_dq = ERROR { break } if (win_dq = win_exe) ;在列表中出现 告诉下面删除新创建的行 { sbs = shac } } if not DllCall("Shell32\SHGetFileInfo" . (A_IsUnicode ? "W":"A"), "str", win_cklj , "uint", 0, "ptr", &sfi, "uint", sfi_size, "uint", 0x101) ; 0x101 为 SHGFI_ICON+SHGFI_SMALLICON IconNumber = 9999999 ; 把它设置到范围外来显示空图标. else ; 成功加载图标. { ; 从结构中提取 hIcon 成员: hIcon := NumGet(sfi, 0) ; 直接添加 HICON 到小图标和大图标列表. ; 下面加上 1 来把返回的索引从基于零转换到基于一: IconNumber := DllCall("ImageList_ReplaceIcon", "ptr", ImageListID1, "int", -1, "ptr", hIcon) + 1 DllCall("ImageList_ReplaceIcon", "ptr", ImageListID2, "int", -1, "ptr", hIcon) ; 现在已经把它复制到图像列表, 所以应销毁原来的: DllCall("DestroyIcon", "ptr", hIcon) ; 缓存图标来节省内存并提升加载性能: IconArray%ExtID% := IconNumber } LV_Add("Icon" . IconNumber ,win_exe,,,win_cklj) if sbs = shac { RowNumber := LV_GetCount() LV_Delete(RowNumber) } sbs = } ;;;;;;;;;;;;;添加配置文件设置;;;;;;;;;;;;; loop { IniRead, win_exe, %A_WorkingDir%\设定.ini, 用户配置, %A_Index% if win_exe = ERROR { break } IniRead, win_exe, %A_WorkingDir%\设定.ini, %win_exe%, 进程 IniRead, win_zt, %A_WorkingDir%\设定.ini, %win_exe%, 状态 IniRead, win_bh, %A_WorkingDir%\设定.ini, %win_exe%, 编号 IniRead, win_cklj, %A_WorkingDir%\设定.ini, %win_exe%, 路径 if not DllCall("Shell32\SHGetFileInfo" . (A_IsUnicode ? "W":"A"), "str", win_cklj , "uint", 0, "ptr", &sfi, "uint", sfi_size, "uint", 0x101) ; 0x101 为 SHGFI_ICON+SHGFI_SMALLICON IconNumber = 9999999 ; 把它设置到范围外来显示空图标. else ; 成功加载图标. { ; 从结构中提取 hIcon 成员: hIcon := NumGet(sfi, 0) ; 直接添加 HICON 到小图标和大图标列表. ; 下面加上 1 来把返回的索引从基于零转换到基于一: IconNumber := DllCall("ImageList_ReplaceIcon", "ptr", ImageListID1, "int", -1, "ptr", hIcon) + 1 DllCall("ImageList_ReplaceIcon", "ptr", ImageListID2, "int", -1, "ptr", hIcon) ; 现在已经把它复制到图像列表, 所以应销毁原来的: DllCall("DestroyIcon", "ptr", hIcon) ; 缓存图标来节省内存并提升加载性能: IconArray%ExtID% := IconNumber } LV_Add("Icon" . IconNumber ,win_exe,win_zt,win_bh,win_cklj) RowNumber := LV_GetCount() LV_Modify(RowNumber,"Check") } GuiControl, +Redraw, MyListView LV_ModifyCol(1,90) LV_ModifyCol(2,"SortDesc") LV_ModifyCol(2,108) LV_ModifyCol(3,0) LV_ModifyCol(4,0) ;;;;;;;;;;;;;创建右键输入法内容;;;;;;;;;;;;; HKLnum:=DllCall("GetKeyboardLayoutList","uint",0,"uint",0) VarSetCapacity( HKLlist, HKLnum*4, 0 ) DllCall("GetKeyboardLayoutList","uint",HKLnum,"uint",&HKLlist) loop,%HKLnum% { SetFormat, integer, hex HKL:=NumGet( HKLlist,(A_Index-1)*4 ) StringTrimLeft,Layout,HKL,2 Layout:= Layout=8040804 ? "00000804" : Layout Layout:= Layout=4090409 ? "00000409" : Layout RegRead,IMEName,HKEY_LOCAL_MACHINE,SYSTEM\CurrentControlSet\Control\Keyboard Layouts\%Layout%,Layout Text SetFormat, integer, D IniWrite, %Layout%, %A_WorkingDir%\其他配置.ini, %A_Index%, 编号 Menu, MyContextMenu, Add, %IMEName%,SubMenu } return MySubroutine: Sleep,1000 if ChosenHotkey is alpha { return } else { IniWrite, %ChosenHotkey%, %A_WorkingDir%\其他配置.ini, 热键, key Hotkey, %ChosenHotkey%, MyLabel } return ;;;;;;;;;;;;;快捷键切换输入法;;;;;;;;;;;;; MyLabel: WinGet, win_ex, ProcessName, A StringReplace, win_exe, win_ex,.exe , , loop % LV_GetCount() { RowNumber := LV_GetNext(RowNumber,"Checked") LV_GetText(win_cl, RowNumber, 1) if (win_cl = win_exe) { LV_GetText(Layout, RowNumber, 3) SwitchIME(Layout) return } } return Mshiqh: GuiControl,, mshiqh,已启动检测 loop { loop % LV_GetCount() ;循环次数为复选框被选中的数量 检查窗口是否有相对的输入法设置 { RowNumber := LV_GetNext(RowNumber,"Checked") ;RowNumber为选中复选框的行数 LV_GetText(win_exe, RowNumber, 1) ;获取选中复选框项目的第一列 WinGet, win_ex, ProcessName,A ;获取当前窗口的进程名 StringReplace, win_pc, win_ex,.exe , , ;对进程名排除.exe if (win_exe = win_pc) { LV_GetText(win_exe, RowNumber, 1) ;获取进程名相对的输入法编号并设置输入法 LV_GetText(Layout, RowNumber, 3) ;获取进程名相对的输入法编号并设置输入法 SwitchIME(Layout) WinWaitNotActive,ahk_exe %win_ex% ;等待这个窗口不活动 } } Sleep,100 } return MyListView: if A_GuiEvent = Normal { FileDelete,%A_WorkingDir%\设定.ini loop % LV_GetCount() { RowNumber := LV_GetNext(RowNumber,"Checked") if not RowNumber ; 上面返回零, 所以选择的行已经都找到了. break LV_GetText(win_exe, RowNumber, 1) LV_GetText(win_zt, RowNumber, 2) LV_GetText(win_bh, RowNumber, 3) LV_GetText(win_lj, RowNumber, 4) IniWrite, %win_exe%, %A_WorkingDir%\设定.ini, 用户配置, %A_Index% IniWrite, %win_exe%, %A_WorkingDir%\设定.ini, %win_exe%, 进程 IniWrite, %win_bh%, %A_WorkingDir%\设定.ini, %win_exe%, 编号 IniWrite, %win_zt%, %A_WorkingDir%\设定.ini, %win_exe%, 状态 IniWrite, %win_lj%, %A_WorkingDir%\设定.ini, %win_exe%, 路径 } } return GuiContextMenu: ;只在MyListView中显示菜单 ggwz := A_EventInfo if A_GuiControl <> MyListView return Menu, MyContextMenu, Show, %A_GuiX%, %A_GuiY% return Submenu: ;输入法配置菜单 IniRead, win_yys, %A_WorkingDir%\其他配置.ini,%A_ThisMenuItemPos%, 编号 ;写入输入法顺序 LV_Modify(ggwz, , ,A_ThisMenuItem ,win_yys) LV_ModifyCol(1,90) LV_ModifyCol(2,"SortDesc") LV_ModifyCol(2,108) LV_ModifyCol(3,0) LV_ModifyCol(4,0) return Menu_Show: IfWinExist, 输入法配置 { Gui, Cancel return } Gui,Show, , return Menu_Tray_Reload: Reload return Menu_Tray_Exit: ExitApp return Menu_Tray_Feedback: TrayTip,百度空间,https://hi.baidu.com/yan8023 , 10, 1 return Menu_Tray_illustrate: TrayTip, 说明, 首先鼠标在行上右键选择输入法`n在选择行前复选框启用次窗口配置, 10, 1 return Menu_Tray_Version: TrayTip,版本信息,内部修正版, 10,1 return Menu_Tray_Empty: FileDelete, %A_WorkingDir%\设定.ini FileDelete, %A_WorkingDir%\其他配置.ini GuiControl,, ChosenHotkey, TrayTip, 已删除, 配置文件:设定与其他配置, 10, 1 gosub, Txck return GuiClose: ; 用户关闭了窗口 ExitApp SeekIME(PN) { HKL:=DllCall("GetKeyboardLayout", "uint",GetThRead(), "uint") HKLnum:=DllCall("GetKeyboardLayoutList","uint",0,"uint",0) VarSetCapacity( HKLlist, HKLnum*4, 0 ) DllCall("GetKeyboardLayoutList","uint",HKLnum,"uint",&HKLlist) loop,%HKLnum% { if( NumGet( HKLlist, (A_Index-1)*4 ) = HKL ) { Index:= A_Index+PN Index:= Index=0 ? HKLnum : Index Index:= Index=HKLnum+1 ? 1 : Index ;~ ToolTip %Index% HKL:=NumGet( HKLlist,(Index-1)*4 ) break } } ControlGetFocus,ctl,A SendMessage,0x50,0,HKL,%ctl%,A } SwitchIME(dwLayout) { HKL:=DllCall("LoadKeyboardLayout", Str, dwLayout, UInt, 1) ControlGetFocus,ctl,A SendMessage,0x50,0,HKL,%ctl%,A } GetThread() { ResultID:=0 hWnd:=WinExist("A") VarSetCapacity( thE, 28, 0 ) NumPut( 28, thE ) WinGet,ProcessID,pid,ahk_id %hWnd% hProcessSnap := DllCall("CreateToolhelp32Snapshot","uint",4, "uint",ProcessID) if (DllCall("ThRead32First","uint",hProcessSnap, "uint",&thE )=0) { return 0 } loop { if (NumGet(thE,12) = ProcessID) { DllCall("CloseHandle","uint",hProcessSnap) ResultID:=NumGet(thE,8) return ResultID } NumPut( 28, thE ) if( DllCall("ThRead32Next","uint",hProcessSnap, "uint",&thE )=0) { DllCall("CloseHandle","uint",hProcessSnap) return 0 } } }
学习了