如何在AutoHotkey的Switch语句中使用4个以上Case制作DLL图标查看器
AutoHotkey DLL图标查看器:25个DLL循环切换问题解决
问题描述
我正在编写AutoHotkey脚本制作DLL图标查看器,需要用Switch-Case实现25个DLL文件的循环切换。目前脚本仅支持1-4个Case循环,推测问题出在Switch的运算逻辑上,但对这部分理解不足,求解决。
当前代码
^T:: Switch ++N := 0 N & 3 ; N = 1,2,3,4,1... { Case 1: DllPath := "C:\WINDOWS\SYSTEM32\accessibilitycpl.dll" Gui, Margin, 0, 0 Gui, +AlwaysOnTop -MinimizeBox -DPIScale +hwndGuiHwnd DllCall("uxtheme\SetWindowThemeAttribute", "ptr", GuiHwnd, "int", 1, "int64*", 6 | 6<<32, "uint", 8) Gui, Add, Button, w300 h50 gIconSizeToggle +Center, Toggle Icon Size Gui, Add, ListView, w300 h550 vListView +hwndListViewHwnd -0x4000 +LV0x10000 +0x8000, ACCESSIBILITYCPL DllCall("UxTheme.dll\SetWindowTheme", "Ptr", ListViewHwnd, "WStr", "Explorer", "Ptr", 0) LV_ModifyCol(1,279) GoSub, IconSizeToggle Gui Show, h600 w300, Dll icons Return Case 2: DllPath := "C:\WINDOWS\SYSTEM32\compstui.dll" Gui, Margin, 0, 0 Gui, +AlwaysOnTop -MinimizeBox -DPIScale +hwndGuiHwnd DllCall("uxtheme\SetWindowThemeAttribute", "ptr", GuiHwnd, "int", 1, "int64*", 6 | 6<<32, "uint", 8) Gui, Add, Button, w300 h50 gIconSizeToggle +Center, Toggle Icon Size Gui, Add, ListView, w300 h550 vListView +hwndListViewHwnd -0x4000 +LV0x10000 +0x8000, COMPSTUI.DLL DllCall("UxTheme.dll\SetWindowTheme", "Ptr", ListViewHwnd, "WStr", "Explorer", "Ptr", 0) LV_ModifyCol(1,279) GoSub, IconSizeToggle Gui Show, h600 w300, Dll icons Return Case 3: DllPath := "C:\WINDOWS\SYSTEM32\comres.dll" Gui, Margin, 0, 0 Gui, +AlwaysOnTop -MinimizeBox -DPIScale +hwndGuiHwnd DllCall("uxtheme\SetWindowThemeAttribute", "ptr", GuiHwnd, "int", 1, "int64*", 6 | 6<<32, "uint", 8) Gui, Add, Button, w300 h50 gIconSizeToggle +Center, Toggle Icon Size Gui, Add, ListView, w300 h550 vListView +hwndListViewHwnd -0x4000 +LV0x10000 +0x8000, COMRES.DLL DllCall("UxTheme.dll\SetWindowTheme", "Ptr", ListViewHwnd, "WStr", "Explorer", "Ptr", 0) LV_ModifyCol(1,279) GoSub, IconSizeToggle Gui Show, h600 w300, Dll icons Return Case 4: DllPath := "C:\WINDOWS\SYSTEM32\ddores.dll" Gui, Margin, 0, 0 Gui, +AlwaysOnTop -MinimizeBox -DPIScale +hwndGuiHwnd DllCall("uxtheme\SetWindowThemeAttribute", "ptr", GuiHwnd, "int", 1, "int64*", 6 | 6<<32, "uint", 8) Gui, Add, Button, w300 h50 gIconSizeToggle +Center, Toggle Icon Size Gui, Add, ListView, w300 h550 vListView +hwndListViewHwnd -0x4000 +LV0x10000 +0x8000, DDORES.DLL DllCall("UxTheme.dll\SetWindowTheme", "Ptr", ListViewHwnd, "WStr", "Explorer", "Ptr", 0) LV_ModifyCol(1,279) GoSub, IconSizeToggle Gui Show, h600 w300, Dll icons } Return IconSizeToggle: IconSize := !IconSize GuiControl, -Redraw, ListView LV_Delete() if (IconSize) ImageListID := IL_Create(1, 1, 1) else ImageListID := IL_Create() LV_SetImageList(ImageListID, 1) Loop { ; Populate the listview Check := IL_Add(ImageListID, DllPath, A_Index) if (Check != 0) { LV_Add("Icon" . A_Index, A_Index) } else Break } GuiControl, +Redraw, ListView Return
问题分析
- 循环计数逻辑错误:原代码中
Switch ++N := 0 N & 3的表达式逻辑混乱,N & 3是按位与操作,只会返回0-3的结果,对应Case1-4,这就是只能循环4个DLL的根本原因。 - 代码冗余严重:每个Case里都重复编写了完整的GUI创建、样式设置代码,后续添加25个DLL时会导致代码量暴增,维护困难。
- 未处理旧窗口:多次触发快捷键会创建多个重叠窗口,没有销毁之前的GUI实例。
解决方案
修改后的代码
Global N := 0, DllPath, ListViewTitle ^T:: ; 让N在1-25范围内循环递增 N := Mod(N, 25) + 1 Switch N { Case 1: DllPath := "C:\WINDOWS\SYSTEM32\accessibilitycpl.dll" ListViewTitle := "ACCESSIBILITYCPL" Case 2: DllPath := "C:\WINDOWS\SYSTEM32\compstui.dll" ListViewTitle := "COMPSTUI.DLL" Case 3: DllPath := "C:\WINDOWS\SYSTEM32\comres.dll" ListViewTitle := "COMRES.DLL" Case 4: DllPath := "C:\WINDOWS\SYSTEM32\ddores.dll" ListViewTitle := "DDORES.DLL" ; 在此处继续添加Case 5到Case 25的DLL路径和标题 ; Case 5: ; DllPath := "路径" ; ListViewTitle := "标题" ; ... } ; 公共GUI初始化逻辑,仅执行一次 Gui, Destroy ; 销毁旧窗口,避免叠加 Gui, Margin, 0, 0 Gui, +AlwaysOnTop -MinimizeBox -DPIScale +hwndGuiHwnd DllCall("uxtheme\SetWindowThemeAttribute", "ptr", GuiHwnd, "int", 1, "int64*", 6 | 6<<32, "uint", 8) Gui, Add, Button, w300 h50 gIconSizeToggle +Center, Toggle Icon Size Gui, Add, ListView, w300 h550 vListView +hwndListViewHwnd -0x4000 +LV0x10000 +0x8000, % ListViewTitle DllCall("UxTheme.dll\SetWindowTheme", "Ptr", ListViewHwnd, "WStr", "Explorer", "Ptr", 0) LV_ModifyCol(1,279) GoSub, IconSizeToggle Gui Show, h600 w300, Dll icons Return IconSizeToggle: IconSize := !IconSize GuiControl, -Redraw, ListView LV_Delete() ; 简化ImageList创建逻辑 ImageListID := IconSize ? IL_Create(1, 1, 1) : IL_Create() LV_SetImageList(ImageListID, 1) Loop { ; 填充ListView图标 Check := IL_Add(ImageListID, DllPath, A_Index) if (Check != 0) { LV_Add("Icon" . A_Index, A_Index) } else Break } GuiControl, +Redraw, ListView Return
关键修改说明
- 修正循环计数:使用
N := Mod(N,25)+1,确保N每次递增后在1-25之间循环,完美匹配25个Case的需求。 - 抽离公共代码:将重复的GUI创建逻辑移到Switch之外,每个Case仅定义DLL路径和标题,大幅降低代码冗余,后续添加DLL只需补充Case即可。
- 销毁旧窗口:每次触发快捷键时执行
Gui, Destroy,避免窗口叠加和资源泄漏。 - 简化逻辑表达式:用三元运算符简化ImageList的创建代码,让结构更清晰。
内容的提问来源于stack exchange,提问作者V0RT3X
相关产品推荐
相关产品推荐

