diff --git a/lib/AHK_Base64PNG.ahk b/AHK_Base64PNG.ahk similarity index 82% rename from lib/AHK_Base64PNG.ahk rename to AHK_Base64PNG.ahk index 3bcf577..38545c4 100644 --- a/lib/AHK_Base64PNG.ahk +++ b/AHK_Base64PNG.ahk @@ -1,96 +1,103 @@ ; Base64转PNG的函数 -Base64PNG_to_HICON(Base64PNG, height := 64) { +Base64PNGToHICON(Base64PNG, height := 64) { size := StrLen(RTrim(Base64PNG, '=')) if DllCall('Crypt32\CryptStringToBinary' - , 'Str', Base64PNG - , 'UInt', StrLen(Base64PNG) - , 'UInt', 0x00000001 - , 'Ptr', buf := Buffer(size) + , 'Str' , Base64PNG + , 'UInt' , StrLen(Base64PNG) + , 'UInt' , 0x00000001 + , 'Ptr' , buf := Buffer(size) , 'UIntP', &size - , 'Ptr', 0 - , 'Ptr', 0) + , 'Ptr' , 0 + , 'Ptr' , 0) return DllCall('CreateIconFromResourceEx' - , 'Ptr', buf + , 'Ptr' , buf , 'UInt', size , 'UInt', true , 'UInt', 0x30000 - , 'Int', height - , 'Int', height + , 'Int' , height + , 'Int' , height , 'UInt', 0) return 0 } ; PNG的Base64字符 +Base64 := { PNG:{} } ; logo图标 -LOGO_PNG_BASE64 := ' +Base64.PNG.LOGO := ' ( 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)' )' ; 搜索背景 -SEARCH_BACK_PNG_BASE64 := ' +Base64.PNG.SEARCH_BACK := ' ( iVBORw0KGgoAAAANSUhEUgAAAUAAAABKCAYAAADKfI14AAAAAXNSR0IArs4c6QAAAARzQklUCAgICHwIZIgAAANYSURBVHic7d3LeeJIFIDRC50Eyw6hMjBkMpnYRDKdiUUGFUIvlcXMogUtbPHWA1TnbGSwBVr935VK4EWMKKW0bn7cb99av14HUIqq2e7aT+acP8Y8iMXQb9BE7715uB76/YBZ2EZElXOuhnyTQQIoekCPthHDTIe9BrAVvnWfrwsQA4SwlwAKHzCibV8RfCiAwgdM6OEQ3h3AJn6fj7w5QA/uDuGPe3ZKKX1ExL/37AvQs/VqtVrUdV3duuPNAWzi937p7wBGdFcEbzoFTil9hut9wPOqcs6ba//46gCKH/Airo7gVQEUP+DFXBXBi9cAm2t+//RwQABj+XnNNcGzAbTgAbywiwsjJ0+BxQ+Yic2pL1VYntlJ/IA5+Gx9Fd+RzgA20x/AXHQOdKcmQNMfMCfrrinwWwBNf8BMfRvsjlaBLXwAM/ZztVrt6rr+vX/i3CIIwNwcDXiHCdD0BxTgaAo0AQKlOQx6y64nAUqwjDj6f70Ac3e4JWY/Aa4nOxSA8b1H/A2g01+gOIuIiJTSf1MfCMDINkuf/ABK5TYYoFRrAQSKJYBAqd6WEfE29VEATMEECBRrGW6CBspkEQQolwACxRJAoFgCCBRLAIFiLSOimvogACZQmQCBYgkgUKrdMiJ2Ux8FwBRMgECxLIIAxTIBAkXKOX8sc85VmAKBApkAgRJtI/4GcDvhgQCMrYpo/i1mRERK6TN8NyBQgJzzIsIpMFCewxnvsutJgBIcAmg1GCjANuf8sX/w9RTYFAgU4yiApkBgxo6mv4juRRBTIDA7X+MX0RFAUyAwQ52D3anbYEyBwGx0TX8RJwLYTIGbAY8HYCwnB7ofp35R1/Xv1Wq1CJ8OAV7Xt4WPtpMBjIio67oSQeBFnY1fROuzwOf4nDDwYqqc88XLeFcFMEIEgZdxVfwibghghAgCT+/q+EXc+G0wzQu7RQZ4Rttb4hdxYRGki4UR4AldXPDocnMAI0QQeCqbnPOve3a86Rpgl5TSR0S8P/o6ADeq4s/kV937Ag8HcE8IgZFU8WD49noLYMQhghFCCPSvip7Ct9drAPeEEOhJ1Wx7Dd/eIAFsSymt489iiRgC16ia7SDRaxs8gF+1psO9t2a7HvdIgAlVrZ937eeGjl7b/86z89ix20r9AAAAAElFTkSuQmCC )' ; 一键更换图标:常态 -CHANGE_ALL_NORMAL_PNG_BASE64 := ' +Base64.PNG.CHANGE_ALL_NORMAL := ' ( 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 )' ; 一键更换图标:活跃态 -CHANGE_ALL_ACTIVE_PNG_BASE64 := ' +Base64.PNG.CHANGE_ALL_ACTIVE := ' ( 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 )' ; 恢复所有默认图标:常态 -RESTORE_ALL_NORMAL_PNG_BASE64 := ' +Base64.PNG.RESTORE_ALL_NORMAL := ' ( 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 )' ; 恢复所有默认图标:活跃态 -RESTORE_ALL_ACTIVE_PNG_BASE64 := ' +Base64.PNG.RESTORE_ALL_ACTIVE := ' ( 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 )' ; 菜单:更换文件图标 -MENU_CHANGE_PNG_BASE64 := ' +Base64.PNG.MENU_CHANGE := ' ( - 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 )' ; 菜单:恢复默认图标 -MENU_DEFAULT_PNG_BASE64 := ' +Base64.PNG.MENU_DEFAULT := ' ( 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 )' ; 菜单:打开目标文件夹图标 -MENU_FOLDER_PNG_BASE64 := ' +Base64.PNG.MENU_FOLDER := ' ( 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 )' ; 菜单:重命名文件图标 -MENU_RENAME_PNG_BASE64 := ' +Base64.PNG.MENU_RENAME := ' ( iVBORw0KGgoAAAANSUhEUgAAAIAAAACACAYAAADDPmHLAAAM30lEQVR42u2d228c53XAf2d2Z3ZnL+QuuVzxTkqkVJm2odaSHAQoEjtODPcCFEVfAgToQxDJ+6f0qa8haSDQQ9v3toGbtA0aJAUqFJJ7sS3JC1oMKZIriaS4vOx9d04fNEvIkUVuXK45Ir8foAdJO7sz5/zmfOf7ZgYjdEAulxNVtVTVBhxVDYlICLAA4ehRoAU0RKQmIo3Z2VmPl4hcLmepqqOqUcDpQpz02T+q2o5Xw7KsZqfxkg4SL/4BpFR1FJhQ1YyIJIE4YHchfnWgCKyKSB5YAkpzc3OtlyT5oqppYFpVZ4AxIHLEP9MCakADaKjqFrAiIg9EZF1Vd0XEm5ub876SALlcTvyzvcdP/GvA7wOvquq4iKSBlH9gR213GXgMfCYivwJ+AdwRkVLQK0Eul7OAqKq+Dbyjqn8IvArEjvinmn6cqkBdVQvAXRH5WETuqWpeRB6LSElVm3Nzc/plXxI6IPkRVR1U1avA94Ec8B4wLSIDQAIId2kIsH25JoEZwBKR+8DO7du3m0E+8/1qOamqfwX8OTDepSpp+SdfHOgRkREReQ246scsKSJloKKq9cuXL3u3b99+7kvCL/jyuKq+rqrfB/4MSPp/vm5CQAb4nud5T4C/ARaDKoA/XPYBPwBGX3SCdREL6AUuAedU9R3gJvBPwK/9avHcBl/g2rVrA57nvaWqfwn8sT9+pbtkcSc9ig1kRWRURKJBLv+qKqqaUNVv+DGzjiFeIcAFBvyh523gT4FvX79+Pf7CHsAvX0nP874J/AXwHWDigCrxtcUVqJ47d+5/3nvvvX85f/78WlAFaLVa1vLycvbGjRs/LJVK2Var1Y3u/3fBA/aABeCXInJDRBaA6uzsrH5hCPDL1+/54/xb/th13MlHRMRxnOjIyMildDo95Xe9gcSyLOnt7Q2lUqm+Wq0W8jxPVPVYd8nv1ab8mdWSqtaBpVwuV5udndUwwPvvv28BMVX9LvAn/plvBySoZDIZyWQyrm3bbtCngKFQiL6+PorFIo1Gg2MWoC1BEnhFVX8gIlt+VXgENNtjVC/wDvAtYNjvZAOR/Hg8ztTUFOPj40Sj0aDnn2g0yptvvsng4CChUCgwxcmXYAb4LjCjqvH9aeDly5cH/c712/70yzrOvQ2HwyQSCUZHR7l06RKvvPIKZ86cIRKJICKBTb6IYFkWsVgMx3GIx+NYlkW1WqXVOvY1LGlP20VkHVi7evXqbvjatWsuMOLbkT1s6hIKhYhEImSzWTKZTFeS0v6NdDrN2NgYmUwG27YDnfxnq1YsFmN6eppUKsXw8DCbm5s0Gkfbuqgq9XqdcrlMsVhka2uLarWK53mHVYJRVZ0RkY9V9VFYRPr85u/MYaU/HA6TTqcZHx9nfHyc0dFRYrHYkSemfSbZto3rujiOw8uEZVn09PQQjUYZGBigXq8feS/geR61Wo2dnR0ePXrE0tISq6ur7OzsHCZBD3BWVSeBT8Ii0g9cUNWeww4qmUxy4cIFrly5QjKZJJlMvjRn5nE0g67r4rrd6VtVlWazSSaTYWBggFQqhW3b5PN5yuXyQZvawJBfCeJhvwE8e9hKn23bDA4Ocu7cOSYnJ02GA9Bv2La9XyUjkQitVotyuUw+nz9s85S/UBS1VDWpqiMccrEiGo0yPDxMNps10Q9gtUkkEgwPDzMyMtLJJhHAFZFw+4JCz2HzfsdxSKfT9Pb2mogHVIJYLEY8Hu/o4+0ZgfXMX6xOfqBbY5rh/994Oo7T6VpJxK/4Yet3+YFwOEw4HDbRDnhP0AG2P+OzLBO6U145TAiMAAYjgMEIYDACGIwABiOAwQhgMAIYjAAGI4DBCGA40QTi0p7neTQaDSqVCrVa7bB72l5KRGT/ZtdoNBqYW+nCQUh+uVxmY2OD5eVl1tfXqVarQXig4kiTHw6HicfjDA4OMjQ0RF9fH9Fo9NglOHYBarUahUKBO3fusLi4yPr6OpVK5cQJYNs28XicoaEhdnd3mZ6eJpvNEolETq8AqkqxWGRhYYFbt26xt7d3IsfZ9j389Xqd3d1dKpUKlmXt3zZ+qitAoVBgcXGRWq12KpquZrNJoVDAdV2y2eyxC3Dss4BSqUSxWAzCo1NfqwS1Wi0Qx3zsAqjqiez6O5n1GAF4erdxhzcynhjaDWEQHnk7dgHS6TSDg4OnRgLLsujr62NkZISenp7TvQ4gIoyNjVEqldjc3GRzczMwY2M3jjUUCpFMJpmYmGBqaoq+vr7TLQBAPB5nenoa13X5/PPPuXfvHhsbGzSbzRN11ruuS39/P6+//joXL14kk8kEYggIByE47bMinU5z4cKFrjxO/eDBAz766COKxeKBn3Ndl3fffZfe3t4jW6VrP+7uOA6pVIpUKoXjOGYp+NlGMB6P47oumUymK6uAIsLdu3cPFcC2baampujv78c6wudmRGRfhFAoFJhH6gMhwLPB6dajZ47jdJRQEdm/YGOdggenzOXgU44RwAhgMAIYjAAGI4DBCGAwAhiMAAYjgMEIYDACGIwABiOAwQhgMAIYjAAGI4DBCGAwAhiMAAYjgMEIYDACGIwABiOAwQhgMAIYjAAGI4DBCGAwAhiMAAYjgMEIYDACGIwABiOAwQhgMAIYjAAGI4DBCGAwAhiMAAYjgMEIYDACGIwABiNA12i/keSgV7W03+xlBDiJB+q/tOmgV9K0X/EelPf5GAGOENu26e3tfeHr2tvvCspkMqeqCpwaAZLJJGNjYwwMDHxpFbBtm+HhYd544w1c1z01VSB8WgRIJBJMTExQrVZRVR49ekSz2cTzPBKJBENDQ1y8eJHJyUkikYgR4KThOA7ZbBZVxXEc0uk09XqdVqtFOp1mfHyciYkJYrHYqXhd3KkToP361qGhIZLJJGfPnsXzPFSVSCRCIpEgkUicquSfKgGelcB1XQYGBswiAGYhyAhgQmAEMBgBDEYAgxHAYAQwGAEMRoAvwfM8ms0mrVbLRO2ECeABLUAP+mCr1aJarVKtVk3UAoiq0mw2qdfrHZ3P7ZxbQA3YAeqHCVCpVKhUKibaAaRer/P48WMePnzYycfLwC7QsFS1qqpbhwlQqVRYWlpibW3NRDtgtFotdnd3WVlZYXl5uZNNNoGCiJTDQBFYBP4ASL5oi1qtxsrKColEAtd1icVi9Pf3n6pr50Es+dVqle3tbZaXl1lYWGBjY6OTzR8DK6paCgMbInIX2AaGD2oCd3Z2yOfzlEolstksU1NTJJPJrlxCDYVChMNhotEokUjkpbtM+2zP1Gw2UdUj//5arcbOzg6FQoH79+/z8OHDTnu0dWAFKIUtyyqq6oL/j9M8vUT8pad0s9nkyZMn7O3tsba2RqFQ6MrtU6FQCNd1SaVSDA8Pk81micViL8W9eqqKqu4nZm1tja2tLZrN5pH+jud5NBoNKpUK29vbPHnyhEaj0cmmNWANWBGRclhESsCyqn4KnAMGOeA+Ac/z9s1eX1/vShDbArTv1JmZmWFiYgLXdQNfCVSVarXKvXv3yOfzrK6udkWAr7p7wBLwmYgURKQWunXrlnflyhVPRCxgwh8G7OMOYr1eZ29vj62tLeDpTZ3xePzA27qDkPxGo8Hy8jI3b94kn8+zu7uL53lB2UVPRH4uIj8HFubm5qrt02kP+E/g3/2GMBBzPc/zqFQq3L9/nwcPHlCr1V6K6djdu3fZ3NwM2qJZBbgD/BL4rJ3jMICINICHwD+ragr4I+As4AShmdrZ2aFYLJYajcaGP4YFlkaj4aysrAyVSiVHVSVAyc+LyN8B/+E3/s19AWZnZxWo5nK5T1X1F0CfPwyMHrcEflltFQqFha2trZ9mMpkHQU2+53nW9vZ2dn19/Uf1en1AVZ0XNdRfI1UgD/wM+FBEFoGqn/Pnd+769esjwDeB7wFv+TMDOcYD8YAt4O+Bv56fn/80qAJcv3495MfrJ8BrQILju+CmPF3u/Rj4UFX/AfjfDz744AvzxOd2bn5+ftWyrJ+JyE+AfwTuAxscslLYxYOo+13rLREpBnwGoKpaUdVPeLrUqscUsypQAD4Rkb+1LOtGKBT66LeTzwHTvTLwqYhsATdV9VvA28CYPzTYvjxWlypD294KsAr8Cvi1iDwJsgAiov56yo/9WDk8XV11ulQJvGckawFNP3e/AX4KfOg39Tv+/z+/zy/65lwuJ4Ctqj2qOg7MAOeB86o6IyIpoBeIdEGCsl917gH/CvybiCyKSGV2dtYLsgS5XM4Cop7nfQf4BvAmhyyzf0Xaya75VXLTT/x/A7f8+f7y/Pz8gUuD0uFBhVQ1qapnVHUCOCciSf+g7C4IUAWeAEsi8l9zc3PLvGTkcrmE53njwKvARSB+1BMkv0LWgYaqbgNrIvLZ/Pz8Yqdf8n+EFeBDvl65ZwAAAABJRU5ErkJggg== )' ; 菜单:添加其他快捷方式至桌面 -MENU_DESKTOP_PNG_BASE64 := ' +Base64.PNG.MENU_DESKTOP := ' ( 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 )' +; 菜单:提取快捷方式图标至桌面 +Base64.PNG.MENU_EXTRACT := ' +( + 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 +)' + ; 菜单的快捷方式属性图标 -MENU_PROPERTY_PNG_BASE64 := ' +Base64.PNG.MENU_PROPERTY := ' ( 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 )' \ No newline at end of file diff --git a/AHK_ChangeIcon.ahk b/AHK_ChangeIcon.ahk index d464ccc..1cfe715 100644 --- a/AHK_ChangeIcon.ahk +++ b/AHK_ChangeIcon.ahk @@ -1,35 +1,38 @@ ;// @Name AHK-ChangeIcon ;// @Author iKineticate -;// @Version v2.7.0 -;// @Destription:zh-CN 快速更换桌面快捷方式图标 -;// @Destription:en Quickly change of desktop shortcut icons +;// @Version v2.8.0 +;// @Destription:zh-CN 只需一步操作,用户即可随心批量更换/恢复快捷方式图标 +;// @Destription:en With just one step, users can change or restore the icons of shortcuts in batches as they wish ;// @HomepageURL https://github.com/iKineticate/AHK-ChangeIcon -;// @Icon Source https://www.iconfont.cn and https://www.flaticon.com -;// @Date 2024/03/14 -;// @Note: Copyright © 2023-2024 iKineticate +;// @Icon Source https://www.iconfont.cn && https://www.flaticon.com +;// @Date 2024/04/04 +;// @Note Copyright © 2023 iKineticate -;@Ahk2Exe-SetVersion 2.7.0 -;@Ahk2Exe-SetFileVersion 2.7.0 -;@Ahk2Exe-SetProductVersion 2.7.0 +;@Ahk2Exe-SetVersion 2.8.0 +;@Ahk2Exe-SetFileVersion 2.8.0 +;@Ahk2Exe-SetProductVersion 2.8.0 ;@Ahk2Exe-SetName AHK-ChangeIcon ;@Ahk2Exe-ExeName AHK-ChangeIcon ;@Ahk2Exe-SetCompanyName AHK-ChangeIcon ;@Ahk2Exe-SetProductName AHK-ChangeIcon ;@Ahk2Exe-SetDescription AHK-ChangeIcon ;@Ahk2Exe-SetInternalName AHK-ChangeIcon -;@Ahk2Exe-SetOrigFilename AHK-ChangeIcon.exe ;@Ahk2Exe-SetLegalTrademarks AHK-ChangeIcon -;@Ahk2Exe-SetCopyright Copyright (c) iKineticate +;@Ahk2Exe-SetOrigFilename AHK-ChangeIcon.exe +;@Ahk2Exe-SetCopyright Copyright © 2023 iKineticate #Requires AutoHotkey v2.0 +#Include AHK_Base64PNG.ahk #Include AHK_Language.ahk #Include AHK_iconGUI.ahk #Include -#Include -#Include ; https://github.com/AHK-just-me/AHK2_LV_Colors -#Include ; https://github.com/buliasz/AHKv2-Gdip -#Include ; https://www.autohotkey.com/boards/viewtopic.php?f=83&t=116218 -#Include +#Include +#Include +#Include +#Include ; https://github.com/AHK-just-me/AHK2_LV_Colors +#Include ; https://www.autohotkey.com/boards/viewtopic.php?f=83&t=116218 +#Include ; https://github.com/TheArkive/ListIcons_ahk2 +#Include ; https://github.com/buliasz/AHKv2-Gdip #SingleInstance Ignore SetControlDelay(-1) @@ -38,11 +41,9 @@ SetWinDelay(-1) ;========================================================================== ; 以管理员身份运行AHK ;========================================================================== -Full_command_line := DllCall("GetCommandLine", "str") -If not (A_IsAdmin OR RegExMatch(Full_command_line, " /restart(?!\S)")) -{ - Try - { +FullCommandLine := DllCall("GetCommandLine", "str") +If not (A_IsAdmin OR RegExMatch(FullCommandLine, " /restart(?!\S)")) { + Try { If A_IsCompiled Run '*RunAs "' A_ScriptFullPath '" /restart' Else @@ -55,8 +56,7 @@ If not (A_IsAdmin OR RegExMatch(Full_command_line, " /restart(?!\S)")) ;======================================================================================================== ; 启动GDIP ;======================================================================================================== -If !pToken := Gdip_Startup() -{ +If !pToken := Gdip_Startup() { MsgBox "Gdiplus failed to start. Please ensure you have gdiplus on your system" ExitApp } @@ -64,206 +64,237 @@ OnExit ExitFunc ;======================================================================================================== -; 创建初始化文件 -;======================================================================================================== -global info_ini_path := A_AppData . "\AHK-ChangeIcon\info.ini" ; 配置路径 -(!FileExist(A_AppData . "\AHK-ChangeIcon")) ? DirCreate(A_AppData . "\AHK-ChangeIcon"):"" ; 若不存在则创建配置文件的目录 -(!FileExist(info_ini_path)) ? FileAppend("[info]`nlast_selected_other_path=`nlast_icons_folder_path=", info_ini_path):"" ; 若不存在配置文件,则创建文件并写入段名、键名 -For Value in ["last_selected_other_path", "last_icons_folder_path"] -{ - If IniRead(info_ini_path, "info", Value, "0") ; 若配置文件不存在任意一个键,则在同一段中创建该键(兼容旧版) +; 创建初始化配置文件 +;======================================================================================================== +; 配置路径 +global iniPath := A_AppData "\AHK-ChangeIcon\info.ini" + +; 若不存在则创建配置文件的目录 +If !DirExist(A_AppData "\AHK-ChangeIcon") + DirCreate(A_AppData "\AHK-ChangeIcon") + +; 若不存在配置文件,则创建文件并写入段名、键名 +If !FileExist(iniPath) + FileAppend("[info]`nlastSelectedLinkFolderPath=`nlastSelectedIconFolderPath=", iniPath) + +; 若配置文件不存在任意一个键,则在同一段中创建该键(兼容旧版) +For Value in ["lastSelectedLinkFolderPath", "lastSelectedIconFolderPath"] { + If IniRead(iniPath, "info", Value, "0") Continue - iniWrite("", info_ini_path, "info", Value) + IniWrite('', iniPath, "info", Value) } ;======================================================================================================== -; 创建窗口 -;======================================================================================================== -; 创建现代风格GUI -ahkGUI := CreateModernGUI( {x:"center", y:"center", w:1200/2, h:650/2, back_color:"202020", gui_options:"-caption -Resize -MaximizeBox +DPIScale", gui_name:"AHK-ChangeIcon", gui_font_options:"Bold cffffff s8", gui_font:"Microsoft YaHei UI", show_options:""} ) -; 创建窗口控制按钮(关闭、最大化、最小化) -ahkGUI.CreateWindowsControlButton( {margin_top:"0", margin_right:"0", button_w:54/2, button_h:40/2, pen_width:3, active_color:"AD62FD"} ) -; 设置提示选项 -MyGui.Tooltips := GuiCtrlTips(MyGui) -MyGui.ToolTips.SetFont(,"Microsoft YaHei UI",,) -MyGui.ToolTips.SetBkColor("0xff303030") -MyGui.ToolTips.SetTxColor("0xff999999") +; 创建窗口,并载入库 +;======================================================================================================== +mainGUI := GUI() +; 创建现代风格窗口 +mainGUI.Morden := ModernGUI( {GUI:mainGUI, x:"center", y:"center", w:1200/2, h:650/2, backColor:"202020", GuiOpt:"-caption -Resize -MaximizeBox +DPIScale", GuiNmae:"AHK-ChangeIcon", GuiFontOpt:"Bold cffffff s8", GuiFont:"Microsoft YaHei UI", showOpt:""} ) +; 创建控制窗口按钮 +mainGUI.Morden.WindowCrontrolButtons( {marginTop:"0", marginRight:"0", buttonW:54/2, buttonH:40/2, activeColor:"AD62FD"} ) +; 创建窗口控件按钮 +mainGUI.Button := CreateButton(mainGUI) +; 创建窗口控件提示 +mainGUI.Tooltips := GuiCtrlTips(mainGUI) +mainGUI.ToolTips.SetFont(,"Microsoft YaHei UI",,) +mainGUI.ToolTips.SetBkColor("0xff303030") +mainGUI.ToolTips.SetTxColor("0xff999999") +mainGUI.ToolTips.SetMargins(L := 10, T := 5, R := 10, B := 5) +; 创建系统字体符号 +mainGUI.SegoeUISymbol := FontSymbol(mainGUI, 'Segoe UI Symbol') ;======================================================================================================== ; 创建标签页 ;======================================================================================================== ; 创建左侧背景 -MyGui.AddPicture("x0 y0" . " w" . 240/2 . " h" . 650/2 . " background252525") +mainGUI.AddPicture("x0 y0 w" 240/2 " h" 650/2 " background252525") ; 创建软件LOGO -MyGui.AddPicture("x" . 70/2 . " y" . 42/2 . " w" . 100/2 . " h" . 100/2 . " BackgroundTrans", "HICON:" Base64PNG_to_HICON(LOGO_PNG_BASE64, height := 512)) +mainGUI.AddPicture("x" 70/2 " y" 42/2 " w" 100/2 " h" 100/2 " BackgroundTrans", "HICON:" Base64PNGToHICON(Base64.PNG.LOGO, height := 512)) ; 设置标签页的各项参数 -tab_prop := {} -tab_prop.label_name := [Text.HOME, Text.Other, Text.LOG, Text.HELP, Text.ABOUT] -tab_prop.label_prop := {distance:0, text_options:"center +0x200", font_options:"Bold cf5f5f5 s11", font:"", font_normal_color:"f5f5f5", font_active_color:"ad62fd"} ; 输入空格来调整标签按钮里的文本相对按钮的x位置 -tab_prop.label_active := {margin_left:0, margin_top:"center", w:220/2, h:72/2, R:22/2, color:"0xfff5f5f5"} -;tab_prop.label_indicator := {margin_left:20/2, margin_top:"center", w:10/2, h:28/2, R:4/2, color:"ad62fd"} -tab_prop.logo_symbol := {margin_left:2, font_name:"Segoe UI Symbol"} -tab_prop.logo_size := [22/2, 20/2, 24/2, 24/2, 32/2] -tab_prop.logo_unicode := ["0xE10F", "0xE292", "0x1F4DC", "0xE115", "0x24D8"] -tab_item := CreateButton( {name:"logo", x:10/2, y:180/2, w:220/2, h:85/2} ).NewTab( tab_prop ) +tabProp := {x:10/2, y:180/2, w:220/2, h:85/2} +tabProp.labelName := [Text.HOME, Text.Other, Text.LOG, Text.HELP, Text.ABOUT] ; 输入空格来调整标签文本相对标签x轴位置 +tabProp.labelProp := {distance:0, textOpt:"center +0x200", fontOpt:"Bold cf5f5f5 s11", font:"", fontNormalColor:"f5f5f5", fontActiveColor:"ad62fd"} +tabProp.labelActive := {marginLeft:0, marginTop:"center", w:220/2, h:72/2, R:22/2, color:"0xfff5f5f5"} +tabProp.logoSymbol := {marginLeft:2, fontName:'Segoe UI Symbol'} +tabProp.logoSize := [22/2, 20/2, 24/2, 24/2, 32/2] +tabProp.logoUnicode := ["0xE10F", "0xE292", "0x1F4DC", "0xE115", "0x24D8"] +mainGUI.Button.NewTab( tabProp ) ;======================================================================================================== -; 标签页一:主页 +; 第一个标签页:主页(Home) ;======================================================================================================== Tab.UseTab(1) -; 左侧偏右背景 -MyGui.AddPicture("x" . 240/2 . " y0" . " w" . 200/2 . " h" . 650/2 . " background303030") -; 上方的框 -MyGui.AddPicture("vTop_Group_Box x" . 250/2 . " y" . 59/2 . " w" 180/2*(A_ScreenDPI/96) . " h" . 304/2*(A_ScreenDPI/96) . " BackgroundTrans +0xE -E0x200") -Gdip_SetPicRoundedRectangle(MyGui["Top_Group_Box"], "0xff999999", 15, isFill:="1") +; 左侧背景 +mainGUI.AddPicture("x" 240/2 " y0" " w" 200/2 " h" 650/2 " background303030") + +; 上方的圆角边框 +mainGUI.AddPicture("vtopGroupBox x" 250/2 " y" 59/2 " w" 180/2*(A_ScreenDPI/96) " h" 304/2*(A_ScreenDPI/96) " BackgroundTrans +0xE -E0x200") +Gdip_SetPicRoundedRectangle(mainGUI["topGroupBox"], "0xff999999", 15, isFill:="1") ; 上方快捷方式的旧图标 -MyGui.AddPicture("vShow_Old_Icon x" . 295/2 . " y" . 83/2 . " w" . 90/2 . " h" . 90/2 . " BackgroundTrans") +mainGUI.AddPicture("vdisplayOldIcon x" 295/2 " y" 83/2 " w" 90/2 " h" 90/2 " BackgroundTrans") ; 转换符号 -FontSymbol( {name:"Replace_Symbol", x:250/2, y:59/2, w:180/2, h:304/2, unicode:0xE1FD, font_name:"Segoe UI Symbol", text_color:"999999", back_color:"trans", font_options:"s" 56/4, text_options:"+0x200 center"} ) +mainGUI.SegoeUISymbol.Font( {name:'Replace_Symbol', unicode:0xE1FD, x:250/2, y:59/2, w:180/2, h:304/2, textColor:'999999', fontOpt:'s' 56/4, textOpt:'+0x200 center'} ) ; 下方快捷方式的新图标 -MyGui.AddPicture("vShow_New_Icon x" . 295/2 . " y" . 248/2 . " w" . 90/2 . " h" . 90/2 . " BackgroundTrans") +mainGUI.AddPicture("vdisplayNewIcon x" 295/2 " y" 248/2 " w" 90/2 " h" 90/2 " BackgroundTrans") ; 下方的框 -MyGui.AddPicture("vBottom_Goup_Box x" . 250/2 . " y" . 395/2 . " w" . 180/2*(A_ScreenDPI/96) . " h" . 196/2*(A_ScreenDPI/96) . " BackgroundTrans +0xE -E0x200") -Gdip_SetPicRoundedRectangle(MyGui["Bottom_Goup_Box"], "0xff999999", 15, isFill:="1") +mainGUI.AddPicture("vbottomGroupBox x" 250/2 " y" 395/2 " w" 180/2*(A_ScreenDPI/96) " h" 196/2*(A_ScreenDPI/96) " BackgroundTrans +0xE -E0x200") +Gdip_SetPicRoundedRectangle(mainGUI["bottomGroupBox"], "0xff999999", 15, isFill:="1") ; 下方已更换、未更换、总共符号 -FontSymbol( {name:"Change_Symbol", x:250/2, y:416/2, w:55/2, h:38/2, unicode:0x25CB, font_name:"Segoe UI Symbol", text_color:"999999", back_color:"trans", font_options:"s" 32/2, text_options:"+0x200 center"} ) -FontSymbol( {name:"Yes_Symbol", x:250/2, y:420/2, w:55/2, h:36/2, unicode:0x2714, font_name:"Segoe UI Symbol", text_color:"999999", back_color:"trans", font_options:"s" 32/4, text_options:"+0x200 center"} ) -FontSymbol( {name:"Uchange_Symbol", x:250/2, y:472/2, w:55/2, h:38/2, unicode:0x25CE, font_name:"Segoe UI Symbol", text_color:"999999", back_color:"trans", font_options:"s" 32/2, text_options:"+0x200 center"} ) -FontSymbol( {name:"Total_Symbol", x:250/2, y:528/2, w:55/2, h:38/2, unicode:0x25C9, font_name:"Segoe UI Symbol", text_color:"999999", back_color:"trans", font_options:"s" 32/2, text_options:"+0x200 center"} ) +mainGUI.SegoeUISymbol.Font( {name:'changedSymbol' , unicode:0x25CB, x:250/2, y:416/2, w:55/2, h:38/2, textColor:'999999', fontOpt:'s' 32/2, textOpt:'+0x200 center'} ) +mainGUI.SegoeUISymbol.Font( {name:'yesSymbol' , unicode:0x2714, x:250/2, y:420/2, w:55/2, h:36/2, textColor:'999999', fontOpt:'s' 32/4, textOpt:'+0x200 center'} ) +mainGUI.SegoeUISymbol.Font( {name:'uchangedSymbol', unicode:0x25CE, x:250/2, y:472/2, w:55/2, h:38/2, textColor:'999999', fontOpt:'s' 32/2, textOpt:'+0x200 center'} ) +mainGUI.SegoeUISymbol.Font( {name:'totalSymbol' , unicode:0x25C9, x:250/2, y:528/2, w:55/2, h:38/2, textColor:'999999', fontOpt:'s' 32/2, textOpt:'+0x200 center'} ) ; 已更换、未更换、总共文本 -MyGui.AddText("x" . 305/2 . " y" . 420/2 . " w" . 75/2 . " h" . 36/2 . " BackgroundTrans +0x200", Text.CHANGED_ICON) -MyGui.AddText("x" . 305/2 . " y" . 476/2 . " w" . 75/2 . " h" . 36/2 . " BackgroundTrans +0x200", Text.UNCHANGED_ICON) -MyGui.AddText("x" . 305/2 . " y" . 532/2 . " w" . 75/2 . " h" . 36/2 . " BackgroundTrans +0x200", Text.LV_LINK_TOTAL) +mainGUI.AddText("x" 305/2 " y" 420/2 " w" 75/2 " h" 36/2 " BackgroundTrans +0x200", Text.CHANGED_ICON) +mainGUI.AddText("x" 305/2 " y" 476/2 " w" 75/2 " h" 36/2 " BackgroundTrans +0x200", Text.UNCHANGED_ICON) +mainGUI.AddText("x" 305/2 " y" 532/2 " w" 75/2 " h" 36/2 " BackgroundTrans +0x200", Text.LV_LINK_TOTAL) ; 已更换、未更换、总共数量 -MyGui.AddText("vChanged_Count x" . 382/2 . " y" . 420/2 . " w" . 42/2 . " h" . 36/2 . " BackgroundTrans +0x200", "0") -MyGui.AddText("vUnchanged_Count x" . 382/2 . " y" . 476/2 . " w" . 42/2 . " h" . 36/2 . " BackgroundTrans +0x200", "0") -MyGui.AddText("vTotal_Count x" . 382/2 . " y" . 532/2 . " w" . 42/2 . " h" . 36/2 . " BackgroundTrans +0x200", "0") +mainGUI.AddText("vcountOfChanged x" 382/2 " y" 420/2 " w" 42/2 " h" 36/2 " BackgroundTrans +0x200", "0") +mainGUI.AddText("vcountOfUnchanged x" 382/2 " y" 476/2 " w" 42/2 " h" 36/2 " BackgroundTrans +0x200", "0") +mainGUI.AddText("vcountOfTotal x" 382/2 " y" 532/2 " w" 42/2 " h" 36/2 " BackgroundTrans +0x200", "0") ; 搜索栏(搜索背景+搜索图标+Edit控件) -MyGui.AddPicture("vSearch_Back x" . 478/2 . " y" . 70/2 . " w" . 320/2 . " h" . 74/2 . " BackgroundTrans", "HICON:" Base64PNG_to_HICON(SEARCH_BACK_PNG_BASE64, height := 512)) -FontSymbol( {name:"Search_Symbol", x:478/2, y:70/2, w:70/2, h:74/2, unicode:0xE11A, font_name:"Segoe UI Symbol", text_color:"999999", back_color:"trans", font_options:"s" 55/4, text_options:"+0x200 center"} ) +mainGUI.AddPicture("vsearchBarBackground x" 478/2 " y" 70/2 " w" 320/2 " h" 74/2 " BackgroundTrans", "HICON:" Base64PNGToHICON(Base64.PNG.SEARCH_BACK, height := 512)) +mainGUI.SegoeUISymbol.Font( {name:'searchSymbol', unicode:0xE11A, x:478/2, y:70/2, w:70/2, h:74/2, textColor:'999999', fontOpt:'s' 55/4, textOpt:'+0x200 center'} ) ; Edit控件,控件内不存在内容时显示指定内容 https://github.com/jNizM/AHK_Scripts/blob/master/src/gui/Gui_Complete_Example.ahk -MyGui.AddEdit("vSearch_Edit x" . 532/2 . " y" . 92/2 . " Background2E2E2E -multi -wrap -E0X200") ; r1可以隐藏该控件的上下导航栏 -SendMessage(EM_SETCUEBANNER := 0x1501, True, StrPtr(Text.PLEASE_INPUT_NAME), MyGui["Search_Edit"].hwnd) -MyGui["Search_Edit"].SetFont("c999999") +mainGUI.AddEdit("vsearchEditCtrl x" 532/2 " y" 92/2 " Background2E2E2E -multi -wrap -E0X200") ; r1可以隐藏该控件的上下导航栏 +SendMessage(EM_SETCUEBANNER := 0x1501, True, StrPtr(Text.PLEASE_INPUT_NAME), mainGUI["searchEditCtrl"].hwnd) +mainGUI["searchEditCtrl"].SetFont("c999999") ; 隐藏的按钮 -MyGui.AddButton("vHidden_BTN yp w26 h26 Default Hidden").OnEvent("Click", Search) - -; 恢复默认图标的PNG图片按钮 -CreateButton( {name:"Restore_All", x:815/2, y:68/2, w:175/2, h:79/2} ).PNG( {normal_png_base64:RESTORE_ALL_NORMAL_PNG_BASE64, active_png_base64:RESTORE_ALL_ACTIVE_PNG_BASE64, png_quality:"300"} ) -MyGui.ToolTips.SetTip(MyGui["Restore_All_BUTTON"], TEXT.TIP_RESTORE) -; 更换所有图标的PNG图片按钮 -CreateButton( {name:"Change_All", x:1006/2, y:68/2, w:175/2, h:79/2} ).PNG( {normal_png_base64:CHANGE_ALL_NORMAL_PNG_BASE64, active_png_base64:CHANGE_ALL_ACTIVE_PNG_BASE64, png_quality:"300"} ) -MyGui.ToolTips.SetTip(MyGui["Change_All_BUTTON"], TEXT.TIP_CHANGE) - +mainGUI.AddButton("vhiddenSearchButton yp w26 h26 Default Hidden").OnEvent("Click", Search) + +; 更换和恢复默认图标的PNG图片按钮 +mainGUI.Button.PNG( {name:"restoreAllLinks", x:815/2 , y:68/2, w:175/2, h:79/2, normal:Base64.PNG.RESTORE_ALL_NORMAL, active:Base64.PNG.RESTORE_ALL_ACTIVE, pngQuality:"300"} ) +mainGUI.Button.PNG( {name:"changedAllLinks", x:1006/2, y:68/2, w:175/2, h:79/2, normal:Base64.PNG.CHANGE_ALL_NORMAL , active:Base64.PNG.CHANGE_ALL_ACTIVE , pngQuality:"300"} ) +mainGUI.Button.OnEvent('restoreAllLinks', 'Click', (*) => RestoreAllLinksIconsToDefault()) +mainGUI.Button.OnEvent('changedAllLinks', 'Click', (*) => ChangeAllLinksIcons()) +mainGUI.ToolTips.SetTip(mainGUI.Button.Obj['restoreAllLinks'], TEXT.TIP_RESTORE) +mainGUI.ToolTips.SetTip(mainGUI.Button.Obj['changedAllLinks'] , TEXT.TIP_CHANGE) + +global folderListFrom := 'Desktop' ; 列表快捷方式的来源 +global MapLinkProp := map() ; 快捷方式的映射数组 +global IL_ID := IL_Create() ; 创建列表的图标列表 ; 创建列表(+LV0x10000: 双缓冲,redraw: 加载数据后在redraw, -Multi: 禁止多选) -LV := MyGui.AddListView("vLV x" . 440/2 . " y" . 180/2 . " w" . 760/2 . " h" . 470/2 . " Background232323 -redraw -Multi -E0x200 +LV0x10000", ["Name", "Y/N", "Type"]) +LV := mainGUI.AddListView("vLV x" 440/2 " y" 180/2 " w" 760/2 " h" 470/2 " Background232323 -redraw -Multi -E0x200 +LV0x10000", ["Name", "Y/N", "Type"]) LV.SetFont("cf5f5f5 s14") -LV.OnEvent("ItemFocus", Refresh_Display_Icon) -LV.OnEvent("DoubleClick", Change_Link_Icon) -LV.OnEvent("ContextMenu", LV_Context_Menu) -global link_map := map() ; 创建快捷方式的映射数组 -global LV_link_from := "Desktop" ; 创建当前列表中的快捷方式是来自哪个文件夹的变量 -global image_list_ID := IL_Create() ; 为添加图标做好准备: 创建图像列表 -LV.SetImageList(image_list_ID) ; 为添加图标做好准备: 设置显示图标列表 +LV.OnEvent("ItemFocus", RefreshIconDisplay) +LV.OnEvent("DoubleClick", ChangeLinkIcon) +LV.OnEvent("ContextMenu", ShowListContextMenu) +LV.SetImageList(IL_ID) ; 添加桌面快捷方式至列表 -For Desktop in [A_Desktop, A_DesktopCommon] -{ - Add_Folder_Link_To_LV(Desktop, Mode := "") +For Desktop in [A_Desktop, A_DesktopCommon] { + AddLinksFromFolderToLV(Desktop, Mode := "") } +; 设置列表颜色 +mainGUI.SetLV := LV_Colors(LV, 0, 0, 0) +mainGUI.SetLV.Critical := 100 +Loop LV.GetCount() { + If (Mod(A_Index, 2) = 0) + Continue + mainGUI.SetLV.Row(A_Index, 0x292929) +} +mainGUI.SetLV.ShowColors() ; 设置、调整列表 LV.ModifyCol(1, 460/2) LV.ModifyCol(2, "+AutoHdr") LV.ModifyCol(3, "+AutoHdr") -SetLV := LV_Colors(LV, 0, 0, 0) -SetLV.Critical := 100 -Loop LV.GetCount() -{ - If (Mod(A_Index, 2) = 0) - Continue - SetLV.Row(A_Index, 0x292929) -} -SetLV.ShowColors(true) LV.Opt("+Redraw") ; 更新计数 -MyGui["Total_Count"].Value := LV.GetCount() -MyGui["Unchanged_Count"].Value := LV.GetCount() - MyGui["Changed_Count"].Value +mainGUI["countOfTotal"].Value := LV.GetCount() +mainGUI["countOfUnchanged"].Value := LV.GetCount() - mainGUI["countOfChanged"].Value -;========================================================================== -; 第二个标签页:其他(其他) -;========================================================================== +;======================================================================================================== +; 第二个标签页:其他(Other) +;======================================================================================================== Tab.UseTab(2) -CreateButton( {name:"Add_Desktop", x:280/2, y:80/2, w:790/2, h:90/2} ).Text( {R:24/2, normal_color:"0x26ffffff", active_color:"909090", text:Text.ADD_DESKTOP_TO_LV, text_options:"+0x200", text_margin:10, font_options:"cffffff s13", font:""} ) -FontSymbol( {name:"Add_Desktop_Symbol", x:290/2, y:78/2, w:90/2, h:90/2, unicode:0xE2CB, font_name:"Segoe UI Symbol", text_color:"ffffff", back_color:"trans", font_options:"s" 90/4, text_options:"+0x200 center"} ) +mainGUI.Button.Text( {name:'addDesktopLinksToLV', x:278/2, y:75/2, w:790/2, h:90/2, R:20/2, normalColor:'0x26ffffff', activeColor:'909090', text: Text.ADD_DESKTOP_TO_LV, textOpt:'+0x200', textHorizontalMargin:10, fontOpt:'cffffff s13', font:''} ) +mainGUI.Button.OnEvent('addDesktopLinksToLV', 'Click', (*) => AddShortcutToList('Desktop')) +mainGUI.SegoeUISymbol.Font( {name:'addDesktopLinksToLV_Symbol', unicode:0xE2CB, x:286/2, y:73/2, w:90/2, h:90/2, textColor:'ffffff', fontOpt:'s' 90/4, textOpt:'+0x200 center'} ) -CreateButton( {name:"Add_Start", x:280/2, y:190/2, w:790/2, h:90/2} ).Text( {R:24/2, normal_color:"0x26ffffff", active_color:"909090", text:Text.ADD_START_TO_LV, text_options:"+0x200", text_margin:10, font_options:"cffffff s13", font:""} ) -FontSymbol( {name:"Add_Start_Symbol", x:290/2, y:191/2, w:90/2, h:90/2, unicode:0xE154, font_name:"Segoe UI Symbol", text_color:"ffffff", back_color:"trans", font_options:"s" 90/4, text_options:"+0x200 center"} ) +mainGUI.Button.Text( {name:'addStartLinksToLV', x:278/2, y:185/2, w:790/2, h:90/2, R:20/2, normalColor:'0x26ffffff', activeColor:'909090', text: Text.ADD_START_TO_LV, textOpt:'+0x200', textHorizontalMargin:10, fontOpt:'cffffff s13', font:''} ) +mainGUI.Button.OnEvent('addStartLinksToLV', 'Click', (*) => AddShortcutToList('Start')) +mainGUI.SegoeUISymbol.Font( {name:'addStartLinksToLV_Symbol', unicode:0xE154, x:286/2, y:186/2, w:90/2, h:90/2, textColor:'ffffff', fontOpt:'s' 90/4, textOpt:'+0x200 center'} ) -CreateButton( {name:"Add_Other", x:280/2, y:300/2, w:790/2, h:90/2} ).Text( {R:24/2, normal_color:"0x26ffffff", active_color:"909090", text:Text.ADD_OTHER_TO_LV, text_options:"+0x200", text_margin:10, font_options:"cffffff s13", font:""} ) -FontSymbol( {name:"Add_Other_Symbol", x:290/2, y:304/2, w:90/2, h:90/2, unicode:0xE1C1, font_name:"Segoe UI Symbol", text_color:"ffffff", back_color:"trans", font_options:"s" 90/5, text_options:"+0x200 center"} ) +mainGUI.Button.Text( {name:'addOtherLinksToLV', x:278/2, y:295/2, w:790/2, h:90/2, R:20/2, normalColor:'0x26ffffff', activeColor:'909090', text: Text.ADD_OTHER_TO_LV, textOpt:'+0x200', textHorizontalMargin:10, fontOpt:'cffffff s13', font:''} ) +mainGUI.Button.OnEvent('addOtherLinksToLV', 'Click', (*) => AddShortcutToList('Other')) +mainGUI.SegoeUISymbol.Font( {name:'addOtherLinksToLV_Symbol', unicode:0xE1C1, x:286/2, y:299/2, w:90/2, h:90/2, textColor:'ffffff', fontOpt:'s' 90/5, textOpt:'+0x200 center'} ) -CreateButton( {name:"Add_UWP_WSA", x:280/2, y:410/2, w:790/2, h:90/2} ).Text( {R:24/2, normal_color:"0x26ffffff", active_color:"909090", text:Text.ADD_UWP_WSA_TO_LV, text_options:"+0x200", text_margin:10, font_options:"cffffff s13", font:""} ) -FontSymbol( {name:"Add_UWP_WSA_Symbol", x:290/2, y:409/2, w:90/2, h:90/2, unicode:0xE2F8, font_name:"Segoe UI Symbol", text_color:"ffffff", back_color:"trans", font_options:"s" 90/3.5, text_options:"+0x200 center"} ) +mainGUI.Button.Text( {name:'openAppsFolder', x:278/2, y:405/2, w:790/2, h:90/2, R:20/2, normalColor:'0x26ffffff', activeColor:'909090', text: Text.ADD_UWP_WSA_TO_LV, textOpt:'+0x200', textHorizontalMargin:10, fontOpt:'cffffff s13', font:''} ) +mainGUI.Button.OnEvent('openAppsFolder', 'Click', (*) => AddUwpAppToDesktop()) +mainGUI.SegoeUISymbol.Font( {name:'openAppsFolder_Symbol', unicode:0xE2F8, x:286/2, y:404/2, w:90/2, h:90/2, textColor:'ffffff', fontOpt:'s' 90/3.5, textOpt:'+0x200 center'} ) -CreateButton( {name:"Add_BackUp", x:280/2, y:520/2, w:790/2, h:90/2} ).Text( {R:24/2, normal_color:"0x26ffffff", active_color:"909090", text:Text.BACKUP_LV_LINK, text_options:"+0x200", text_margin:10, font_options:"cffffff s13", font:""} ) -FontSymbol( {name:"Add_BackUp_Symbol", x:290/2, y:522/2, w:90/2, h:90/2, unicode:0xE17C, font_name:"Segoe UI Symbol", text_color:"ffffff", back_color:"trans", font_options:"s" 90/5, text_options:"+0x200 center"} ) +mainGUI.Button.Text( {name:'backupLinksToDesktop', x:278/2, y:515/2, w:790/2, h:90/2, R:20/2, normalColor:'0x26ffffff', activeColor:'909090', text: Text.BACKUP_LV_LINK, textOpt:'+0x200', textHorizontalMargin:10, fontOpt:'cffffff s13', font:''} ) +mainGUI.Button.OnEvent('backupLinksToDesktop', 'Click', (*) => BackupLinksToFolder()) +mainGUI.SegoeUISymbol.Font( {name:'backupLinksToDesktop_Symbol', unicode:0xE17C, x:286/2, y:516/2, w:90/2, h:90/2, textColor:'ffffff', fontOpt:'s' 90/5, textOpt:'+0x200 center'} ) -CreateButton( {name:"Show_iconGUI", x:1090/2, y:80/2, w:75/2, h:530/2} ).Text( {R:16/2, normal_color:"0x26ffffff", active_color:"9657DB", text:"", text_options:"+0x200 center", text_margin:0, font_options:"cffffff s13", font:""} ) -FontSymbol( {name:"Show_iconGUI_Symbol", x:1090/2, y:80/2, w:75/2, h:530/2, unicode:0x2B9E, font_name:"Segoe UI Symbol", text_color:"ffffff", back_color:"trans", font_options:"s" 90/5, text_options:"+0x200 center"} ) -MyGui.ToolTips.SetTip(MyGui["Show_iconGUI_BUTTON"], TEXT.SYSTEM_ICONS) -;========================================================================== +mainGUI.Button.Text( {name:'showIconGUI', x:1088/2, y:75/2, w:75/2, h:530/2, R:16/2, normalColor:'0x26ffffff', activeColor:'9657DB', text:'', textOpt:'+0x200 center', textHorizontalMargin:0, fontOpt:'cffffff s13', font:''} ) +mainGUI.Button.OnEvent('showIconGUI', 'Click', (*) => ToggleIconGUIVisibility()) +mainGUI.SegoeUISymbol.Font( {name:'showIconGUI_Symbol', unicode:0xE291, x:1090/2, y:75/2, w:75/2, h:530/2, textColor:'ffffff', fontOpt:'s' 90/5, textOpt:'+0x200 center'} ) +mainGUI.ToolTips.SetTip(mainGUI.Button.Obj['showIconGUI'], TEXT.SYSTEM_ICONS) + + +;======================================================================================================== ; 第三个标签页:日志(Log) -;========================================================================== +;======================================================================================================== Tab.UseTab(3) -MyGui.AddEdit("vLog x" . 240/2 . " y" . 40/2 . " w" . 960/2 . " h" . 610/2 . " Background303030 -E0x200 -WantReturn -Wrap +0x100000 +ReadOnly") ; +0x100000: 水平滚动条 -MyGui["Log"].SetFont("s10") +mainGUI.AddEdit("vlog x" 240/2 " y" 40/2 " w" 960/2 " h" 610/2 " Background303030 -E0x200 -WantReturn -Wrap +0x100000 +ReadOnly +0x4000000") ; +0x100000: 水平滚动条 +mainGUI['log'].SetFont("s10") -;========================================================================== +;======================================================================================================== ; 第四个标签页:设置(Settings) -;========================================================================== +;======================================================================================================== Tab.UseTab(4) +mainGUI.Button.Text( {name:'save', x:1030/2, y:570/2, w:140/2, h:50/2, R:10/2, normalColor:'0x1Affffff', activeColor:'9657DB', text:'Save', textOpt:'+0x200 center', textHorizontalMargin:0, fontOpt:'cffffff s10', font:''} ) +mainGUI.Button.OnEvent('save', 'Click', (*)=>Msgbox()) - -;========================================================================== +;======================================================================================================== ; 第五个标签页:关于(About) -;========================================================================== +;======================================================================================================== Tab.UseTab(5) ; 背景 -MyGui.AddPicture("vAbout_Background x" . 270/2 . " y" . 46/2 . " w" 900/2*(A_ScreenDPI/96) . " h" . 585/2*(A_ScreenDPI/96) . " BackgroundTrans +0xE -E0x200") -Gdip_SetPicRoundedRectangle(MyGui["About_Background"], "0x0Dffffff", 15, isFill:="true") +mainGUI.AddPicture("vleftBackground x" 260/2 " y" 46/2 " w" 920/2*(A_ScreenDPI/96) " h" 585/2*(A_ScreenDPI/96) " BackgroundTrans +0xE -E0x200") +Gdip_SetPicRoundedRectangle(mainGUI["leftBackground"], "0x0Dffffff", 15, isFill:="true") ; 软件名 -MyGui.AddText("vsoftware x" 320/2 " y" 80/2 " w" 540/2 " h" 60/2 " 0x200 backgroundtrans", "AHK-ChangeIcon") -MyGui["software"].SetFont("s18 cffffff", "Verdana") +mainGUI.AddText("vsoftware x" 320/2 " y" 70/2 " w" 540/2 " h" 60/2 " 0x200 backgroundtrans", "AHK-ChangeIcon") ; 版本 -MyGui.AddText("vVersion x" 320/2 " y" 140/2 " w" 240/2 " h" 40/2 " 0x200 backgroundtrans", "Version 2.7.0 (x64)") -MyGui["Version"].SetFont("s10 cbebebe", "Calibri") +mainGUI.AddText("vversion x" 320/2 " y" 130/2 " w" 300/2 " h" 40/2 " 0x200 backgroundtrans", "Version 2.8.0 (x64)") ; 作者 -MyGui.AddText("vAuthor x" 320/2 " y" 180/2 " w" 240/2 " h" 40/2 " 0x200 backgroundtrans", "Author: iKineticate").OnEvent("DoubleClick", (*)=>"") -MyGui["Author"].SetFont("s10 cbebebe", "Calibri") -MyGui.ToolTips.SetTip(MyGui["Author"], "酷安:林琼雅") +mainGUI.AddText("vauthor x" 320/2 " y" 170/2 " w" 300/2 " h" 40/2 " 0x200 backgroundtrans", "Author: iKineticate").OnEvent("DoubleClick", (*)=>"") ; 跳转至网页 -CreateButton( {name:"github", x:316/2, y:220/2, w:222/2, h:60/2} ).Text( {R:10/2, normal_color:"0x00ffffff", active_color:"0x1Affffff", text_options:"+0x200",text_margin:"2", font_options:"s11 c5bad72", font:"", text:TEXT.GITHUB} ) -CreateButton( {name:"download", x:316/2, y:280/2, w:222/2, h:60/2} ).Text( {R:10/2, normal_color:"0x00ffffff", active_color:"0x1Affffff", text_options:"+0x200",text_margin:"2", font_options:"s11 c5bad72", font:"", text:TEXT.DOWNLOAD} ) -CreateButton( {name:"help", x:316/2, y:340/2, w:222/2, h:60/2} ).Text( {R:10/2, normal_color:"0x00ffffff", active_color:"0x1Affffff", text_options:"+0x200",text_margin:"2", font_options:"s11 c5bad72", font:"", text:TEXT.ABOUT_HELP} ) -CreateButton( {name:"issues", x:316/2, y:400/2, w:222/2, h:60/2} ).Text( {R:10/2, normal_color:"0x00ffffff", active_color:"0x1Affffff", text_options:"+0x200",text_margin:"2", font_options:"s11 c5bad72", font:"", text:TEXT.ISSUES} ) -CreateButton( {name:"Contributors", x:316/2, y:460/2, w:222/2, h:60/2} ).Text( {R:10/2, normal_color:"0x00ffffff", active_color:"0x1Affffff", text_options:"+0x200",text_margin:"2", font_options:"s11 c5bad72", font:"", text:TEXT.CONTRIBUTORS} ) -MyGui.ToolTips.SetTip(MyGui["github_BUTTON"], "https://github.com/iKineticate/AHK-ChangeIcon") -MyGui.ToolTips.SetTip(MyGui["download_BUTTON"], "https://github.com/iKineticate/AHK-ChangeIcon/releases") -MyGui.ToolTips.SetTip(MyGui["help_BUTTON"], "https://github.com/iKineticate/AHK-ChangeIcon?tab=readme-ov-file#已知问题") ; 根据中英文更换链接 -MyGui.ToolTips.SetTip(MyGui["issues_BUTTON"], "https://github.com/iKineticate/AHK-ChangeIcon/issues") -MyGui.ToolTips.SetTip(MyGui["Contributors_BUTTON"], "https://github.com/iKineticate/AHK-ChangeIcon?tab=readme-ov-file#感谢") -; 灰色 -MyGui.SetFont("s10 c666666", "Cambria") -MyGui.AddText("vcopy_right x" 320/2 " y" 520/2 " w" 600/2 " h" 35/2 " 0x200 backgroundtrans", "Copyright " chr(0x00A9) " 2023-2024 iKineticate") -MyGui.AddText("vicon_from x" 320/2 " y" 555/2 " w" 600/2 " h" 35/2 " 0x200 backgroundtrans", "Logo by iconfield from www.flaticon.com") -MyGui.AddText("vlogo_from x" 320/2 " y" 590/2 " w" 600/2 " h" 30/2 " 0x200 backgroundtrans", "Icons from www.iconfont.cn and www.flaticon.com") +mainGUI.Button.Text( {name:"github" , x:316/2, y:210/2, w:222/2, h:60/2, R:10/2, normalColor:"0x00ffffff", activeColor:"0x1Affffff", textOpt:"+0x200",textHorizontalMargin:"2", fontOpt:"s11 c5bad72", font:"", text: TEXT.GITHUB} ) +mainGUI.Button.Text( {name:"download" , x:316/2, y:270/2, w:222/2, h:60/2, R:10/2, normalColor:"0x00ffffff", activeColor:"0x1Affffff", textOpt:"+0x200",textHorizontalMargin:"2", fontOpt:"s11 c5bad72", font:"", text: TEXT.DOWNLOAD} ) +mainGUI.Button.Text( {name:"help" , x:316/2, y:330/2, w:222/2, h:60/2, R:10/2, normalColor:"0x00ffffff", activeColor:"0x1Affffff", textOpt:"+0x200",textHorizontalMargin:"2", fontOpt:"s11 c5bad72", font:"", text: TEXT.ABOUT_HELP} ) +mainGUI.Button.Text( {name:"issues" , x:316/2, y:390/2, w:222/2, h:60/2, R:10/2, normalColor:"0x00ffffff", activeColor:"0x1Affffff", textOpt:"+0x200",textHorizontalMargin:"2", fontOpt:"s11 c5bad72", font:"", text: TEXT.ISSUES} ) +mainGUI.Button.Text( {name:"contribution", x:316/2, y:450/2, w:222/2, h:60/2, R:10/2, normalColor:"0x00ffffff", activeColor:"0x1Affffff", textOpt:"+0x200",textHorizontalMargin:"2", fontOpt:"s11 c5bad72", font:"", text: TEXT.CONTRIBUTORS} ) + +mainGUI["software"].SetFont("s18 cffffff", "Verdana") +mainGUI["version"].SetFont("s10 cbebebe" , "Franklin Gothic") +mainGUI["author"].SetFont("s10 cbebebe" , "Franklin Gothic") +mainGUI.SetFont("s10 c666666", "Cambria") + +mainGUI.Button.OnEvent('github' , 'Click', (*) => Run('https://github.com/iKineticate/AHK-ChangeIcon')) +mainGUI.Button.OnEvent('download' , 'Click', (*) => Run('https://github.com/iKineticate/AHK-ChangeIcon/releases/latest')) +mainGUI.Button.OnEvent('help' , 'Click', (*) => Run('https://github.com/iKineticate/AHK-ChangeIcon?tab=readme-ov-file#已知问题')) +mainGUI.Button.OnEvent('issues' , 'Click', (*) => Run('https://github.com/iKineticate/AHK-ChangeIcon/issues')) +mainGUI.Button.OnEvent('contribution', 'Click', (*) => Run('https://github.com/iKineticate/AHK-ChangeIcon?tab=readme-ov-file#感谢')) + +mainGUI.ToolTips.SetTip(mainGUI["author"] , "酷安:林琼雅") +mainGUI.ToolTips.SetTip(mainGUI.Button.Obj['github'] , "https://github.com/iKineticate/AHK-ChangeIcon") +mainGUI.ToolTips.SetTip(mainGUI.Button.Obj['download'] , "https://github.com/iKineticate/AHK-ChangeIcon/releases") +mainGUI.ToolTips.SetTip(mainGUI.Button.Obj['help'] , "https://github.com/iKineticate/AHK-ChangeIcon?tab=readme-ov-file#已知问题") ; 根据中英文更换链接 +mainGUI.ToolTips.SetTip(mainGUI.Button.Obj['issues'] , "https://github.com/iKineticate/AHK-ChangeIcon/issues") +mainGUI.ToolTips.SetTip(mainGUI.Button.Obj['contribution'], "https://github.com/iKineticate/AHK-ChangeIcon?tab=readme-ov-file#感谢") + +mainGUI.AddText("vcopyRight x" 320/2 " y" 510/2 " w" 600/2 " h" 35/2 " 0x200 backgroundtrans", "Copyright " chr(0x00A9) " 2023 iKineticate") +mainGUI.AddText("viconsFrom x" 320/2 " y" 545/2 " w" 600/2 " h" 35/2 " 0x200 backgroundtrans", "Logo by iconfield from www.flaticon.com") +mainGUI.AddText("vlogoFrom x" 320/2 " y" 580/2 " w" 600/2 " h" 30/2 " 0x200 backgroundtrans", "Icons from www.iconfont.cn and www.flaticon.com") ;========================================================================== @@ -271,8 +302,8 @@ MyGui.AddText("vlogo_from x" 320/2 " y" 590/2 " w" 600/2 " h" 30/2 " 0x200 backg ;========================================================================== Tab.UseTab() ; (1)窗口标题栏(根据Windows版本赋予attr不同的值) -dwAttr:= VerCompare(A_OSVersion, "10.0.18985") >= 0 ? 20 : VerCompare(A_OSVersion, "10.0.17763") >= 0 ? 19 : "" -DllCall("dwmapi\DwmSetWindowAttribute", "Ptr", MyGui.Hwnd, "int", dwAttr, "int*", True, "int", 4) +dwAttr:= (VerCompare(A_OSVersion, "10.0.18985") >= 0) ? 20 : ((VerCompare(A_OSVersion, "10.0.17763") >= 0) ? 19 : "") +DllCall("dwmapi\DwmSetWindowAttribute", "Ptr", mainGUI.Hwnd, "int", dwAttr, "int*", True, "int", 4) ; (2)呼出的菜单(1:根据系统显示模式调整深浅,2:深色,3:浅色) DllCall(DllCall("GetProcAddress", "Ptr", DllCall("GetModuleHandle", "Str", "uxtheme", "Ptr"), "Ptr", 135, "Ptr"), "int", 2) DllCall(DllCall("GetProcAddress", "Ptr", DllCall("GetModuleHandle", "Str", "uxtheme", "Ptr"), "Ptr", 136, "Ptr")) @@ -280,560 +311,529 @@ DllCall(DllCall("GetProcAddress", "Ptr", DllCall("GetModuleHandle", "Str", "uxth LV_header_hwnd := SendMessage(0x101F, 0, 0, LV.hWnd) ;列表标题栏的hwnd DllCall("uxtheme\SetWindowTheme", "Ptr", LV_header_hwnd, "Str", "DarkMode_ItemsView", "Ptr", 0) DllCall("uxtheme\SetWindowTheme", "Ptr", LV.hWnd, "Str", "DarkMode_Explorer", "Ptr", 0) -; DllCall("SetWindowLongPtr", "Ptr", LV_header_hwnd, "int", -20, "Int", 0x80000) -; DllCall("SetLayeredWindowAttributes", "Ptr", LV_header_hwnd, "Uint", 0xffffffff, "Uchar", 50, "Uint", 0x2) ; 0x1指定颜色按照Uchar透明、0x2指定窗口按照Uchar透明 -; DllCall("ShowWindow", "Ptr", LV_header_hwnd, "int", 1) ; (4)日志(Edit)的滚动条 -DllCall("uxtheme\SetWindowTheme", "Ptr", MyGui["Log"].hWnd, "Str", "DarkMode_Explorer", "Ptr", 0) +DllCall("uxtheme\SetWindowTheme", "Ptr", mainGUI['log'].hWnd, "Str", "DarkMode_Explorer", "Ptr", 0) -; 圆角窗口 -FrameShadow(MyGui.hwnd) -; 展示GUI -ahkGUI.GuiShow(ahkGUI.show_options) -; 检测MyGui内的鼠标移动 -OnMessage(0x200, WM_MOUSEMOVE) -; 监测MyGui外的鼠标移动 -; OnMessage(0x2A3, WM_MOUSELEAVE) -; 检测MyGui的移动 -OnMessage(0x03, WM_MOVE) +mainGUI.Morden.Show() ; 展示圆角GUI +OnMessage(0x200, WM_MOUSEMOVE) ; 监测mainGUI内的鼠标移动 +OnMessage(0x03 , WM_MOVE) ; 监测mainGUI窗口的移动 +OnMessage(0x20 , WM_SETCURSOR, -1) ; 设置mainGUI内鼠标样式 ;========================================================================== Return ;========================================================================== -;========================================================================== -; 设置窗口圆角(框架阴影) ; https://www.autohotkey.com/boards/viewtopic.php?f=82&t=113202&p=560692&hilit=WinSetRegion#p560692 -; https://github.com/jNizM/AHK_Scripts/blob/master/src/gui/GUI_ShadowBorder2.ahk -;========================================================================== -FrameShadow(hwnd) -{ - DllCall("dwmapi.dll\DwmIsCompositionEnabled", "int*", &dwmEnabled:=0) - - if !dwmEnabled { - ; GetClassLongPtr: 从与指定窗口关联的 WNDCLASSEX 结构中检索指定值 - ; GCL_STYLE = -26 (检索窗口类样式位) - ; SetClassLongPtr: 替换指定窗口所属类的额外类内存或 WNDCLASSEX 结构的指定偏移量处的指定值。 - ; GCL_STYLE = -26 (替换窗口类样式位) - ; CS_DropSHADOW = 0x20000 - DllCall("user32.dll\SetClassLongPtr", "ptr", hwnd, "int", -26, "ptr", DllCall("user32.dll\GetClassLongPtr", "ptr", hwnd, "int", -26) | 0x20000) - } - else { - ; v1版本: - ; VarSetCapacity(_MARGINS,16) - ; NumPut(1,&_MARGINS,0,"UInt") - ; NumPut(1,&_MARGINS,4,"UInt") - ; NumPut(1,&_MARGINS,8,"UInt") - ; NumPut(1,&_MARGINS,12,"UInt") - margins := Buffer(16, 0) - NumPut("int", 1, "int", 1, "int", 1, "int", 1, margins) ; <= converted from v1 above. I'm not sure about this. - ; DWM(桌面窗口管理器): 提供的视觉效果有毛玻璃框架、3D窗口变换动画、窗口翻转和高分辨率支持; 自带双缓冲!!! - DllCall("dwmapi.dll\DwmSetWindowAttribute", "ptr", hwnd, "Int", 2, "Int*", 2, "Int", 4) - DllCall("dwmapi.dll\DwmExtendFrameIntoClientArea", "ptr", hwnd, "ptr", margins) - } -} - - ;========================================================================== ; 处理鼠标移动的消息(使光标下控件转换为活跃态) ;========================================================================== -WM_MOUSEMOVE(wParam, lParam, Msg, Hwnd) -{ - If GuiCtrlFromHwnd(Hwnd) ; 若鼠标下为窗口控件,则执行知道功能,否则隐藏所有控件的活动态图片 - { - current_control := GuiCtrlFromHwnd(Hwnd) , thisGui := current_control.Gui ; 获取控件hwnd和父窗口 - - ; 若当前控件为活动控件或列表,则返回,否则活动控件设置为当前控件(避免鼠标在同一控件移动时发生闪烁) - If current_control = thisGui.active_control - or current_control = MyGui["LV"] - or current_control = MyGui["Log"] - or (IsSet(iconGUI) and (thisGUI=iconGUI)) - ; or thisGUI["其他控件"] +WM_MOUSEMOVE(wParam, lParam, Msg, Hwnd) { + If currentControl := GuiCtrlFromHwnd(Hwnd) { ; 若鼠标下为窗口控件,则执行功能 + thisGui := currentControl.Gui ; 获取控件hwnd和父窗口 + + If currentControl = thisGui.activeControl ; 若当前控件为活动控件或指定控件,则返回(避免鼠标在这些控件移动时发生重复闪烁或错误) Return - ; 若存在其他活跃态控件,则取消其活跃态 - (thisGui.active_control) ? WM_MOUSELEAVE() : False - ; 取消其他活跃态后,在判读是否为当前焦点标签页 - If current_control = MyGui.Focus_Tab + + (thisGui.activeControl) ? WM_MOUSELEAVE(thisGUI) : False ; 若存在其他活跃态控件,则取消其活跃态 + + If currentControl = mainGUI.lastTab ; 取消其他活跃态后,在判读是否为当前焦点标签页 + or currentControl = mainGUI["LV"] + or currentControl = mainGUI['log'] Return - ; 定义活跃态控件为当前焦点控件 - thisGui.active_control := current_control - ; 设置当前控件为活跃态(若为标签页则特殊处理) - If Instr(current_control.name, "_Tab_Button") - { - active_name := StrReplace(current_control.name, "_Tab_Button", "_ACTIVE") - indicator_name := StrReplace(current_control.name, "_Tab_Button", "_INDICATOR") - logo_symbol_name := StrReplace(current_control.name, "_Tab_Button", "_SYMBOL") - thisGui[active_name].Visible := True - thisGui[current_control.name].SetFont("c" . tab_prop.label_prop.font_active_color) - (tab_prop.HasOwnProp("label_indicator")) ? (thisGui[indicator_name].Visible := True) : False - (tab_prop.HasOwnProp("logo_symbol")) ? thisGui[logo_symbol_name].SetFont("c" . tab_prop.label_prop.font_active_color) : False - } - Else - { - active_control_name := StrReplace(current_control.name, "_BUTTON", "_ACTIVE") - thisGui[active_control_name].Visible := True + + thisGui.activeControl := currentControl ; 定义活跃态控件为当前焦点控件 + + If Instr(currentControl.name, "_TAB_BUTTON") { ; 设置当前控件为活跃态(若为标签页则特殊处理) + activeName := StrReplace(currentControl.name, "_TAB_BUTTON", "_ACTIVE") + indicatorName := StrReplace(currentControl.name, "_TAB_BUTTON", "_INDICATOR") + logoSymbolName := StrReplace(currentControl.name, "_TAB_BUTTON", "_SYMBOL") + activeColor := tabProp.labelProp.fontActiveColor + + thisGui[activeName].Visible := True ; 高亮背景 + thisGui[currentControl.name].SetFont("c" activeColor) ; 高亮名称 + + tabProp.HasOwnProp("labelIndicator") ? thisGui[indicatorName].Visible := True : False ; 高亮其指示符 + tabProp.HasOwnProp("logoSymbol") ? thisGui[logoSymbolName].SetFont("c" activeColor) : False ; 高亮标签图标 + } Else { + activeControlName := StrReplace(currentControl.name, "_BUTTON", "_ACTIVE") + thisGui[activeControlName].Visible := True ; 高亮背景 } - } - Else - { - ; wparam=1 (鼠标左键被按下) - ; WM_NCLBUTTONDOWN = 0x00A1 (模拟鼠标按下窗口的非客户区域) , WM_NCHITTEST消息中的HTCAPTION = 2 (在标题栏中) - ((wParam = 1) and (hwnd = MyGui.hwnd)) ? PostMessage(0xA1, 2) : WM_MOUSELEAVE() + } Else { + static WM_NCLBUTTONDOWN := 0xA1 ; 按下鼠标的左键 + static WM_NCHITTEST := 2 ; 窗口的标题栏中 + ; static wParam = 1 ; 鼠标左键被按下 + ((wParam = 1) and (hwnd = mainGUI.hwnd)) ? PostMessage(WM_NCLBUTTONDOWN, WM_NCHITTEST) : WM_MOUSELEAVE(mainGUI) } } ;========================================================================== -; 处理离开MyGui窗口消息(取消绝大部分控件活跃态) +; 处理离开mainGUI窗口消息(取消绝大部分控件活跃态) ;========================================================================== -WM_MOUSELEAVE(*) -{ - ; 若活动按钮为空或不为按钮则返回(避免影响caption控件),若活动按钮为焦点按钮 - If !MyGui.active_control - or !Instr(MyGui.active_control.name, "_Button") - or MyGui.active_control = MyGui.Focus_Tab - Return - ; 隐藏上一次活跃控件的活跃态 - If Instr(MyGui.active_control.name, "_Tab_Button") - { - active_name := StrReplace(MyGui.active_control.name, "_Tab_Button", "_ACTIVE") - indicator_name := StrReplace(MyGui.active_control.name, "_Tab_Button", "_INDICATOR") - logo_symbol_name := StrReplace(MyGui.active_control.name, "_Tab_Button", "_SYMBOL") - - MyGui[active_name].Visible := False - MyGui[MyGui.active_control.name].SetFont("c" . tab_prop.label_prop.font_normal_color) - (tab_prop.HasOwnProp("label_indicator")) ? (MyGui[indicator_name].Visible := False) : False - (tab_prop.HasOwnProp("logo_symbol")) ? MyGui[logo_symbol_name].SetFont("c" . tab_prop.label_prop.font_normal_color) : False +WM_MOUSELEAVE(thisGUI) { + Try { + If !thisGUI.activeControl ; 若该窗口的活动按钮不存在、不为可被点击的按钮控件或为上一次标签页,则返回 + or !Instr(thisGUI.activeControl.name, "_BUTTON") + or thisGUI.activeControl = thisGUI.lastTab + Return } - Else - { - active_control_name := StrReplace(MyGui.active_control.name, "_Button", "_ACTIVE") - MyGui[active_control_name].Visible := False + + If Instr(thisGUI.activeControl.name, "_TAB_BUTTON") { ; 隐藏上一次活跃控件的活跃态 + activeName := StrReplace(thisGUI.activeControl.name, "_TAB_BUTTON", "_ACTIVE") + indicatorName := StrReplace(thisGUI.activeControl.name, "_TAB_BUTTON", "_INDICATOR") + logoSymbolName := StrReplace(thisGUI.activeControl.name, "_TAB_BUTTON", "_SYMBOL") + normalColor := tabProp.labelProp.fontNormalColor + + thisGUI[activeName].Visible := False ; 隐藏高亮背景 + thisGUI[thisGUI.activeControl.name].SetFont("c" normalColor) ; 恢复名称原色 + + tabProp.HasOwnProp("labelIndicator") ? thisGUI[indicatorName].Visible := False : False ; 恢复其指示器原色 + tabProp.HasOwnProp("logoSymbol") ? thisGUI[logoSymbolName].SetFont("c" normalColor) : False ; 恢复标签图标原色 + } Else { + activeControlName := StrReplace(thisGUI.activeControl.name, "_BUTTON", "_ACTIVE") + thisGUI[activeControlName].Visible := False ; 隐藏高亮背景 } - MyGui.active_control := False + thisGUI.activeControl := False ; 设置窗口活动按钮不存在 } ;========================================================================== -; iconGUI窗口随MyGui窗口移动而移动 +; iconGUI窗口随mainGUI窗口移动而移动 ;========================================================================== -WM_MOVE(wParam, lParam, Msg, Hwnd) -{ - If (Hwnd != MyGui.hwnd) or (!IsSet(iconGUI)) +WM_MOVE(wParam, lParam, Msg, Hwnd) { + If (Hwnd != mainGUI.hwnd) or !IsSet(iconGUI) or !(iconGUI is GUI) Return - Try - { - MyGui.GetPos(&main_x, &main_y, &main_w) - iconGUI.Move((main_x+main_w+10), main_y) - } - Catch - { + + Try { + mainGUI.GetPos(&mainX, &mainY, &mainW) + iconGUI.Move((mainX/(A_ScreenDPI/96)+mainW+10), mainY/(A_ScreenDPI/96)) + } Catch { Return } } ;========================================================================== -; 各个按钮的功能分配 +; 不同控件下的鼠标样式 ;========================================================================== -ButtonFunc(GuiCtrlObj, Info, *) -{ - If Instr(GuiCtrlObj.Name, "_Tab_Button") - Return Tab_Click(GuiCtrlObj.Name) +; 不用WM_MOUSEMOVE的原因:光标移动时,系统会在新位置重绘类游标。若要防止重绘类游标,必须处理WM_SETCURSOR消息。每次移动光标和未捕获鼠标输入时,系统都会将此消息发送到光标移动的窗口 +WM_SETCURSOR(wParam, lParam, msg, hwnd) { + static IMAGE_CURSOR := 2 + , LR_DEFAULTSIZE := 0x00000040 + , LR_SHARED := 0x00008000 - control_btn_name := RegExReplace(GuiCtrlObj.Name, "i)_BUTTON$") - Switch control_btn_name - { - Case "Close" : Progressive_ExitApp(MyGui.hwnd) - Case "Minimize" : WinMinimize(MyGui.hwnd) - Case "Change_All" : Change_All_Shortcut_Icons() - Case "Restore_All" : Restore_All_Shortcut_Icons() - Case "Add_Desktop" : Add_Desktop_To_LV() - Case "Add_Start" : Add_Sart_To_LV() - Case "Add_Other" : Add_Other_To_LV() - Case "Add_UWP_WSA" : Add_UWP_APP_To_LV() - Case "Add_BackUp" : Backup_LV_Link_To_Folder() - Case "Show_iconGUI" : Show_Hide_iconGUI() - Case "github" : Run("https://github.com/iKineticate/AHK-ChangeIcon") - Case "download" : Run("https://github.com/iKineticate/AHK-ChangeIcon/releases") - Case "help" : Run("https://github.com/iKineticate/AHK-ChangeIcon?tab=readme-ov-file#已知问题") - Case "issues" : Run("https://github.com/iKineticate/AHK-ChangeIcon/issues") - Case "Contributors" : Run("https://github.com/iKineticate/AHK-ChangeIcon?tab=readme-ov-file#感谢") + static LoadCursor(name) => DllCall("User32.dll\LoadImage", "Ptr", hInst:=0, "Ptr", name, "UInt", IMAGE_CURSOR, "Int", 0, "Int", 0, "UInt", LR_DEFAULTSIZE|LR_SHARED, "Ptr") + + static hCursPrior := 0 ; About Cursors: https://learn.microsoft.com/zh-CN/windows/win32/menurc/about-cursors + , hCursARROW := LoadCursor(IDC_ARROW:=32512) ; 正常箭头 + , hCursWAIT := LoadCursor(IDC_WAIT :=32514) ; 正在工作 + , hCursHAND := LoadCursor(IDC_HAND :=32649) ; 按钮点击 + + ; Critical("on") + hCursNew := 0, hcursor := 0 + + MouseGetPos(,,,&ctrlHwnd:=0, 2) ; 2: 保存控件hwnd到第四个参数,而不是控件ClssNN + Switch ctrlHwnd { + Case mainGUI.Button.Obj['changedAllLinks'].hwnd : hCursNew := hCursHand + Case mainGUI.Button.Obj['restoreAllLinks'].hwnd : hCursNew := hCursHand + Case mainGUI.Button.Obj['github'].hwnd : hCursNew := hCursHand + Case mainGUI.Button.Obj['download'].hwnd : hCursNew := hCursHand + Case mainGUI.Button.Obj['help'].hwnd : hCursNew := hCursHand + Case mainGUI.Button.Obj['issues'].hwnd : hCursNew := hCursHand + Case mainGUI.Button.Obj['contribution'].hwnd : hCursNew := hCursHand + Default : + Try { + If !IsSet(iconGUI) or !(iconGUI IS GUI) or (hwnd != iconGUI.hwnd) + Return + (ctrlHwnd = iconGUI.Button.Obj['iconGUIBtn1'].hwnd) ? hCursNew := hCursHand : False + (ctrlHwnd = iconGUI.Button.Obj['iconGUIBtn2'].hwnd) ? hCursNew := hCursHand : False + } } -} + If hCursNew { + hcursor := DllCall("SetCursor", "Ptr", hCursNew, "Ptr") + hCursPrior ? False : hCursPrior := hcursor + } Else If hCursPrior { + hcursor := DllCall("SetCursor", "Ptr", hCursPrior, "Ptr") + hCursPrior := 0 + } -;========================================================================== -; 渐进式淡化、隐藏、关闭 -;========================================================================== -Progressive_ExitApp(hwnd) -{ - static AW_BLEND := 0x00080000 - static AW_HIDE := 0x00010000 - WinGetPos(,,&OutWidth, &OutHeight, hwnd) - WinSetRegion("0-0 r30-30 w" . OutWidth . " h" . OutHeight, hwnd) ; 避免渐进式关闭时,DWM会失效导致圆角消失,因此需在关闭前通过别的办法设置圆角,避免影响视觉效果 - (IsSet(iconGUI)) ? iconGUI.Destroy() : False - DllCall("user32.dll\AnimateWindow", "ptr", hwnd, "uint", 800, "uint", AW_BLEND|AW_HIDE) - ExitApp() -} - - -;========================================================================== -; 标签被点击的函数(选择并聚焦该标签页、取消其他标签页活跃态) -;========================================================================== -Tab_Click(current_tab_name) -{ - If MyGui[current_tab_name] = MyGui.Focus_Tab - Return - - Tab.Choose(StrReplace(current_tab_name, "_Tab_Button")) ; 选择对应的隐藏标签页 - - For name in [MyGui.Focus_Tab.name, current_tab_name] - { - active_name := StrReplace(name, "_Tab_Button", "_ACTIVE") - focus_name := StrReplace(name, "_Tab_Button", "_FOCUS") - indicator_name := StrReplace(name, "_Tab_Button", "_INDICATOR") - MyGui[focus_name].Visible := (name=current_tab_name) ? True:False - MyGui[active_name].Visible := False - (tab_prop.HasOwnProp("label_indicator")) ? (MyGui[indicator_name].Visible := (name=current_tab_name) ? True:False) : False - } - ; 本次被点击标签页的logo激活活跃态 - logo_symbol_name := StrReplace(MyGui[current_tab_name].name, "_Tab_Button", "_SYMBOL") - MyGui[current_tab_name].SetFont("c" . tab_prop.label_prop.font_active_color) - (tab_prop.HasOwnProp("logo_symbol")) ? MyGui[logo_symbol_name].SetFont("c" . tab_prop.label_prop.font_active_color) : False - ; 上次被点击的标签页恢复常态 - logo_symbol_name := StrReplace(MyGui.Focus_Tab.name, "_Tab_Button", "_SYMBOL") - MyGui.Focus_Tab.SetFont("c" . tab_prop.label_prop.font_normal_color) - (tab_prop.HasOwnProp("logo_symbol")) ? MyGui[logo_symbol_name].SetFont("c" . tab_prop.label_prop.font_normal_color) : False - ; 上次被点击标签页=本次 - MyGui.Focus_Tab := MyGui[current_tab_name] + return (hcursor ? True : False) } ;========================================================================== ; 调用WshShell对象(COM对象)获取、更改、创建快捷方式的属性 ;========================================================================== -COM_Link_Attribute(&link_path, &link_attribute, &link_icon_location) -{ - link_attribute := ComObject("WScript.Shell").CreateShortcut(link_path) ; 快捷方式的属性 - link_icon_location := RegExReplace(link_attribute.IconLocation, ",[^,]+$") ; 快捷方式的图标路径(去除了图片编号)(存储的是值而不是变量) +ManageLinkProp(&objLink, &linkPath, &linkIconLocation) { + objLink := ComObject("WScript.Shell").CreateShortcut(linkPath) ; 对象快捷方式 + linkIconLocation := RegExReplace(objLink.IconLocation, ",-?\d+$") ; 快捷方式的图标路径(去除了图片编号)(存储的是值而不是变量) + ; objLink.IconLocation - 提供或设置快捷方式对象的图标位置 + ; objLink.TargePath - 提供或设置快捷方式对象的目标路径 + ; objLink.WorkingDirectory - 提供或设置快捷方式对象的工作目录 + ; objLink.Save - 将快捷方式存储到指定的文件系统中 } ;========================================================================== -; 将目标文件夹中的快捷方式添加进列表的事件 +; 将目标文件夹中的快捷方式添加进列表的功能函数 ;========================================================================== -Add_Folder_Link_To_LV(link_folder_path, Mode) ; Mode:="R"扫描子文件夹中的文件,默认只扫描目标文件夹中的文件 -{ - Loop Files, link_folder_path "\*.lnk", Mode - { - ; If ((LV_link_from = "Start") AND (RegExMatch(A_LoopFileName, "i)uninstall|卸载"))) ; 若添加的是菜单,且快捷方式名为"卸载",则下一轮循环(避免添加软件的卸载程序) - ; Continue - - link_path := A_LoopFilePath - COM_Link_Attribute(&link_path, &link_attribute, &link_icon_location) ; 调用WshShell对象的函数,获取快捷方式属性 - link_target_path := link_attribute.TargetPath - link_target_dir := (link_target_path AND !link_attribute.WorkingDirectory) ? RegExReplace(link_target_path, "\\[^\\]+$"):link_attribute.WorkingDirectory ; 解决目标目录未填写的情况 - link_name := RegExReplace(A_LoopFileName, "i)\.lnk$") ; 去除了后缀名的快捷方式的名称 - ; 若变量值存在但目标文件不存在,则提醒不存在且告知是否删除 - If (!FileExist(link_target_path) and link_target_path) - { - (Msgbox(link_name . TEXT.IS_DELETE, "( •̀ ω •́ )y", "OKCANCEL icon?") = "OK") ? FileDelete(link_path) : False +AddLinksFromFolderToLV(shortcutFolderPath, Mode) { ; Mode:="R"扫描子文件夹中的文件,默认只扫描目标文件夹中的文件 + mainGUI.Opt("+Disabled") ; 禁止与GUI交互 + Loop Files, shortcutFolderPath "\*.lnk", Mode { + SplitPath(linkPath := A_LoopFilePath,,,, &linkName) ; 快捷方式无扩展名的名称 + ManageLinkProp(&objLink, &linkPath, &linkIconLocation) ; 调用WshShell对象的函数,获取快捷方式属性 + + ; 若快捷方式属性中有目标路径,但目标文件不存在,则提醒建议删除,然后执行下一循环 + If !FileExist(linkTargetPath := objLink.TargetPath) and objLink.TargetPath { + (Msgbox(linkName . TEXT.IS_DELETE, "( •̀ ω •́ )y", "OKCANCEL icon?") = "OK") ? FileDelete(linkPath) : False Continue } - ; 快捷方式的目标扩展名 - SplitPath(link_target_path,,, &link_target_ext) - Switch - { - Case !link_target_ext : ; 空则为UWP - link_target_ext := "uwp" - Case InStr(link_target_path, "WindowsSubsystemForAndroid") : ; 安卓应用 - link_target_ext := "app" - Case InStr(link_target_path, "schtasks") : ; 命令任务(计划程序)的快捷方式 - link_target_ext := "schtasks" - Case Instr(link_target_path, "explorer") : - link_target_ext := "explorer" - Case Instr(link_target_path, "cmd") : - link_target_ext := "cmd" - Case Instr(link_target_path, "powershell") : - link_target_ext := "ps" - Default : - link_target_ext := StrLower(link_target_ext) + + ; 若快捷方式属性中有目标目录,但目录不存在,则利用SplitPath分解存在的目标路径获取目录 + If DirExist(linkTargetDir := objLink.WorkingDirectory) { + SplitPath(linkTargetPath, &linkTargetName, , &linkTargetExt) + } Else { + SplitPath(linkTargetPath, &linkTargetName, &linkTargetDir, &linkTargetExt) } - ; 若本次循环快捷方式名称跟既往循环快捷方式名称相同(即数组存在),且二者扩展名称相同,则跳过(有些同名称但目标扩展类型不同) - key := link_name . link_target_ext - If link_map.Has(key) + + Switch linkTargetName { + Case 'schtasks.exe' : linkTargetExt := "schtasks" ; 任务计划程序 + Case 'explorer.exe' : linkTargetExt := "explorer" ; 资源管理器 + Case 'cmd.exe' : linkTargetExt := "cmd" ; 命令提示符 + Case 'powershell.exe' : linkTargetExt := "psh" ; PowerShell + Case 'wscript.exe' : linkTargetExt := 'wscript' ; WScript 对象 + Case 'mstsc.exe' : linkTargetExt := 'mstsc' ; 远程连接 + Case 'control.exe' : linkTargetExt := 'control' ; 控制面板 + Default : + Switch { + Case !linkTargetExt : + linkTargetExt := "uwp" + Case InStr(linkTargetPath, "WindowsSubsystemForAndroid") : + linkTargetExt := "app" + Default : + linkTargetExt := StrLower(linkTargetExt) + } + } + + linkID := linkName . linkTargetExt + If MapLinkProp.Has(linkID) ; 本次循环中,若快捷方式属性的数组存在快捷方式唯一标识,则执行下一循环 Continue - ; LTP = Link Target Path = 快捷方式的目标路径(UWP无法查看) - ; LTD = Link Target Dir = 快捷方式的目标目录(UWP无法查看) - ; LP = Link Path = 快捷方式的路径 - ; LD = Link Dir = 快捷方式的目录 - link_map[key] := {} - link_map[key].LTP := (!link_target_path) ? Text.SAFE_UNAVAILABLE : link_target_path - link_map[key].LTD := (!link_target_dir) ? Text.SAFE_UNAVAILABLE : link_target_dir - link_map[key].LP := A_LoopFilePath - link_map[key].LD := A_LoopFileDir - ; 判断是否更换图标 - If !link_icon_location - or link_icon_location = link_target_path ; 图标来源于目标图标 - or RegExMatch(link_icon_location, "i)%[^%]*%|WindowsSubsystemForAndroid|\{[^\{]*\}\\[^\\]*\.exe$") ; WSA、系统图标(% %即可排除使用system32的图标) - or InStr(link_target_dir, RegExReplace(link_icon_location, "\\([^\\]+)\.ico$")) ; 某些应用EXE无内置图标,其图标来源于其父目录 - ; or (link_icon_location and InStr(link_icon_location, link_target_dir)) ; 图标来源于其子目录中 - or (!FileExist(link_icon_location) and RegExMatch(link_icon_location, "i)[^\\]+\.[dll|exe]$")) ; 图标文件不存在,且不是来自路径为如shell32.dll - { - is_changed := "" + MapLinkProp[linkID] := { + LTP : (linkTargetPath ? linkTargetPath : Text.SAFE_UNAVAILABLE) ; Link Target Path = 快捷方式的目标路径(UWP无法查看) + , LTD : (linkTargetDir ? linkTargetDir : Text.SAFE_UNAVAILABLE) ; Link Target Dir = 快捷方式的目标目录(UWP无法查看) + , LP : (A_LoopFilePath) ; Link Path = 快捷方式的路径 + , LD : (A_LoopFileDir) ; Link Dir = 快捷方式的目录 } - Else - { - is_changed := "√" - MyGui["Changed_Count"].Value += 1 + + If !FileExist(linkIconLocation) ; 图标不存在 + or linkIconLocation = linkTargetPath ; 图标源于目标文件图标 + or RegExMatch(linkIconLocation, "i)WindowsSubsystemForAndroid|%[^%]+%|\{[^\{]+\}\\[^\\]+\.exe$") ; 图标源于APP图标、系统图标(%__%)或{__}\__\.exe图标 + or (linkTargetDir = RegExReplace(linkIconLocation, "\\([^\\]+)\.ico$")) ; 图标来源于其目标上一级目录的图标 + or (linkTargetDir and InStr(linkIconLocation, linkTargetDir)) { ; 图标来源于其目标子目录中的图标 + IsChangede := "" + } Else { + IsChangede := "√" + mainGUI["countOfChanged"].Value += 1 } - ; 调用DllCall_Get_Icon函数和图像列表替换函数,添加图标给数组,赋予给icon_number--刷新列表左侧图标 - hIcon := DllCall_Get_Icon(A_LoopFilePath) - icon_number := DllCall("ImageList_ReplaceIcon", "Ptr", image_list_ID, "Int", -1, "Ptr", hIcon) + 1 - DllCall("DestroyIcon", "ptr", hIcon) - LV.Add("Icon" . icon_number, link_name, is_changed, link_target_ext) ; 列表添加图标、名称、"√"、目标扩展名 + + hIcon := GetFileHICON(A_LoopFilePath) + IconNumber := DllCall("ImageList_ReplaceIcon", "Ptr", IL_ID, "Int", -1, "Ptr", hIcon) + 1, DllCall("DestroyIcon", "ptr", hIcon) + LV.Add("Icon" IconNumber, linkName, IsChangede, linkTargetExt) ; 列表添加图标、名称、"√"、目标扩展名 } LV.ModifyCol(1, "+Sort") LV.ModifyCol(2, "+Center") LV.ModifyCol(3, "+Center +Sort") ; 先第一列(名称)排列,后第三列(扩展名)排列,保证扩展名为主排列,名称为次排列 + mainGUI.Opt("-Disabled") } ;========================================================================== ; DllCall获取图标的函数 ;========================================================================== -DllCall_Get_Icon(link_target_path) -{ - fileinfo := Buffer(fisize := A_PtrSize + 688) +GetFileHICON(filePath) { + static SHGFI_ICON := 0x100 ; 检索表示文件图标的句柄 + ; static SHGFI_SMALLICON := 0x001 ; 修改 SHGFI_ICON,使函数检索文件的小型图标 + ; static SHGFI_LARGEICON := 0x000 ; 修改 SHGFI_ICON,使函数检索文件的大型图标 + ; static SHGFI_ICON + SHGFI_LARGEICON = 0x100 + ; static SHGFI_ICON + SHGFI_SMALLICON = 0x101 + fileInfo := Buffer(fisize := A_PtrSize + 688) If DllCall("Shell32\SHGetFileInfoW" - , "Str", link_target_path + , "Str", filePath , "Uint", 0 - , "Ptr", fileinfo + , "Ptr", fileInfo , "UInt", fisize - , "UInt", 0x100) - Return hIcon := NumGet(fileinfo, 0, "Ptr") -} - - -;========================================================================== -; 刷新列表项目图标的函数 -;========================================================================== -Refresh_LV_Icon(LV, Item) -{ - LV.Focus() - key := LV.GetText(Item, 1) . LV.GetText(Item, 3) - link_path := link_map[key].LP - hIcon := DllCall_Get_Icon(link_path) - icon_number := DllCall("ImageList_ReplaceIcon", "Ptr", image_list_ID, "Int", -1, "Ptr", hIcon) + 1 ; 调用DllCall_Icon函数重新刷新列表指定项目图标 - DllCall("DestroyIcon", "ptr", hIcon) - LV.Modify(Item, "Icon" . icon_number) + , "UInt", SHGFI_ICON) + Return hIcon := (NumGet(fileinfo, 0, "Ptr") ? NumGet(fileinfo, 0, "Ptr") : LoadPicture('shell32.dll', 'icon3')) } ;========================================================================== -; 刷新ICON显示的函数 +; 刷新图标显示的函数 ;========================================================================== -Refresh_Display_Icon(LV, Item) -{ +RefreshIconDisplay(LV, Item, IsRefreshListIcon := False) { LV.Focus() - key := LV.GetText(Item, 1) . LV.GetText(Item, 3) - link_path := link_map[key].LP - link_target_path := link_map[key].LTP - - Try - { - hIcon := DllCall_Get_Icon(Link_Path) - MyGui["Show_New_Icon"].Value := "HICON:" hIcon ; 调用DllCall_Get_Icon函数重新刷新顶部显示图标区域的图片内容 - DllCall("DestroyIcon", "ptr", hIcon) - } - Catch - { - MyGui["Show_New_Icon"].Value := "*icon3 shell32.dll" ; 从系统中调用图标 + linkID := LV.GetText(Item, 1) . LV.GetText(Item, 3) + linkPath := MapLinkProp[linkID].LP + linkTargetPath := MapLinkProp[linkID].LTP + + Try { + hIcon := GetFileHICON(linkPath) + If IsRefreshListIcon { + IconNumber := DllCall("ImageList_ReplaceIcon", "Ptr", IL_ID, "Int", -1, "Ptr", hIcon) + 1 + LV.Modify(Item, "Icon" IconNumber) + } + mainGUI["displayNewIcon"].Value := "HICON:" hIcon, DllCall("DestroyIcon", "ptr", hIcon) + } Catch { + mainGUI["displayNewIcon"].Value := "*icon3 shell32.dll" ; 从系统中调用第二个图标--应用 } - Try ; 无法获取某些应用(如UWP)目标的路径,或应用目标路径不存在时,采用Try - { - hIcon := DllCall_Get_Icon(link_target_path) - MyGui["Show_Old_Icon"].Value := "HICON:" hIcon - DllCall("DestroyIcon", "ptr", hIcon) - } - Catch - { - MyGui["Show_Old_Icon"].Value := "*icon3 shell32.dll" ; 从系统中调用图标 + Try { ; 无法获取某些应用(如UWP)目标的路径,或应用目标路径不存在时,采用Try + hIcon := GetFileHICON(linkTargetPath) + mainGUI["displayOldIcon"].Value := "HICON:" hIcon, DllCall("DestroyIcon", "ptr", hIcon) + } Catch { + mainGUI["displayOldIcon"].Value := "*icon3 shell32.dll" ; 从系统中调用第二个图标--应用 } } ;========================================================================== ; 更换单个快捷方式的图标函数 ;========================================================================== -Change_Link_Icon(LV, Item) -{ - MyGui.Opt("+OwnDialogs") ; 解除对话框(如Msgbox等)后才可于GUI窗口交互 - - link_name := LV.GetText(Item, 1) - key := LV.GetText(Item, 1) . LV.GetText(Item, 3) - link_path := link_map[key].LP - link_target_path := link_map[key].LTP - ; 调用WshShell对象的函数,获取快捷方式属性 - COM_Link_Attribute(&Link_Path, &Link_Attribute, &Link_Icon_Location) - ; 选择文件格式为“.ico”的图标并赋予图标路径给该变量 - select_icon_path := FileSelect(3,, TEXT.SELECT_A_ICON, "Icon files(*.ico)") - If ((!select_icon_path) OR (select_icon_path = Link_Icon_Location)) +ChangeLinkIcon(LV, Item) { + mainGUI.Opt("+OwnDialogs") ; 解除对话框(如Msgbox等)后才可与GUI交互 + linkName := LV.GetText(Item, 1) + linkExt := LV.GetText(Item, 3) + linkID := linkName . linkExt + linkPath := MapLinkProp[linkID].LP + + ManageLinkProp(&objLink, &linkPath, &linkIconLocation) ; 创建WshShell对象,设置或获取快捷方式属性 + + selectedIconPath := FileSelect(3,, TEXT.SELECT_A_ICON, "Icon file(*.ico)") ; 选择文件格式为“.ico”的图标并赋予图标路径给该变量 + If ((!selectedIconPath) OR (selectedIconPath = linkIconLocation)) Return - ; 否则更换图片并保存 - Link_Attribute.IconLocation := select_icon_path - Link_Attribute.Save() - ; 更新显示的数据 - If !LV.GetText(Item, 2) - { - MyGui["Changed_Count"].Value += 1 - MyGui["Unchanged_Count"].Value -= 1 + + objLink.IconLocation := selectedIconPath ; 更换图片并保存该操作 + objLink.Save() + + If !LV.GetText(Item, 2) { ; 更新显示的数据 + mainGUI["countOfChanged"].Value += 1 + mainGUI["countOfUnchanged"].Value -= 1 } - ; 刷新顶部和列表图标,并目标行添加"√" - Refresh_Display_Icon(LV, Item) - Refresh_LV_Icon(LV, Item) + + RefreshIconDisplay(LV, Item, IsRefreshListIcon:=True) + RefreshExplorer() + LV.Modify(Item,,,"√") - ; 添加至日志 - MyGui["Log"].Value .= FormatTime(A_Now, "`syyyy/MM/dd HH:mm:ss`n`s") - . Text.LOG_CHANGED_LINK . link_name . "`n`s" - . Text.Source_OF_ICON . select_icon_path . "`n`n===========================================`n`n" + + mainGUI['log'].Value .= FormatTime(A_Now, "`syyyy/MM/dd HH:mm:ss`n`s") ; 添加至日志 + . Text.LOG_CHANGED_LINK . linkName . "`n`s" + . Text.Source_OF_ICON . selectedIconPath . "`n`n===========================================`n`n" } ;========================================================================== ; 列表右键菜单事件 ;========================================================================== -LV_Context_Menu(LV, Item, IsRightClick, X, Y) -{ +ShowListContextMenu(LV, Item, IsRightClick, X, Y) { If ((Item > 1000) OR (Item <= 0) OR !IsSet(Item)) ; 避免右键列表的标题栏时出现错误 Return - link_name := LV.GetText(Item, 1) ; 快捷方式的名称 - key := link_name . LV.GetText(Item, 3) - link_target_path := link_map[key].LTP - link_target_dir := link_map[key].LTD - link_path := link_map[key].LP - link_dir := link_map[key].LD - - COM_Link_Attribute(&link_path, &Link_Attribute, &Link_Icon_Location) ; 调用WshShell对象的函数,获取快捷方式属性 - - link_menu := Menu() ; 创建菜单并添加选项及功能 - link_menu.Add(Text.MENU_RUN, (*) => Run(link_path)) - link_menu.Add - link_menu.Add(Text.MENU_CHANGE, (*) => Run(Change_Link_Icon(LV, Item))) - link_menu.Add - link_menu.Add(Text.MENU_RESTORE, Link_Restore) - link_menu.Add - link_menu.Add(Text.MENU_OPEN, (*) => Run(link_target_dir)) - link_menu.Add - link_menu.Add(Text.MENU_RENAME, Link_Rename) - - If (LV_link_from != "Desktop") ; 若当前列表中非桌面快捷方式,则菜单选项添加一行"添加至桌面" - { - link_menu.Add - link_menu.Add(Text.MENU_ADD_LINK_TO_DESKTOP, Link_Add_Desktop) - link_menu.SetIcon(Text.MENU_ADD_LINK_TO_DESKTOP, "HICON:" Base64PNG_to_HICON(MENU_DESKTOP_PNG_BASE64)) + linkName := LV.GetText(Item, 1) + linkExt := LV.GetText(Item, 3) + linkID := linkName . linkExt + linkTargetPath := MapLinkProp[linkID].LTP + linkTargetDir := MapLinkProp[linkID].LTD + linkPath := MapLinkProp[linkID].LP + linkDir := MapLinkProp[linkID].LD + + ManageLinkProp(&objLink, &linkPath, &linkIconLocation) ; 创建WshShell对象,设置或获取快捷方式属性 + + LVContextMenu := Menu() + LVContextMenu.Add(TEXT.MENU_RUN , (*) => Run(linkPath)) + LVContextMenu.Add() + LVContextMenu.Add(TEXT.MENU_CHANGE , (*) => ChangeLinkIcon(LV, Item)) + LVContextMenu.Add() + LVContextMenu.Add(TEXT.MENU_RESTORE, (*) => RestoreLinkIconsToDefault()) + LVContextMenu.Add() + LVContextMenu.Add(TEXT.MENU_EXTRACT, (*) => ExtractLinkIcon()) + LVContextMenu.Add() + LVContextMenu.Add(TEXT.MENU_OPEN , (*) => Run(linkTargetDir)) + LVContextMenu.Add() + LVContextMenu.Add(TEXT.MENU_RENAME , (*) => RenameLink()) + LVContextMenu.Add() + + ; 创建总菜单的子菜单 + addLinkPropToMenu := Menu() + addLinkPropToMenu.Add(TEXT.COPY_LINK_TARGET_PATH . linkTargetPath , (*) => (A_Clipboard := linkTargetPath)) + addLinkPropToMenu.Add() + addLinkPropToMenu.Add(TEXT.COPY_LINK_TARGET_DIR . linkTargetDir , (*) => (A_Clipboard := linkTargetDir)) + addLinkPropToMenu.Add() + addLinkPropToMenu.Add(TEXT.COPY_LINK_Path . linkPath , (*) => (A_Clipboard := linkPath)) + addLinkPropToMenu.Add() + addLinkPropToMenu.Add(TEXT.COPU_LINK_DIR . linkDir , (*) => (A_Clipboard := linkDir)) + addLinkPropToMenu.Add() + addLinkPropToMenu.Add(TEXT.COPY_LINK_ICON_PATH . objLink.IconLocation, (*) => (A_Clipboard := objLink.IconLocation)) + + LVContextMenu.Add(TEXT.MENU_PROPERTIES, addLinkPropToMenu) ; 快捷方式属性添加至上下文菜单 + + hIcon := GetFileHICON(linkPath) + LVContextMenu.SetIcon(TEXT.MENU_RUN, "HICON:" hIcon), DllCall("DestroyIcon", "ptr", hIcon) ; 菜单的运行文件的图标 + LVContextMenu.SetIcon(TEXT.MENU_CHANGE , "HICON:" Base64PNGToHICON(Base64.PNG.MENU_CHANGE)) ; 菜单的改变图标的图标 + LVContextMenu.SetIcon(TEXT.MENU_RESTORE , "HICON:" Base64PNGToHICON(Base64.PNG.MENU_DEFAULT)) ; 菜单的恢复默认的图标 + LVContextMenu.SetIcon(TEXT.MENU_EXTRACT , "HICON:" Base64PNGToHICON(Base64.PNG.MENU_EXTRACT)) ; 菜单的提取目标的图标 + LVContextMenu.SetIcon(TEXT.MENU_OPEN , "HICON:" Base64PNGToHICON(Base64.PNG.MENU_FOLDER)) ; 菜单的目标目录的图标 + LVContextMenu.SetIcon(TEXT.MENU_RENAME , "HICON:" Base64PNGToHICON(Base64.PNG.MENU_RENAME)) ; 菜单的重新命名的图标 + LVContextMenu.SetIcon(TEXT.MENU_PROPERTIES, "HICON:" Base64PNGToHICON(Base64.PNG.MENU_PROPERTY)) ; 菜单快捷方式属性图标 + + ; 若当前列表快捷方式来源不是桌面,则给列表右键菜单选项添加一行"添加其至桌面" + If (folderListFrom != "Desktop") { + LVContextMenu.Add() + LVContextMenu.Add(TEXT.MENU_ADD_LINK_TO_DESKTOP, (*) => AddLinkToDesktop) + LVContextMenu.SetIcon(TEXT.MENU_ADD_LINK_TO_DESKTOP, "HICON:" Base64PNGToHICON(Base64.PNG.MENU_DESKTOP)) } - link_infor := Menu() - link_infor.Add(Text.COPY_LINK_TARGET_PATH . link_target_path, (*) => (A_Clipboard := link_target_path)) - link_infor.Add - link_infor.Add(Text.COPY_LINK_TARGET_DIR . link_target_dir, (*) => (A_Clipboard := link_target_dir)) - link_infor.Add - link_infor.Add(Text.COPY_LINK_PATH . link_path, (*) => (A_Clipboard := link_path)) - link_infor.Add - link_infor.Add(Text.COPU_LINK_DIR . link_dir, (*) => (A_Clipboard := link_dir)) - link_infor.Add - link_infor.Add(Text.COPY_LINK_ICON_PATH . Link_Attribute.IconLocation, (*) => (A_Clipboard := Link_Attribute.IconLocation)) - link_menu.Add - link_menu.Add(Text.MENU_PROPERTIES, link_infor) - - hIcon := DllCall_Get_Icon(link_path) ; 调用DllCall函数显示该项目的图标 - link_menu.SetIcon(Text.MENU_RUN, "HICON:" hIcon) - DllCall("DestroyIcon", "ptr", hIcon) ; 释放hIcon - link_menu.SetIcon(Text.MENU_CHANGE, "HICON:" Base64PNG_to_HICON(MENU_CHANGE_PNG_BASE64)) ; 菜单的改变图标的图标 - link_menu.SetIcon(Text.MENU_RESTORE, "HICON:" Base64PNG_to_HICON(MENU_DEFAULT_PNG_BASE64)) ; 菜单的恢复默认的图标 - link_menu.SetIcon(Text.MENU_OPEN, "HICON:" Base64PNG_to_HICON(MENU_FOLDER_PNG_BASE64)) ; 菜单的目标目录的图标 - link_menu.SetIcon(Text.MENU_RENAME, "HICON:" Base64PNG_to_HICON(MENU_RENAME_PNG_BASE64)) ; 菜单的重新命名的图标 - link_menu.SetIcon(Text.MENU_PROPERTIES, "HICON:" Base64PNG_to_HICON(MENU_PROPERTY_PNG_BASE64)) ; 菜单的快捷方式属性的图标 - - If ((link_target_path = Text.SAFE_UNAVAILABLE)) ; 若选择与焦点行为UWP应用或APP应用,将"恢复默认图标"和"打开目标目录"的功能禁止 - { - link_menu.Disable(Text.MENU_RESTORE) - link_menu.Disable(Text.MENU_OPEN) + ; 若选择与焦点行为UWP应用或APP应用,将"恢复默认图标"和"打开目标目录"的功能禁止 + If ((linkTargetPath = TEXT.SAFE_UNAVAILABLE)) { + LVContextMenu.Disable(TEXT.MENU_RESTORE) + LVContextMenu.Disable(TEXT.MENU_OPEN) + ; linkIconLocation ? False : LVContextMenu.Disable(TEXT.MENU_EXTRACT) } - link_menu.Show() + LVContextMenu.Show() - Link_Restore(*) ; 恢复快捷方式的默认图标的函数 - { - ; 若图标为默认图标则返回 ; 否则恢复为默认图标并保存 - If ((Link_Icon_Location = link_target_path) OR (!Link_Icon_Location)) + RestoreLinkIconsToDefault(*) { + ; 若图标为默认图标则返回 + If ((linkIconLocation = linkTargetPath) OR (!linkIconLocation)) Return - Link_Attribute.IconLocation := link_target_path - Link_Attribute.Save() - ; 更新显示的数据 - If (LV.GetText(Item, 2) = "√") - { - MyGui["Changed_Count"].Value -= 1 - MyGui["Unchanged_Count"].Value += 1 + + objLink.IconLocation := linkTargetPath + objLink.Save() + + ; 更新显示的数据(若此前已更换过图标,则执行更新) + If (LV.GetText(Item, 2) = "√") { + mainGUI["countOfChanged"].Value -= 1 + mainGUI["countOfUnchanged"].Value += 1 } - ; 刷新显示、列表图标,目标行删除"√" - Refresh_Display_Icon(LV, Item) - Refresh_LV_Icon(LV, Item) + + RefreshIconDisplay(LV, Item, IsRefreshListIcon:=True) ; 刷新显示并修改Y/N LV.Modify(Item,,,"") - ; 添加至日志 - MyGui["Log"].Value .= FormatTime(A_Now, "`syyyy/MM/dd HH:mm:ss`n`s") - . Text.LOG_RESTORE_LINK . link_name . "`n`n===========================================`n`n" + + RefreshExplorer() + + mainGUI['log'].Value .= FormatTime(A_Now, "`syyyy/MM/dd HH:mm:ss`n`s") + . TEXT.LOG_RESTORE_LINK . linkName . "`n`n===========================================`n`n" } - Link_Rename(*) ; 重命名快捷方式名称的函数 - { - MyGui.Opt("+OwnDialogs") ; 解除对话框后才可于GUI窗口交互 - ; 重命名输入窗口 - IB := InputBox(Text.RENAME_NEW_NAME, link_name, "W300 H100", Trim(link_name)) - If (IB.Result = "CANCEL") + ExtractLinkIcon(*) { + ; 无法检测系统环境变量如%windir%,如%windir%\system32\Speech\SpeechUX\sapi.cpl,5 + RegExMatch(linkIconLocation, 'i)^%[^%]+%', &environmentVariables) + + If environmentVariables { + Switch StrLower(environmentVariables[]) { + Case '%windir%' : linkIconLocation := RegExReplace(linkIconLocation, 'i)^%[^%]+%', A_WinDir) + Case '%systemroot%' : linkIconLocation := RegExReplace(linkIconLocation, 'i)^%[^%]+%', A_WinDir) + Case '%programfiles%' : linkIconLocation := RegExReplace(linkIconLocation, 'i)^%[^%]+%', 'C:\Program Files') + Case '%programfiles(x86)%' : linkIconLocation := RegExReplace(linkIconLocation, 'i)^%[^%]+%', 'C:\Program Files (x86)') + Case '%programfiles(arm)%' : linkIconLocation := RegExReplace(linkIconLocation, 'i)^%[^%]+%', 'C:\Program Files (ARM)') + Case '%systemdrive%' : linkIconLocation := RegExReplace(linkIconLocation, 'i)^%[^%]+%', 'C:') + } + } + + Switch RegExReplace(linkIconLocation, '.+\.') { + Case 'ico' : + If Msgbox(TEXT.LINK_ICON_FROM_EXIST_ICO,,'Iconi OKCancel') = 'Cancel' + Return + ; 没有自带loop检测重复名称,需另检测 + iconName := linkName + Loop ; 重复的名称 + iconName := (A_Index = 2) ? iconName '_1' : RegExReplace(iconName, '_\d+$', '_' (A_Index-1)) + Until !FileExist(A_Desktop '\' iconName '.ico') + FileCopy(linkIconLocation, A_desktop '\' iconName '.ico') + Case 'dll' : + RegExMatch(objLink.IconLocation, '-?\d+$', &iconNumber) + index := iconNumber[]+1 + ConvertToIconFile.Dll( {dllName:linkIconLocation, index:index, size:0, iconName:linkName} ) + Case 'exe' : + RegExMatch(objLink.IconLocation, '-?\d+$', &iconNumber) + index := (iconNumber[] = -1) ? 1 : iconNumber[]+1 ; 特殊情况:检测到的索引号是-1的exe提取不了图片,把索引号改为0(index := 0+1) + + If FileExist(linkIconLocation) and (index=1) { ; 如果exe存在0索引图标(iconNumber[]=0),则使用File + ConvertToIconFile.File( {path:linkIconLocation, iconName:linkName} ) + } Else { ; 可用于提取linkIconLocation为explorer.exe图标或其他完整路径的exe且有索引号的图标 + ConvertToIconFile.Dll( {dllName:linkIconLocation, index:index, size:0, iconName:linkName} ) + } + Case '' : + path := FileExist(linkTargetPath) ? linkTargetPath : linkPath + ConvertToIconFile.File( {path:path, iconName:linkName} ) + Default : + If !FileExist(linkIconLocation) { + path := FileExist(linkTargetPath) ? linkTargetPath : linkPath + ConvertToIconFile.File( {path:path, iconName:linkName} ) + } Else { + RegExMatch(objLink.IconLocation, '-?\d+$', &iconNumber) + index := (iconNumber[] = -1) ? 1 : iconNumber[]+1 ; 特殊情况:检测到的索引号是-1的exe提取不了图片,把索引号改为0(index := 0+1) + If index=1 { ; 如果exe存在0索引图标(iconNumber[]=0),则使用File + ConvertToIconFile.File( {path:linkIconLocation, iconName:linkName} ) + } Else { + ConvertToIconFile.Dll( {dllName:linkIconLocation, index:index, size:0, iconName:linkName} ) + } + } + } + + If !FileExist(A_desktop '\' linkName '.ico') + Return Msgbox(TEXT.FAILED_TO_EXTRACT) + TrayTip(TEXT.EXTRACTED, "Ciallo~(∠・ω< )⌒★", "Mute"), SetTimer(TrayTip, -5000) + } + + RenameLink(*) { + mainGUI.Opt("+OwnDialogs") + + IB := InputBox(TEXT.RENAME_NEW_NAME, linkName, "W300 H100", Trim(linkName)) ; 重命名输入窗口 + If IB.Result = "CANCEL" Return - ; 排除重复名称 - IB.Value := RegExReplace(IB.Value, "i).lnk$") - Loop LV.GetCount() - { + IB.Value := RegExReplace(IB.Value, "i)\.lnk$") + + Loop LV.GetCount() { ; 排除重复名称 If IB.Value = LV.GetText(A_Index, 1) Return MsgBox(TEXT.SAME_NAME, "(・∀・(・∀・(・∀・*)", "icon!") } - ; 赋予新名称给变量,然后重命名 - new_link_path := link_dir . "\" . IB.Value . ".lnk" - FileMove(link_path, new_link_path) - ; 重命名后,添加新的键值和删除旧的键值于映射数组 - new_key := IB.Value . LV.GetText(Item, 3) - link_map[new_key] := {LP:new_link_path, LD:link_dir, LTP:link_target_path, LTD:link_target_dir} - link_map.Delete(key) - ; 记录日志 - MyGui["Log"].Value .= FormatTime(A_Now, "`syyyy/MM/dd HH:mm:ss`n`s") - . Text.LOG_OLD_NAME . link_name . "`n`s" - . Text.LOG_NEW_NAME . IB.Value . "`n`n===========================================`n`n" - ; 更新列表快捷方式名称(最后更新可避免过早更新使映射数组中的link_name发生改变而不能删除对应键值) - LV.Modify(Item,, IB.Value) + + new_linkPath := linkDir . "\" . IB.Value . ".lnk" ; 新路径 + FileMove(linkPath, new_linkPath) ; 重命名 + + new_linkID := IB.Value . LV.GetText(Item, 3) ; 重命名后,快捷方式属性数组添加新键值和删除旧键值 + MapLinkProp[new_linkID] := {LP:new_linkPath, LD:linkDir, LTP:linkTargetPath, LTD:linkTargetDir} + MapLinkProp.Delete(linkID) + + mainGUI['log'].Value .= FormatTime(A_Now, "`syyyy/MM/dd HH:mm:ss`n`s") + . TEXT.LOG_OLD_NAME . linkName . "`n`s" + . TEXT.LOG_NEW_NAME . IB.Value . "`n`n===========================================`n`n" + + LV.Modify(Item,, IB.Value) ; 更新列表中的快捷方式名称 } - Link_Add_Desktop(*) ; 添加当前快捷方式至桌面的函数 - { - Try - { - FileCopy(link_path, A_Desktop) + AddLinkToDesktop(*) { + Try { + If FileExist(A_Desktop '\' linkName '.' linkExt) { + If Msgbox('桌面已存在相同名称的快捷方式,是否继续创建?',,'iconi OKCancel')='Cancel' + Return + + Loop + duplicateNmae := (A_Index = 2) ? duplicateNmae '_1' : RegExReplace(duplicateNmae, '_\d+$', '_' (A_Index-1)) + Until !FileExist(A_Desktop '\' duplicateNmae '.' linkExt) + } - MyGui["Log"].Value .= FormatTime(A_Now, "`syyyy/MM/dd HH:mm:ss`n`s") ; 添加至日志 - . "“`s" . link_name . "`s”被添加至当前用户的桌面" . "`n`n===========================================`n`n" + FileCopy(linkPath, A_Desktop) - Msgbox("成功添加“`s" . link_name . "`s”至当前用户的桌面", "Ciallo~(∠・ω< )⌒★") - } - Catch Error - { - Msgbox(Text.ERROE_ADD_LINK_TO_DESKTOP,, "Icon!") + mainGUI['log'].Value .= FormatTime(A_Now, "`syyyy/MM/dd HH:mm:ss`n`s") + . "“`s" . linkName . "`s”被添加至当前用户的桌面" . "`n`n===========================================`n`n" + + Msgbox("成功添加“`s" . linkName . "`s”至当前用户的桌面", "Ciallo~(∠・ω< )⌒★") + } Catch { + Msgbox(TEXT.ERROE_ADD_LINK_TO_DESKTOP,, "Icon!") Return } } @@ -843,297 +843,241 @@ LV_Context_Menu(LV, Item, IsRightClick, X, Y) ;========================================================================== ; 在列表中搜索含有关键词的项目的函数 ;========================================================================== -Search(*) -{ - ; 若搜索框未输入文本,则提示“请输入”并返回 - If (MyGui["Search_Edit"].Value = "") - Return (ToolTip(Text.PLEASE_INPUT, 280*(A_ScreenDPI/96), 70*(A_ScreenDPI/96)) AND SetTimer((*) => ToolTip(), -2000)) - ; 搜索框为焦点,暂时允许列表多行选择, 取消聚焦列表行 - MyGui["Search_Edit"].Focus() - LV.Opt("+Multi"), LV.Modify(0, "-Select -Focus") - ; 从列表中搜索目标,并刷新显示图标,选择、聚焦目标行 - Loop LV.GetCount() - { - If (!InStr(LV.GetText(A_Index), Trim(MyGui["Search_Edit"].Value))) +Search(*) { + If mainGUI["searchEditCtrl"].Value = '' + Return (ToolTip(TEXT.PLEASE_INPUT, 280*(A_ScreenDPI/96), 70*(A_ScreenDPI/96)) AND SetTimer((*) => ToolTip(), -2000)) + + mainGUI["searchEditCtrl"].Focus() + LV.Opt("+Multi") ; 暂时允许列表多行选择 + LV.Modify(0, "-Select -Focus") + + Loop LV.GetCount() { + If (!InStr(Trim(LV.GetText(A_Index)), Trim(mainGUI["searchEditCtrl"].Value))) Continue Sleep(300) - LV.Modify(A_Index, "+Select +Focus +Vis") - Refresh_Display_Icon(LV, A_Index) + LV.Modify(A_Index, "+Select +Focus +Vis") ; 聚焦该列表项目 + RefreshIconDisplay(LV, A_Index) } + ; 禁止列表多行选择(不影响之前的多行选择) LV.Opt("-Multi") - ; 若未搜寻到目标,则提示“未找到”并返回(利用未寻到目标时焦点在搜索框的机制) - If (ControlGetFocus("A") = MyGui["Search_Edit"].hWnd) - Return (ToolTip(Text.NOT_FOUND, 280*(A_ScreenDPI/96), 70*(A_ScreenDPI/96)) AND SetTimer((*) => ToolTip(), -2000)) + + If (ControlGetFocus("A") = mainGUI["searchEditCtrl"].hWnd) ; 若无目标,则提示“未找到”并返回(利用未寻到目标时焦点在搜索框的机制) + Return (ToolTip(TEXT.NOT_FOUND, 280*(A_ScreenDPI/96), 70*(A_ScreenDPI/96)) AND SetTimer((*) => ToolTip(), -2000)) } ;========================================================================== ; 更换所有快捷方式图标的函数 ;========================================================================== -Change_All_Shortcut_Icons(*) -{ - MyGui.Opt("+OwnDialogs") ; 解除对话框后才可于GUI窗口交互 - ; 访问ini,打开上一次打开的存放ICO的文件夹,并更新ini里的上一次打开的图标文件夹路径 - Try - { - last_selected_folder_path := iniRead(info_ini_path, "info", "last_icons_folder_path") - } - Catch - { - Msgbox("the info.ini does not have an option named `"last_icons_folder_path`" ",,"icon!") - } - If not (selected_folder_path := DirSelect("*" . last_selected_folder_path, 0, Text.SELECT_ICONS_FOLDER)) +ChangeAllLinksIcons(*) { + mainGUI.Opt("+OwnDialogs") + + ; 访问ini,选择存放ICO文件夹(默认打开上一次),更新ini + lastSelectedIconFolderPath := iniRead(iniPath, "info", "lastSelectedIconFolderPath") + If not (selectedFolderPath := DirSelect("*" . lastSelectedIconFolderPath, 0, TEXT.SELECT_ICONS_FOLDER)) Return - iniWrite(selected_folder_path, info_ini_path, "info", "last_icons_folder_path") - ; 创建数组 - changed_log_msgbox := "" - map_iconName_iconPath := map() - map_both_name_same := map() - ; 以被选择文件夹的图标名称为键,图标路径为值添加至映射数组(R:扫描包括子文件夹的文件) - Loop Files, selected_folder_path "\*.ico", "R" - { - map_iconName_iconPath[RegExReplace(A_LoopFileName, "i)\.ico$")] := A_LoopFilePath - } - ; 若选择文件夹无图标则提醒并返回 - If !map_iconName_iconPath.Count - Return (Msgbox("There is no icon in the folder", "(っ °Д °;)っ")) - ; 提醒正在扫描、更换图标,在完成扫描、更换操作前禁止与GUI交互 - TrayTip(Text.CHANGING) - MyGui.Opt("+Disabled") - ; 从图标组合中枚举,并从列表开头开始循环 - For icon_name, icon_path in map_iconName_iconPath - { - no_space_icon_name := RegExReplace(icon_name, "[`s`n`t]") - Loop LV.GetCount() - { - link_name := LV.GetText(A_Index, 1) - key := link_name . LV.GetText(A_Index, 3) - no_space_link_name := RegExReplace(link_name, "[`s`n`t]") - - ; 若快捷方式已更换过与快捷方式相同名称的ICO图标,则跳过这一次循环(比如QQ音乐软件换了"QQ音乐"图标后,可能会更换"QQ"图标,因此需要截停) - ; 注意:不能根据列表"√"来跳过循环(比如QQ音乐先换了"QQ"图标,要是跳过就不能换"QQ音乐"图标) - ; 注意:若要跳过这一次循环,用Continue,Return会退出所有循环和函数 - If (map_both_name_same.has(key) OR (map_both_name_same.has(key))) - Continue + iniWrite(selectedFolderPath, iniPath, "info", "lastSelectedIconFolderPath") + + changedLog := '' + MapMatchName := map() + + mainGUI.Opt("+Disabled") + TrayTip(TEXT.CHANGING) + + Loop Files, selectedFolderPath "\*.ico", "R" { + iconName := RegExReplace(A_LoopFileName, 'i)\.ico$') + iconPath := A_LoopFilePath + noSpacesIconName := RegExReplace(iconName, "[`s`n`t]+") + + Loop LV.GetCount() { + linkName := LV.GetText(A_Index, 1) + linkExt := LV.GetText(A_Index, 3) + linkID := linkName . linkExt + noSpacesLinkName := RegExReplace(linkName, "[`s`n`t]+") + + If MapMatchName.has(linkID) ; 若数组已存在快捷方式唯一ID,则表明上一次快捷方式和图标完全匹配,再次扫描到该快捷方式时无需在更换,然后跳过本次循环 + Continue ; 使用Continue跳过本次循环,Return会退出整个函数 + ; 根据快捷方式和图标名称长度来检查二者的包含关系,包含则更换,不包含执行下一次循环 - ; 优势:部分应用因版本不同而快捷方式名称不同,如Adobe PhtotShop 2024/2023/2022,使用该方法可以使图标名称只要是"PhtotShop即可匹配更换 - ; 缺点:部分应用名称重叠,导致如QQ音乐换了"QQ"图标 - Switch VerCompare(StrLen(no_space_link_name), StrLen(no_space_icon_name)) - { - Case -1: - If !InStr(no_space_icon_name, no_space_link_name) - Continue - Case 1: - If !InStr(no_space_link_name, no_space_icon_name) - Continue - Case 0: - If (no_space_link_name != no_space_icon_name) ; 若快捷方式名称与文件名称不同,则下一循环,相同给数组添加两个键 - Continue - map_both_name_same[key] := "SAME" ; 此处标记,后续扫描跳过第二个循环中的该快捷方式(注意:数组的键是区分大小写的) - map_both_name_same[key] := "SAME" ; 此处标记,后续扫描跳过第一个循环中的该图标(注意数组的键是区分大小写的) + ; 优势:匹配部分应用名称因版本不同等原因而快捷方式名称不同的情况,如软件Adobe PhtotShop 2024匹配图标名称PhtotShop + ; 缺点:部分应用与多个不合适的图标匹配,如软件"QQ音乐"更换了图标"QQ",但图标存在完全与应用名称匹配情况下,可解决该缺点 + Switch VerCompare(StrLen(noSpacesLinkName), StrLen(noSpacesIconName)) { + Case -1: + If !InStr(noSpacesIconName, noSpacesLinkName) + Continue + Case 1: + If !InStr(noSpacesLinkName, noSpacesIconName) + Continue + Case 0: + If (noSpacesLinkName != noSpacesIconName) + Continue + MapMatchName[linkID] := "SAME" ; 本次快捷方式名称和图标名称完全匹配,则添加至数组(注意:数组的键是区分大小写的) } - ; 获取快捷方式信息 - link_path := link_map[key].LP - COM_Link_Attribute(&Link_Path, &Link_Attribute, &Link_Icon_Location) - ; 若快捷方式图标的路径与文件图标的路径相同,则跳过这一次循环 - If (Link_Icon_Location = icon_path) + + linkPath := MapLinkProp[linkID].LP + ManageLinkProp(&objLink, &linkPath, &linkIconLocation) + + If (linkIconLocation = iconPath) ; 若快捷方式图标路径与文件图标路径相同,则跳过这一次循环 Continue - ; 更换图标并保存该操作 - Link_Attribute.IconLocation := icon_path - Link_Attribute.Save() - ; 更新显示的数据 - If (LV.GetText(A_Index, 2) = "") - { - MyGui["Changed_Count"].Value += 1 - MyGui["Unchanged_Count"].Value -= 1 + + objLink.IconLocation := iconPath + objLink.Save() + + ; 更新显示的数据(若此前未更换过图标,则执行更新) + If (LV.GetText(A_Index, 2) = "") { + mainGUI["countOfChanged"].Value += 1 + mainGUI["countOfUnchanged"].Value -= 1 } - ; 刷新显示和列表图标,选择、聚焦目标行并添加"√" - Refresh_Display_Icon(LV, A_Index) - Refresh_LV_Icon(LV, A_Index) + + RefreshIconDisplay(LV, A_Index, IsRefreshListIcon:=True) LV.Modify(A_Index, "+Select +Focus +Vis",,"√") - ; 记录被更换图标的软件,完成操作后显示 - changed_log_msgbox .= link_name . "`s=>`s" . icon_name . ".ico`n" - ; 添加至日志 - MyGui["Log"].Value .= FormatTime(A_Now, "`syyyy/MM/dd HH:mm:ss`n`s") + + ; 记录更换信息 + changedLog .= linkName . "`s=>`s" . iconName . ".ico`n" + + mainGUI['log'].Value .= FormatTime(A_Now, "`syyyy/MM/dd HH:mm:ss`n`s") . Text.LOG_CHANGED_LINK . LV.GetText(A_Index, 1) . "`n`s" - . Text.SOURCE_OF_ICON . icon_name . ".ico`n`n" + . Text.SOURCE_OF_ICON . iconName . ".ico`n`n" } } - MyGui["Log"].Value .= "======================================`n`n" - ; 恢复与窗口的交互 - MyGui.Opt("-Disabled") - ; 若未记录到更换信息,则显示“未更换任何图标” - If !changed_log_msgbox + mainGUI['log'].Value .= "===========================================`n`n" + mainGUI.Opt("-Disabled") + + If !changedLog Return (Msgbox(Text.NO_CHANGE, "╰( ̄ω ̄o)") and TrayTip) - Msgbox(changed_log_msgbox, Text.SUCCESS) - ; 更新托盘提醒 + + RefreshExplorer(), Msgbox(changedLog, Text.SUCCESS) TrayTip - TrayTip(Text.COMPLETED,"Ciallo~(∠・ω< )⌒★", "Mute"), SetTimer(TrayTip, -2500) + TrayTip(Text.COMPLETED, "Ciallo~(∠・ω< )⌒★", "Mute"), SetTimer(TrayTip, -3000) } ;========================================================================== ; 恢复所有快捷方式的默认图标事件(UWP、APP不支持恢复默认) ;========================================================================== -Restore_All_Shortcut_Icons(*) -{ - MyGui.Opt("+OwnDialogs") ; 解除对话框后才可于GUI窗口交互 - ; 提醒UWP、APP不支持恢复默认 +RestoreAllLinksIconsToDefault(*) { + mainGUI.Opt("+OwnDialogs") + If Msgbox(Text.IS_RESTORE_ALL_ICON, "Ciallo~(∠・ω< )⌒★", "OKCancel Icon? Default2") = "Cancel" Return - ; 循环恢复 - Loop LV.GetCount() - { + + mainGUI.Opt("+Disabled") ; 禁止与GUI交互 + + Loop LV.GetCount() { If ((LV.GetText(A_Index, 2) != "√") OR (LV.GetText(A_Index, 3) = "uwp")) Continue - - link_name := LV.GetText(A_Index, 1) - key := link_name . LV.GetText(A_Index, 3) - link_path := link_map[key].LP - link_target_path := link_map[key].LTP - ; 获取快捷方式的属性,并恢复默认图标(即更换为目标文件图标) - COM_Link_Attribute(&Link_Path, &Link_Attribute, &Link_Icon_Location) - Link_Attribute.IconLocation := link_target_path - Link_Attribute.Save() - ; 更新显示的数据 - If (LV.GetText(A_Index, 2) = "√") - { - MyGui["Changed_Count"].Value -= 1 - MyGui["Unchanged_Count"].Value += 1 + linkName := LV.GetText(A_Index, 1) + linkExt := LV.GetText(A_Index, 3) + linkID := linkName . linkExt + linkPath := MapLinkProp[linkID].LP + linkTargetPath := MapLinkProp[linkID].LTP + + ManageLinkProp(&objLink, &linkPath, &linkIconLocation) + objLink.IconLocation := linkTargetPath + objLink.Save() + + ; 更新显示的数据(若此前更换过图标,则执行更新) + If (LV.GetText(A_Index, 2) = "√") { + mainGUI["countOfChanged"].Value -= 1 + mainGUI["countOfUnchanged"].Value += 1 } - ; 刷新显示和列表图标,选择、聚焦目标行并删除"√" - Refresh_Display_Icon(LV, A_Index) - Refresh_LV_Icon(LV, A_Index) + + RefreshIconDisplay(LV, A_Index, IsRefreshListIcon:=True) LV.Modify(A_Index, "+Select +Focus +Vis",,"") - ; 添加至日志 - MyGui["Log"].Value .= FormatTime(A_Now, "`syyyy/MM/dd HH:mm:ss`n`s") + + mainGUI['log'].Value .= FormatTime(A_Now, "`syyyy/MM/dd HH:mm:ss`n`s") . Text.LOG_RESTORE_LINK . LV.GetText(A_Index, 1) . "`n`n" } - MyGui["Log"].Value .= "======================================`n`n" - ; 提醒 - TrayTip(Text.COMPLETED,"Ciallo~(∠・ω< )⌒★","Mute"), SetTimer(TrayTip, -2500) + mainGUI['log'].Value .= "===========================================`n`n" + mainGUI.Opt("-Disabled") + + RefreshExplorer() + + TrayTip(Text.COMPLETED, "Ciallo~(∠・ω< )⌒★", "Mute"), SetTimer(TrayTip, -3000) } ;========================================================================== ; 清空列表中的快捷方式的函数 ;========================================================================== -Clean_LV(*) -{ - LV.Delete() ; 清空列表 - link_map.Clear() ; 清空数组 - MyGui["Changed_Count"].Value := 0 - MyGui["Unchanged_Count"].Value := 0 - MyGui["Total_Count"].Value := 0 +ClearData(*) { + clearList(), clearMap(), resetCount() + clearList() => LV.Delete() + clearMap() => MapLinkProp.Clear() + resetCount() => (mainGUI["countOfChanged"].Value := 0, mainGUI["countOfUnchanged"].Value := 0, mainGUI["countOfTotal"].Value := 0) } ;========================================================================== -; 重新添加桌面快捷方式至列表的函数 +; 添加指定文件夹的快捷方式至列表 ;========================================================================== -Add_Desktop_To_LV(*) -{ - MyGui.Opt("+OwnDialogs") ; 解除对话框后才可于GUI窗口交互 - ; 确认操作 - If Msgbox(Text.IS_ADD_DESKTOP_TO_LV, "Ciallo~(∠・ω< )⌒★", "Icon? OKCancel") = "Cancel" - Return - ; 清空列表、计数、数组 - Clean_LV() - ; 更新列表的快捷方式来源的变量为桌面 - global LV_link_from := "Desktop" - ; 添加桌面快捷方式 - For Desktop in [A_Desktop, A_DesktopCommon] - { - Add_Folder_Link_To_LV(Desktop, Mode := "") +AddShortcutToList(shortcutFolderPath) { + Switch folderListFrom := shortcutFolderPath { + Case 'Desktop' : + textIsAdd := Text.IS_ADD_DESKTOP_TO_LV + textAdded := Text.ADD_DESKTOP_TO_LV + ArrayLinkFolderPath := [A_Desktop, A_DesktopCommon] + Case 'Start' : + textIsAdd := Text.IS_ADD_START_TO_LV + textAdded := Text.ADD_START_TO_LV + ArrayLinkFolderPath := [A_StartMenu, A_StartMenuCommon] + Case 'Other' : + textIsAdd := Text.IS_ADD_OTHER_TO_LV + textAdded := Text.ADD_OTHER_TO_LV } - ; 刷新计数 - MyGui["Total_Count"].Value := LV.GetCount() - MyGui["Unchanged_Count"].Value := LV.GetCount() - MyGui["Changed_Count"].Value - ; 添加至日志 - MyGui["Log"].Value .= FormatTime(A_Now, "`syyyy/MM/dd HH:mm:ss`n`s") - . Text.ADD_DESKTOP_TO_LV . "`n`n===========================================`n`n" - ; 返回主页 - ControlClick(MyGui[StrReplace(tab_prop.label_name[1], "`s") . "_Tab_BUTTON"]) -} + mainGUI.Opt("+OwnDialogs") -;========================================================================== -; 添加开始(菜单)中的快捷方式至列表的函数 -;========================================================================== -Add_Sart_To_LV(*) -{ - MyGui.Opt("+OwnDialogs") ; 解除对话框后才可于GUI窗口交互 - ; 确认是否添加 - If Msgbox(Text.IS_ADD_START_TO_LV, "Ciallo~(∠・ω< )⌒★", "Icon? OKCancel") = "Cancel" + If Msgbox(textIsAdd, "Ciallo~(∠・ω< )⌒★", "Icon? OKCancel") = "Cancel" Return - ; 清空列表、计数、数组 - Clean_LV() - ; 更新列表的快捷方式来源的变量为开始菜单 - global LV_link_from := "Start" - ; 将当前用户、所有用户的开始(菜单)中的快捷方式添加至列表中 - For Value in [A_StartMenu, A_StartMenuCommon] - { - Add_Folder_Link_To_LV(Value, Mode := "R") + + If folderListFrom = 'Other' { + lastSelectedLinkFolderPath := iniRead(iniPath, "info", "lastSelectedLinkFolderPath") + + ; 选择目录(默认为上一次选择的目录) + If not (selectedLinkFolderPath := DirSelect("*" . lastSelectedLinkFolderPath, 0, Text.SELECT_ICONS_FOLDER)) + Return + + ; 检查文件夹名称的最后一个字符是否为反斜杠(避免文件名包含"\",导致最终变成C:**\**\\这种错误格式) + (SubStr(selectedLinkFolderPath, -1, 1) = "\") ? (selectedLinkFolderPath := SubStr(selectedLinkFolderPath, 1, -1)) : False + iniWrite(selectedLinkFolderPath, iniPath, "info", "lastSelectedLinkFolderPath") + + folderListFrom := RegExReplace(selectedLinkFolderPath, "^.*\\") + + ArrayLinkFolderPath := [selectedLinkFolderPath] } - ; 刷新计数 - MyGui["Total_Count"].Value := LV.GetCount() - MyGui["Unchanged_Count"].Value := LV.GetCount() - MyGui["Changed_Count"].Value - ; 添加至日志 - MyGui["Log"].Value .= FormatTime(A_Now, "`syyyy/MM/dd HH:mm:ss`n`s") - . Text.ADD_START_TO_LV . "`n`n===========================================`n`n" + + ClearData() + ; 返回主页 - ControlClick(MyGui[StrReplace(tab_prop.label_name[1], "`s") . "_Tab_BUTTON"]) - TrayTip(Text.COMPLETED,"Ciallo~(∠・ω< )⌒★","Mute"), SetTimer(TrayTip, -2500) -} + ControlClick(mainGUI[StrReplace(tabProp.labelName[1], "`s") . "_TAB_BUTTON"]) + ; 添加至桌面快捷方式 + For value in ArrayLinkFolderPath { + AddLinksFromFolderToLV(value, Mode := (shortcutFolderPath='Desktop' ? '':'R')) + } -;========================================================================== -; 添加其他文件夹的快捷方式至列表中 -;========================================================================== -Add_Other_To_LV(*) -{ - MyGui.Opt("+OwnDialogs") ; 解除对话框后才可于GUI窗口交互 - ; 确认是否添加 - If Msgbox(Text.IS_ADD_OTHER, "Ciallo~(∠・ω< )⌒★", "Icon? OKCancel") = "Cancel" - Return - ; 访问ini - last_selected_other_path := iniRead(info_ini_path, "info", "last_selected_other_path") - ; 选择目录 - If not (selected_other_path := DirSelect("*" . last_selected_other_path, 0, Text.SELECT_ICONS_FOLDER)) - Return - ; 检查文件夹名称的最后一个字符是否为反斜杠(避免文件名包含"\",导致最终变成C:**\**\\这种错误格式) - (SubStr(selected_other_path, -1, 1) = "\") ? (selected_other_path := SubStr(selected_other_path, 1, -1)) : False - ; 写入ini - iniWrite(selected_other_path, info_ini_path, "info", "last_selected_other_path") - ; 清空列表、计数、数组 - Clean_LV() - ; 更新列表的快捷方式来源的变量为其他文件夹 - global LV_link_from := RegExReplace(selected_other_path, "^.*\\") - ; 将文件夹及其子文件夹的快捷方式添加至列表中 - Add_Folder_Link_To_LV(selected_other_path, Mode := "R") ; 刷新计数 - MyGui["Total_Count"].Value := LV.GetCount() - MyGui["Unchanged_Count"].Value := LV.GetCount() - MyGui["Changed_Count"].Value + mainGUI["countOfTotal"].Value := LV.GetCount() + mainGUI["countOfUnchanged"].Value := LV.GetCount() - mainGUI["countOfChanged"].Value + ; 添加至日志 - MyGui["Log"].Value .= FormatTime(A_Now, "`syyyy/MM/dd HH:mm:ss`n`s") - . Text.ADD_OTHER_TO_LV . "`n`n===========================================`n`n" - ; 返回主页 - ControlClick(MyGui[StrReplace(tab_prop.label_name[1], "`s") . "_Tab_BUTTON"]) - TrayTip(Text.COMPLETED,"Ciallo~(∠・ω< )⌒★","Mute"), SetTimer(TrayTip, -2500) + mainGUI['log'].Value .= FormatTime(A_Now, "`syyyy/MM/dd HH:mm:ss`n`s") + . textAdded . "`n`n===========================================`n`n" + + TrayTip(Text.COMPLETED,"Ciallo~(∠・ω< )⌒★","Mute"), SetTimer(TrayTip, -2500) } + ;========================================================================== ; 添加UWP、APP的快捷方式至桌面中的函数 ;========================================================================== -Add_UWP_APP_To_LV(*) -{ - MyGui.Opt("+OwnDialogs") ; 解除对话框后才可于GUI窗口交互 - ; 确认操作 - If Msgbox(Text.IS_ADD_UWP_APP_TO_LV, "Ciallo~(∠・ω< )⌒★","Icon? OKCancel") = "Cancel" +AddUwpAppToDesktop(*) { + mainGUI.Opt("+OwnDialogs") + If Msgbox(TEXT.IS_ADD_UWP_APP_TO_DESKTOP, "Ciallo~(∠・ω< )⌒★","Icon? OKCancel") = "Cancel" Return - ; 打开存放快捷方式的文件夹 Run("shell:AppsFolder") } @@ -1141,61 +1085,68 @@ Add_UWP_APP_To_LV(*) ;========================================================================== ; 备份列表中的快捷方式的函数 ;========================================================================== -Backup_LV_Link_To_Folder(*) -{ - MyGui.Opt("+OwnDialogs") ; 解除对话框后才可于GUI窗口交互 - ; 确认操作 - If Msgbox(Text.IS_BACKUP_TO_FOLDER . LV_link_from . FormatTime(A_Now, "_yyyy_MM_dd_HH_mm") . "`"", "Ciallo~(∠・ω< )⌒★","Icon? OKCancel") = "Cancel" +BackupLinksToFolder(*) { + mainGUI.Opt("+OwnDialogs") + If Msgbox(TEXT.IS_BACKUP_TO_FOLDER . folderListFrom . FormatTime(A_Now, "_yyyy_MM_dd_HH_mm") . "`"", "Ciallo~(∠・ω< )⌒★","Icon? OKCancel") = "Cancel" Return - ; 备份路径 - backup_folder_path := A_DesktopCommon . "\" . LV_link_from . FormatTime(A_Now, "_yyyy_MM_dd_HH_mm") - ; 存在重复文件夹,则创建新的文件夹 - backup_folder_path .= DirExist(backup_folder_path) ? "_repeat" : "" - ; 创建备份文件夹 - DirCreate(backup_folder_path) - ; 循环复制粘贴快捷方式至备份文件夹 - Loop LV.GetCount() - { - link_name := LV.GetText(A_Index, 1) - key := LV.GetText(A_Index, 1) . LV.GetText(A_Index, 3) - link_path := link_map[key].LP - FileCopy(Link_Path, backup_folder_path, 1) + + ; 若存在重复文件夹,则创建新的文件夹 + backupFolderPath := A_DesktopCommon . "\" . folderListFrom . FormatTime(A_Now, "_yyyy_MM_dd_HH_mm") + Loop + backupFolderPath := (A_Index = 2) ? backupFolderPath '_1' : RegExReplace(backupFolderPath, '_\d+$', '_' (A_Index-1)) + Until !DirExist(backupFolderPath) + DirCreate(backupFolderPath) + + Loop LV.GetCount() { + linkName := LV.GetText(A_Index, 1) + linkExt := LV.GetText(A_Index, 3) + linkID := linkName . linkExt + linkPath := MapLinkProp[linkID].LP + FileCopy(linkPath, backupFolderPath, 1) } - ; 添加至日志 - MyGui["Log"].Value .= FormatTime(A_Now, "`syyyy/MM/dd HH:mm:ss`n`s") - . Text.HAVE_BACKUP . StrReplace(backup_folder_path, A_DesktopCommon . "\") . "`n`n===========================================`n`n" - ; 提醒已完成 - TrayTip(Text.COMPLETED,"Ciallo~(∠・ω< )⌒★","Mute"), SetTimer(TrayTip, -2500) + + mainGUI['log'].Value .= FormatTime(A_Now, "`syyyy/MM/dd HH:mm:ss`n`s") + . Text.HAVE_BACKUP . StrReplace(backupFolderPath, A_DesktopCommon . "\") . "`n`n===========================================`n`n" + + TrayTip(Text.COMPLETED, "Ciallo~(∠・ω< )⌒★","Mute"), SetTimer(TrayTip, -2500) } ;========================================================================== ; 显示/隐藏展示icon窗口 ;========================================================================== -Show_Hide_iconGUI(*) -{ +ToggleIconGUIVisibility(*) { static isShow := False - If IsSet(iconGUI) and (isShow) - { + If IsSet(iconGUI) and (isShow) { iconGUI.Destroy() - MyGui["Show_iconGUI_Symbol"].Text := chr(0x2B9E) + mainGUI["showIconGUI_Symbol"].Text := chr(0xE291) isShow := False - } - Else - { - Create_iconGUI() - MyGui["Show_iconGUI_Symbol"].Text := chr(0x2B9C) - ; ControlClick(MyGui[StrReplace(tab_prop.label_name[1], "`s") . "_Tab_BUTTON"]) + } Else { + ShowIconGUI() + mainGUI["showIconGUI_Symbol"].Text := chr(0xE290) isShow := true } } +;========================================================================== +; 刷新资源管理器 +;========================================================================== +RefreshExplorer() { + static VT_UI4 := 0x13, SWC_DESKTOP := 0x8 + Windows := ComObject("Shell.Application").Windows + Windows.Item(ComValue(VT_UI4, SWC_DESKTOP)).Refresh() + For Process in Windows { + If (Process.Name = "Internet Explorer") + Continue + Process.Refresh() + } + } + ;========================================================================== ; 退出时关闭GDIP ;========================================================================== -ExitFunc(ExitReason, ExitCode) -{ +ExitFunc(ExitReason, ExitCode) { global ; gdi+ may now be shutdown on exiting the program Gdip_Shutdown(pToken) } \ No newline at end of file diff --git a/AHK_Language.ahk b/AHK_Language.ahk index 42bbcd5..995139d 100644 --- a/AHK_Language.ahk +++ b/AHK_Language.ahk @@ -1,29 +1,32 @@ -; zh: LCID_7804 := "Chinese"(中文) -; zh-Hans: LCID_0004 := "Chinese (中文简体)" -; zh-Hant: LCID_7C04 := "Chinese (中文繁体)" -; zh-CN: LCID_0804 := "Chinese (中文简体-中国大陆)" -; zh-HK: LCID_0C04 := "Chinese (中文繁体-中国香港)" -; zh-MO: LCID_1404 := "Chinese (中文繁体-中国澳门)" -; zh-TW: LCID_0404 := "Chinese (中文繁体-中国台湾)" -; zh-SG: LCID_1004 := "Chinese (中文简体-新加坡)" -Switch A_Language -{ -Case "0804": zh := True -Case "7804": zh := True -Case "0004": zh := True -Case "1004": zh := True -Case "7C04": zh := True -Case "0C04": zh := True -Case "1404": zh := True -Case "0404": zh := True -Default : zh := False + +/* + zh LCID_7804 = "Chinese(中文)" + zh-Hans LCID_0004 = "Chinese (中文简体)" + zh-Hant LCID_7C04 = "Chinese (中文繁体)" + zh-CN LCID_0804 = "Chinese (中文简体-中国大陆)" + zh-HK LCID_0C04 = "Chinese (中文繁体-中国香港)" + zh-MO LCID_1404 = "Chinese (中文繁体-中国澳门)" + zh-TW LCID_0404 = "Chinese (中文繁体-中国台湾)" + zh-SG LCID_1004 = "Chinese (中文简体-新加坡)" +*/ +Switch A_Language { + Case "0804": zh := True + Case "7804": zh := True + Case "0004": zh := True + Case "1004": zh := True + Case "7C04": zh := True + Case "0C04": zh := True + Case "1404": zh := True + Case "0404": zh := True + Default : zh := False } -; Note: This a object, not an array, ":" (√), ":="(×) -; Format: name_ZH and name_EN -Text := -{ + +Text := { + ;========================================================================== ; Label Name + ;========================================================================== + HOME_ZH : " 主 页" ,HOME_EN : " Home" @@ -31,10 +34,10 @@ Text := ,OTHER_EN : " Other" ,LOG_ZH : " 日 志" - ,LOG_EN : "Log " + ,LOG_EN : "Logs" ,HELP_ZH : " 设 置" - ,HELP_EN : " Settings" + ,HELP_EN : " Options" ,ABOUT_ZH : " 关 于" ,ABOUT_EN : " About" @@ -42,6 +45,7 @@ Text := ;========================================================================== ; Tab: Home ;========================================================================== + ; Count (计数) ,CHANGED_ICON_ZH : "已更换:" ,CHANGED_ICON_EN : "Yes.C`s:" @@ -68,6 +72,9 @@ Text := ,MENU_RESTORE_ZH : "恢复默认图标" ,MENU_RESTORE_EN : "Restore" + + ,MENU_EXTRACT_ZH : '提取文件图标' + ,MENU_EXTRACT_EN : 'Extract' ,MENU_OPEN_ZH : "打开目标目录" ,MENU_OPEN_EN : "Explore" @@ -105,22 +112,26 @@ Text := ,SAME_NAME_ZH : "存在重复名称,请重新命名" ,SAME_NAME_EN : "Duplicate name exists, please rename" + ,LINK_ICON_FROM_EXIST_ICO_ZH : '该快捷方式图标源于已存在的图标,是否复制它到桌面?' + ,LINK_ICON_FROM_EXIST_ICO_EN : "The shortcut s icon is from an existing .ico file, is it copied to the desktop?" + ;========================================================================== ; Tab: Other ;========================================================================== - ,ADD_DESKTOP_TO_LV_ZH : "重新加载桌面快捷方式至主页列表" - ,ADD_DESKTOP_TO_LV_EN : "Reload the desktop shortcuts" - ,ADD_START_TO_LV_ZH : "管理`"开始`"菜单的快捷方式的图标" - ,ADD_START_TO_LV_EN : "Manage shortcuts to Start Menu" + ,ADD_DESKTOP_TO_LV_ZH : ' 管理所有用户的桌面快捷方式的图标' ; "重新加载桌面快捷方式至主页列表" + ,ADD_DESKTOP_TO_LV_EN : 'Manage shortcuts from Desktops' ;"Reload the desktop shortcuts" + + ,ADD_START_TO_LV_ZH : " 管理系统开始菜单的快捷方式的图标" + ,ADD_START_TO_LV_EN : "Manage shortcuts from Start menu" - ,ADD_OTHER_TO_LV_ZH : "管理其他文件夹的快捷方式的图标" - ,ADD_OTHER_TO_LV_EN : "Manage shortcuts to other folder" + ,ADD_OTHER_TO_LV_ZH : " 管理其他的文件夹的快捷方式的图标" + ,ADD_OTHER_TO_LV_EN : "Manage shortcuts from Directories" - ,ADD_UWP_WSA_TO_LV_ZH : "添加UWP/WSA的快捷方式至桌面" - ,ADD_UWP_WSA_TO_LV_EN : "Add UWP/WSA shortcuts to desktop" + ,ADD_UWP_WSA_TO_LV_ZH : " 创建UWP或WSA等的桌面快捷方式" + ,ADD_UWP_WSA_TO_LV_EN : "Create UWP/APP desktop shortcuts" - ,BACKUP_LV_LINK_ZH : "备份列表的快捷方式至桌面文件夹" + ,BACKUP_LV_LINK_ZH : " 备份列表所有快捷方式至桌面文件夹" ,BACKUP_LV_LINK_EN : "Backup shortcuts to a desktop folder" ,ERROE_ADD_LINK_TO_DESKTOP_ZH : "桌面已存在相同名称的快捷方式" @@ -130,13 +141,13 @@ Text := ,IS_ADD_DESKTOP_TO_LV_EN : "Do you want to reload desktop shortcuts to the list and manage shortcuts on the home page?" ,IS_ADD_START_TO_LV_ZH : "是否添加`"开始`"菜单的快捷方式至列表,并在`"主页`"进行更换图标等操作?`n`s①对于开始菜单的快捷方式,不建议使用`"更换所有快捷方式图标`"的功能`n`s②右键可添加`"开始`"菜单的快捷方式至桌面`n`s③`"开始`"菜单的文件夹中不存在UWP应用" - ,IS_ADD_START_TO_LV_EN : "Do you want to add Start Menu shortcuts to the list and manage shortcuts on the home page?`n`s①It is not recommended to change the icons of all shortcuts in Start Menu`n`s②Context menu has the function called `"Add to the desktop`"`n`s③There are no UWP apps in Start Menu" + ,IS_ADD_START_TO_LV_EN : "Do you want to add Start menu shortcuts to the list and manage shortcuts on the home page?`n`s①It is not recommended to change the icons of all shortcuts in Start menu`n`s②Context menu has the function called `"Add to the desktop`"`n`s③There are no UWP apps in Start menu" - ,IS_ADD_OTHER_ZH : "是否添加其他文件夹的快捷方式至列表,并在`"主页`"进行更换图标等操作?" - ,IS_ADD_OTHER_EN : "Do you want to add shortcuts from other folder to the list and change icons on the home page?" + ,IS_ADD_OTHER_TO_LV_ZH : "是否添加其他文件夹的快捷方式至列表,并在`"主页`"进行更换图标等操作?" + ,IS_ADD_OTHER_TO_LV_EN : "Do you want to add shortcuts from other folder to the list and change icons on the home page?" - ,IS_ADD_UWP_APP_TO_LV_ZH : "是否添加UWP或APP等应用的快捷方式至桌面?`n`s①建议从(`"开始`"菜单--所有应用)中拖拽UWP/APP快捷方式至桌面`n`s②右键呼出菜单并添加指定的快捷方式至桌面" - ,IS_ADD_UWP_APP_TO_LV_EN : "Do you want to add UWP or APP shortcuts to the desktops?`n`s①Suggest dragging UWP or APP shortcuts from `"Start Menu--All Apps`" to the desktop`n`s②Context menu The menu has the function `"Add to the desktop`"" + ,IS_ADD_UWP_APP_TO_DESKTOP_ZH : "是否添加UWP或APP等应用的快捷方式至桌面?`n`s①建议从(`"开始`"菜单--所有应用)中拖拽UWP/APP快捷方式至桌面`n`s②右键呼出菜单并添加指定的快捷方式至桌面" + ,IS_ADD_UWP_APP_TO_DESKTOP_EN : "Do you want to add UWP or APP shortcuts to the desktops?`n`s①Suggest dragging UWP or APP shortcuts from `"Start menu--All Apps`" to the desktop`n`s②Context menu The menu has the function `"Add to the desktop`"" ,IS_BACKUP_TO_FOLDER_ZH : "是否备份列表的快捷方式至桌面文件夹——`"" ,IS_BACKUP_TO_FOLDER_EN : "Do you want to back up the list's shortcuts to a desktop folder named `"" @@ -207,6 +218,7 @@ Text := ;========================================================================== ; Tab: About ;========================================================================== + ,GITHUB_ZH : " 官 网" ,GITHUB_EN : "Github" @@ -221,19 +233,31 @@ Text := ,CONTRIBUTORS_ZH : " 贡献者" ,CONTRIBUTORS_EN : "Contributors" + + ;========================================================================== + ; IconGUI + ;========================================================================== + + ,EXTRACT_ICON_ZH : '提取图标至桌面' + ,EXTRACT_ICON_EN : 'Extract the icon to desktop' + + ,EXTRACTED_ZH : '已成功提取图标至桌面:' + ,EXTRACTED_EN : 'The icon have been successfully extracted to the desktop - ' + + ,FAILED_TO_EXTRACT_ZH : '提取图标失败,若有疑问,请前往Github提交ISSUES' + ,FAILED_TO_EXTRACT_EN : 'Failed to extract the icon, if in doubt, go to Github and submit ISSUES!' + + ,LINK_TARGET_NOT_EXIST_ZH : '快捷方式的目标文件不存在或路径错误' + ,LINK_TARGET_NOT_EXIST_EN : 'The target file of the shortcut does not exist or its path is wrong' } -For name, Descriptor in Text.OwnProps() -{ - If zh = True - { +For name, Descriptor in Text.OwnProps() { + If zh = True { If !Instr(name, "_ZH") Continue name := StrReplace(name, "_ZH") Text.%name%:=Descriptor - } - Else - { + } Else { If !Instr(name, "_EN") Continue name := StrReplace(name, "_EN") diff --git a/AHK_iconGUI.ahk b/AHK_iconGUI.ahk index 1e6e2dd..e0741fe 100644 --- a/AHK_iconGUI.ahk +++ b/AHK_iconGUI.ahk @@ -1,131 +1,148 @@ -Create_iconGUI(*) -{ +ShowIconGUI(*) { + ; 获取mainGUI的大小位置 + mainGUI.GetPos(&X, &Y, &Width, &Height) + ; 创建 iconGUI 窗口. - global iconGUI := Gui(" -Resize -caption +DPIScale +Owner" MyGui.hwnd) - iconGUI.SetFont("cffffff","Microsoft YaHei UI") - iconGUI.BackColor := "000000" - iconGUI.active_control := False + global iconGUI := Gui(" -Resize -caption +DPIScale +Owner" mainGUI.hwnd) + iconGUI.Morden := ModernGUI( {GUI:iconGUI, x:x+(Width+10)*(A_ScreenDPI/96), y:y, w:500/2, h:Height, backColor:"000000", GuiOpt:" -Resize -caption +DPIScale +Owner" mainGUI.hwnd, GuiName:"", GuiFontOpt:"cffffff s10", GuiFont:"Microsoft YaHei UI", showOpt:"NA"} ) + iconGUI.activeControl := False + ; 创建按钮 - iconGUI.AddButton("vTestButton1 x0 y0" " w" 250/2 " h" 78/2, TEXT.SYSTEM_ICONS_TITLE).OnEvent("click", iconGUI_Menu) - iconGUI.AddButton("vTestButton2 x" 250/2 " y0 w" 250/2 " h" 78/2, TEXT.USERS_ICONS_TITLE).OnEvent("click", Add_Users_Icons) - iconGUI["TestButton1"].Setfont("s10 cffffff") - iconGUI["TestButton2"].Setfont("s10 cffffff") - WinSetTransparent(80, iconGUI["TestButton1"].hwnd) - WinSetTransparent(80, iconGUI["TestButton2"].hwnd) + iconGUI.Button := CreateButton(iconGUI) + iconGUI.Button.Text( {name:"iconGUIBtn1", x:0 , y:0, w:250/2, h:60/2, R:0, normalColor:"2B2B2B", activeColor:"555555", text:TEXT.SYSTEM_ICONS_TITLE, textOpt:"+0x200 center", textHorizontalMargin:0, fontOpt:"cffffff", font:""} ) + iconGUI.Button.Text( {name:"iconGUIBtn2", x:250/2, y:0, w:250/2, h:60/2, R:0, normalColor:"2B2B2B", activeColor:"555555", text:TEXT.USERS_ICONS_TITLE , textOpt:"+0x200 center", textHorizontalMargin:0, fontOpt:"cffffff", font:""} ) + iconGUI.Button.OnEvent('iconGUIBtn1', 'Click', (*) => ShowMenuForIconGUI()) + iconGUI.Button.OnEvent('iconGUIBtn2', 'Click', (*) => AddUsersIconsToIconGUI()) + ; 大图标列表 - iconLV := iconGUI.Add("ListView", "viconLV x0 y" 78/2 " h" 572/2 " w" 500/2 " Background252525 -Multi -E0x200 +icon +LV0x10000", ["Icon", "Path"]) ; 创建 ListView. + global iconLV := iconGUI.Add("ListView", "viconLV x0 y" 60/2 " h" 550/2 " w" 500/2 " Background202020 -Multi -E0x200 +icon +LV0x10000", ["Icon", "Path"]) iconLV.SetFont("cf5f5f5 s12") - iconLV.OnEvent("DoubleClick", iconLV_DoubleCick) - ; 添加图标 - Add_Icon_dll_GUI("shell32.dll", "dll") - ; 深色模式 - DllCall("uxtheme\SetWindowTheme", "Ptr", iconLV.hWnd, "Str", "DarkMode_Explorer", "Ptr", 0) - ; 设置圆角 - FrameShadow(iconGUI.hwnd) - ; 获取MyGui的大小位置 - MyGui.GetPos(&X, &Y, &Width, &Height) - ; 显示窗口 - iconGUI.Show("x" (x+Width+10)*(A_ScreenDPI/96) " y" y*(A_ScreenDPI/96) " h" Height " w" 500/2 " NA") - ; 重绘按钮 - WinRedraw(iconGUI["TestButton1"].hwnd) - WinRedraw(iconGUI["TestButton2"].hwnd) - ; 设置鼠标在其上方的按钮 - icursor := "C:\Windows\Cursors\aero_link.cur" - DllCall("SetClassLongPtr", "ptr", iconGUI["TestButton1"].hwnd, "int", GCLP_HCURSOR := -12, "ptr", LoadPicture(icursor,"w" 28*(A_ScreenDPI/96) " h" 28*(A_ScreenDPI/96), &IMAGE_CURSOR := 2)) - - iconGUI_Menu(*) - { - iconsMenu := Menu() - iconsMenu.Add("shell32.dll", (*) => Add_Icon_dll_GUI("shell32.dll", "dll")) - iconsMenu.Add("imageres.dll", (*) => Add_Icon_dll_GUI("imageres.dll", "dll")) - iconsMenu.Add("mmres.dll", (*) => Add_Icon_dll_GUI("mmres.dll", "dll")) - iconsMenu.Add("ddores.dll", (*) => Add_Icon_dll_GUI("ddores.dll", "dll")) - iconsMenu.Add("explorer.exe", (*) => Add_Icon_dll_GUI("explorer.exe", "dll")) - iconsMenu.Add("imagesp1.dll", (*) => Add_Icon_dll_GUI("imagesp1.dll", "dll")) - iconsMenu.Add("pifmgr.dll", (*) => Add_Icon_dll_GUI("pifmgr.dll", "dll")) - iconsMenu.Add("networkexplorer.dll", (*) => Add_Icon_dll_GUI("networkexplorer.dll","")) - iconsMenu.Show(0, 39*(A_ScreenDPI/96)) - } + iconLV.OnEvent("DoubleClick", DoubleClickIconLV) + iconLV.OnEvent('ItemFocus' , RefreshStatusBar) + iconLV.OnEvent('ContextMenu', ShowMenuForIconLV) - Add_Users_Icons(*) - { - ; 访问ini,打开上一次打开的存放ICO的文件夹,并更新ini里的上一次打开的图标文件夹路径 - Try - { - last_selected_folder_path := iniRead(info_ini_path, "info", "last_icons_folder_path") - } - Catch - { - Msgbox("the info.ini does not have an option named `"last_icons_folder_path`" ",,"icon!") - } - If not (selected_folder_path := DirSelect("*" . last_selected_folder_path, 0, Text.SELECT_ICONS_FOLDER)) - Return - Add_Icon_dll_GUI(selected_folder_path, "") - } + ; 底部状态栏 + iconGUI.AddText('vstatusBar x0 y' 610/2 ' w' 560/2 ' h' 40/2 ' Background171717 +0x200', ' Name: #1') + iconGUI['statusBar'].SetFont('s8') - Add_Icon_dll_GUI(path, Is_dll_Icons) - { - global default_dll := path - iconLV.Opt("-Redraw") - iconLV.Delete() - If !Is_dll_Icons - { - global is_users_icons := False - icon_list_ID := IL_Create(,,"true") - iconLV.SetImageList(icon_list_ID) - Loop Files, path "\*.ico" - { - hIcon := DllCall_Get_Icon(A_LoopFilePath) - icon_number := DllCall("ImageList_ReplaceIcon", "Ptr", icon_list_ID, "Int", -1, "Ptr", hIcon) + 1 - DllCall("DestroyIcon", "ptr", hIcon) - iconLV.Add("Icon" . icon_number, A_Index, A_LoopFilePath) - } - } - Else - { - global is_users_icons := True - icon_list_ID := IL_Create(,,"true") - iconLV.SetImageList(icon_list_ID) - Loop ; 把 DLL 中的一系列图标装入图像列表. - { - If !IL_Add(icon_list_ID, path, A_Index) - Break - iconLV.Add("Icon" . A_Index+1, A_Index) - } - } - iconLV.Opt("+Redraw") + ; 添加图标 + If laseSelectedFolderPath := iniRead(iniPath, "info", "lastSelectedIconFolderPath") { + AddIconsToIconLV(laseSelectedFolderPath, IsAddDllIcons := False) + } Else { + AddIconsToIconLV("shell32.dll", IsAddDllIcons := True) } - iconLV_DoubleCick(*) - { - If !LV.GetNext() + ControlClick(mainGUI[StrReplace(tabProp.labelName[1], "`s") . "_TAB_BUTTON"]) + ; 深色模式 + DllCall("uxtheme\SetWindowTheme", "Ptr", iconLV.hWnd, "Str", "DarkMode_Explorer", "Ptr", 0) + ; 显示窗口 + iconGUI.Morden.Show() + + ;======================================================================================================== + ; 函数 + ;======================================================================================================== + DoubleClickIconLV(LV, Item, *) { + If !mainGUI['LV'].GetNext() or !iconLV.GetNext() or Tab.Value != "1" Return - ; 获取快捷方式数据 - link_name := LV.GetText(LV.GetNext()) - link_ext := LV.GetText(LV.GetNext(), "3") - key := link_name . link_ext - link_path := link_map[key].LP + ; 获取mainGUI的LV快捷方式数据 + linkName := mainGUI['LV'].GetText(mainGUI['LV'].GetNext(), 1) + linkExt := mainGUI['LV'].GetText(mainGUI['LV'].GetNext(), 3) + linkID := linkName . linkExt + linkPath := MapLinkProp[linkID].LP ; 更换图标 - COM_Link_Attribute(&Link_Path, &Link_Attribute, &Link_Icon_Location) - (!is_users_icons) ? (Link_Attribute.IconLocation := iconLV.GetText(iconLV.GetNext(), 2)) : (Link_Attribute.IconLocation := default_dll . "," . iconLV.GetNext()) - Link_Attribute.Save() + ManageLinkProp(&objLink, &linkPath, &linkIconLocation) + objLink.IconLocation := IsUsersIcons ? iconLV.GetText(Item, 2) : defaultDllName . "," . (Item-1) + objLink.Save() ; 更新显示的数据 - If !LV.GetText(LV.GetNext(), 2) - { - MyGui["Changed_Count"].Value += 1 - MyGui["Unchanged_Count"].Value -= 1 + If !mainGUI['LV'].GetText(mainGUI['LV'].GetNext(), 2) { + mainGUI["countOfChanged"].Value += 1 + mainGUI["countOfUnchanged"].Value -= 1 } ; 刷新顶部和列表图标,并目标行添加"√" - Refresh_Display_Icon(LV, LV.GetNext()) - Refresh_LV_Icon(LV, LV.GetNext()) - LV.Modify(LV.GetNext(),,,"√") + RefreshIconDisplay(mainGUI['LV'], mainGUI['LV'].GetNext(), IsRefreshListIcon := True) + mainGUI['LV'].Modify(mainGUI['LV'].GetNext(),,,"√") + RefreshExplorer() ; 添加日志 - icon_from := (!is_users_icons) ? (iconLV.GetText(iconLV.GetNext(), 2)) : default_dll . "," . iconLV.GetNext() - MyGui["Log"].Value .= FormatTime(A_Now, "`syyyy/MM/dd HH:mm:ss`n`s") - . Text.LOG_CHANGED_LINK . link_name . "`n`s" - . Text.Source_OF_ICON . icon_from . "`n`n===========================================`n`n" + iconFrom := (IsUsersIcons) ? (iconLV.GetText(Item, 2)) : defaultDllName "," Item + mainGUI["log"].Value .= FormatTime(A_Now, "`syyyy/MM/dd HH:mm:ss`n`s") + . Text.LOG_CHANGED_LINK . linkName . "`n`s" + . Text.Source_OF_ICON . iconFrom . "`n`n===========================================`n`n" + } + + RefreshStatusBar(LV, Item, *) { + iconName := (IsUsersIcons) ? RegExReplace(iconLV.GetText(Item, '2'), '^.*\\') : iconLV.GetText(Item, '2') + iconGUI['statusBar'].Text := ' Name: ' iconName + } + + ShowMenuForIconLV(LV, Item, *) { ; 展示列表的右键菜单 + If IsUsersIcons or item<1 + Return + + iconLVMenu := Menu() + iconLVMenu.Add(TEXT.EXTRACT_ICON, ExtractDllIcon) + iconLVMenu.SetIcon(TEXT.EXTRACT_ICON, "HICON:" Base64PNGToHICON(Base64.PNG.MENU_EXTRACT)) + iconLVMenu.Show() + + ExtractDllIcon(*) { + index := Instr(defaultDllName, '.exe') ? Item : iconLV.GetText(Item, '2') + iconName := defaultDllName '(' index ',' item ')' + + ConvertToIconFile.Dll( {dllName:defaultDllName, index:index, size:0, iconName:iconName} ) + + mainGUI["log"].Value .= FormatTime(A_Now, "`syyyy/MM/dd HH:mm:ss`n`s") + . TEXT.EXTRACTED . iconName . "`n`n===========================================`n`n" + + TrayTip(TEXT.EXTRACTED . iconName , "Ciallo~(∠・ω< )⌒★", "Mute"), SetTimer(TrayTip, -5000) + } } } +AddIconsToIconLV(path, IsAddDllIcons := False) { + mainGUI.Opt("+Disabled") + iconGUI.Opt("+Disabled") + global defaultDllName := path + iconLV.Opt("-Redraw") + iconLV.Delete() + If !IsAddDllIcons { ; Users的图标文件 + global IsUsersIcons := True + IL_ID := IL_Create(,,"true") + iconLV.SetImageList(IL_ID) + Loop Files, path "\*.ico" { + hIcon := GetFileHICON(A_LoopFilePath) + iconNumber := DllCall("ImageList_ReplaceIcon", "Ptr", IL_ID, "Int", -1, "Ptr", hIcon) + 1, DllCall("DestroyIcon", "ptr", hIcon) + iconLV.Add("Icon" . iconNumber, A_Index, A_LoopFilePath) + } + } Else { ; Dll图标文件 + global IsUsersIcons := False + ListIcons.AddIconsToList(iconLV, path) + } + iconLV.Opt("+Redraw") + mainGUI.Opt("-Disabled") + iconGUI.Opt("-Disabled") +} + +ShowMenuForIconGUI(*) { ; 展示系统图标的菜单 + iconsMenu := Menu() + ArraySystemIcons := ['shell32.dll', 'imageres.dll', 'ddores.dll', 'mmres.dll', 'wmploc.dll', 'dmdskres.dll', 'setupapi.dll', 'explorer.exe', 'imagesp1.dll', 'pifmgr.dll', 'networkexplorer.dll'] + + For value in ArraySystemIcons { + iconsMenu.Add(value, (Item, *) => AddIconsToIconLV(Item, IsAddDllIcons := True)) + } + + iconsMenu.Show(30*(A_ScreenDPI/96), 30*(A_ScreenDPI/96)) +} + +AddUsersIconsToIconGUI(*) { ; 访问ini,打开上一次打开的存放ICO的文件夹,并更新ini里的上一次打开的图标文件夹路径 + iconGUI.Opt("+OwnDialogs") + Try { + laseSelectedFolderPath := iniRead(iniPath, "info", "lastSelectedIconFolderPath") + } + Catch { + Msgbox("the info.ini does not have an option named `"lastSelectedIconFolderPath`" ",,"icon!") + } + If not (selectedFolderPath := DirSelect("*" . laseSelectedFolderPath, 0, Text.SELECT_ICONS_FOLDER)) + Return + AddIconsToIconLV(selectedFolderPath) +} \ No newline at end of file diff --git a/README-en_US.md b/README-en_US.md index 2e91f0c..4c3b92b 100644 --- a/README-en_US.md +++ b/README-en_US.md @@ -1,4 +1,4 @@ -![image](https://github.com/iKineticate/AHK-ChangeIcon/blob/main/Introduction/homepage.png) +![image](https://github.com/iKineticate/AHK-ChangeIcon/blob/main/introduction/homepage.png) ## About @@ -17,32 +17,35 @@ This is a software written in AHK, which can solves the tedious operation when r (1)The full name of the icon is included in the name of the shortcut(e.g. the icon name is "Chrome.ico" and the shortcut name is "Chrome Canary.lnk") (2)The full name of the shortcut should be included in the name of the icon(e.g. the icon name is "Honkai: Star Rail.ico" and the shortcut name is "Star Rail.lnk") -![image](https://github.com/iKineticate/AHK-ChangeIcon/blob/main/Introduction/change_and_restore.gif) +![image](https://github.com/iKineticate/AHK-ChangeIcon/blob/main/introduction/change_and_restore.gif) 3.Change/Restore the icon of a single shortcut -![image](https://github.com/iKineticate/AHK-ChangeIcon/blob/main/Introduction/change_one.gif) +![image](https://github.com/iKineticate/AHK-ChangeIcon/blob/main/introduction/change_one.gif) 4.List context menu * Lanuch the shortcut * Change the shortcut icon * Restore the default icon for the shortcut +* Extract shortcut icon * Explore the shortcut target directory * Rename the shortcut * Adds the non-desktop shortcut to the desktop * View and copy the properties of shortcuts -![image](https://github.com/iKineticate/AHK-ChangeIcon/blob/main/Introduction/menu.jpg) +![image](https://github.com/iKineticate/AHK-ChangeIcon/blob/main/introduction/menu.jpg) ## Other Function -1.Manage shortcuts to the desktop, Start menu or other folders, such as changing icons, restoring default icons, renaming, etc. +1.Manage shortcuts to the desktop, Start menu or other folders -2.Manually add shortcuts to desktop for apps like UWP and WSA +2.Display system icons or user folder icons (supports extracting system icons) -3.Backup shortcuts from the list to a desktop folder +3.Create shortcuts to desktop for UWP/WSA etc. applications -![image](https://github.com/iKineticate/AHK-ChangeIcon/blob/main/Introduction/other_en.png) +4.Backup shortcuts from the list to a desktop folder + +![image](https://github.com/iKineticate/AHK-ChangeIcon/blob/main/introduction/other_en.png) ## ISSUES: diff --git a/README.md b/README.md index ee13ee7..266097c 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -![image](https://github.com/iKineticate/AHK-ChangeIcon/blob/main/Introduction/homepage.png) +![image](https://github.com/iKineticate/AHK-ChangeIcon/blob/main/introduction/homepage.png)

简体中文 | English

@@ -20,11 +20,11 @@ * 快捷方式的全名称包含于图标的名称(例如图标名称为"崩坏:星穹铁道.ico",快捷方式名称为"星穹铁道.lnk") -![image](https://github.com/iKineticate/AHK-ChangeIcon/blob/main/Introduction/change_and_restore.gif) +![image](https://github.com/iKineticate/AHK-ChangeIcon/blob/main/introduction/change_and_restore.gif) 3.更换/恢复单个快捷方式图标 -![image](https://github.com/iKineticate/AHK-ChangeIcon/blob/main/Introduction/change_one.gif) +![image](https://github.com/iKineticate/AHK-ChangeIcon/blob/main/introduction/change_one.gif) 4.右键上下文菜单 @@ -34,6 +34,8 @@ * 恢复快捷方式默认图标 +* 提取快捷方式图标 + * 打开快捷方式目标目录 * 重新命名桌面快捷方式 @@ -42,21 +44,23 @@ * 查看和复制快捷方式的属性 -![image](https://github.com/iKineticate/AHK-ChangeIcon/blob/main/Introduction/menu.jpg) +![image](https://github.com/iKineticate/AHK-ChangeIcon/blob/main/introduction/menu.jpg) ## 其他功能 -1.管理桌面、"开始"菜单或其他文件夹的快捷方式,进行如更换图标、恢复默认图标、重命名等操作 +1.管理桌面、"开始"菜单或其他文件夹的快捷方式 + +2.显示系统图标或用户文件夹图标(支持提取系统图标) -2.手动添加UWP/WSA等应用的快捷方式至桌面 +2.创建UWP/WSA等应用的快捷方式至桌面 -3.备份列表中的快捷方式至桌面指定名称的文件夹 +3.备份列表快捷方式至桌面指定的文件夹 -![image](https://github.com/iKineticate/AHK-ChangeIcon/blob/main/Introduction/other_zh.png) +![image](https://github.com/iKineticate/AHK-ChangeIcon/blob/main/introduction/other_zh.png) 4.浏览系统大部分图标或用户自选图标,支持双击更换左侧列表快捷方式图标 -![image](https://github.com/iKineticate/AHK-ChangeIcon/blob/main/Introduction/system_icons.gif) +![image](https://github.com/iKineticate/AHK-ChangeIcon/blob/main/introduction/system_icons.gif) ## 已知问题 @@ -88,15 +92,11 @@ 解决办法:单独更换其他快捷方式图标 -8.快捷方式图标手动更换为系统内置图标时(如shell32.dll),误判为未更换 - - 尚无解决办法 - -9.Windows10不支持圆角 +8.Windows10不支持圆角 ## 下载 -Github:[AHK-ChangeIcon](https://github.com/iKineticate/AHK-ChangeIcon/releases) +Github:[AHK-ChangeIcon](https://github.com/iKineticate/AHK-ChangeIcon/releases/latest) 蓝奏云:[AHK-ChangeIcon](https://wwu.lanzoul.com/b03rjy4ud) (密码:6666) @@ -121,10 +121,10 @@ Github:[AHK-ChangeIcon](https://github.com/iKineticate/AHK-ChangeIcon/releases ## 更新内容 -1.新功能:浏览系统内置图标或用户自选文件夹图标,并支持双击功能(随主窗口移动而移动) +1.新功能:浏览系统内置图标或用户自选文件夹图标,支持双击更换快捷方式图标 -2.优化了搜索的Edit控件内的显示内容和tooltip位置 +2.新功能:支持提取快捷方式、系统的图标 -3.新增关闭时的渐进淡化隐藏和关闭的效果 +3.优化了判断快捷方式是否更换过图标的能力 -4.优化了判断快捷方式是否更换过图标的能力 \ No newline at end of file +4.在指定控件上更换鼠标样式 \ No newline at end of file diff --git a/lib/Class_Button.ahk b/lib/Class_Button.ahk index 63a639b..d17f177 100644 --- a/lib/Class_Button.ahk +++ b/lib/Class_Button.ahk @@ -1,282 +1,250 @@ -;======================================================================================================== -; Class: Create png/text/logotext/tab button +;=============================================================================================================== +; Class: Create png/text/newTab button ; Description: Please add the "ButtonFunc(GuiCtrlObj, Info, *)" Funcontions at the bottom to your main code ; 请添加"ButtonFunc(GuiCtrlObj, Info, *)"函数到你的代码中 ; Assign the specified function according to the name of the created button ; 根据创建按钮的名称来分配指定的功能 -; ******************************************************************************************************* -; ButtonFunc(GuiCtrlObj, Info, *) -; { -; ; If Instr(GuiCtrlObj.Name, "Tab_Item_") ; If you create new tab, need add it -; ; Return Tab_Focus(GuiCtrlObj.Text) -; -; control_btn_name := RegExReplace(GuiCtrlObj.Name, "i)_BUTTON$") -; Switch control_btn_name -; { -; Case "Close" :ExitApp() -; Case "Minimize":WinMinimize("A") -; Case "Change" :Msgbox("hellow") -; Case "Click" :Msgbox("hellow") -; Case "Add" :Msgbox("hellow") -; Case "Delete" :Msgbox("hellow") -; } -; } -; ******************************************************************************************************* -; Parameters: GuiCtrlObj - Subclass button control -; Case CaseValue - Subclass button name -; Case CaseValue : Statements - Function of buttons -;======================================================================================================== +;=============================================================================================================== +/* + e.g. + MyGui := GUI() + MyGui.Button := CreateButton(MyGui) + MyGui.Button.PNG( {name:'testButton1', x:0 , y:0, w:80, h:40, normal:Base64_PNG_Unclicked, active:Base64_PNG_Click, pngQuality:'300'} ) + MyGui.Button.Text( {name:'testButton2', x:0, y:50, w:80, h:40, R:10, normalColor:'0x26ffffff', activeColor:'909090', text: 'Hellow', textOpt:'+0x200', textHorizontalMargin:4, fontOpt:'c4B6A87 s10', font:''} ) + MyGui.Button.OnEvent('testButton1', 'Click', (*)=>Exist) + MyGui.Button.Obj['testButton1'] = MyGui['testButton1_BUTTON'] + MyGui.Button.Obj['testButton1'].OnEvent('Click', (*)=>Exist) +*/ Class CreateButton { - __New( obj:={name:"", x:"", y:"", w:"", h:""} ) - { - this._name := obj.name - this._x := obj.X - this._y := (_caption_h) ? (obj.Y + _caption_h) : obj.Y - this._w := obj.W - this._h := obj.H - } + __New( GuiObj ) => (this.GUI := GuiObj, this.Obj := map()) - ;======================================================================================================== + OnEvent(GuiCtrlName, EventName, Callback, AddRemove:=1) => this.Obj[GuiCtrlName].OnEvent(EventName, Callback, AddRemove) + + ;=========================================================================================================================== ; Create: PNG Button - ; Parameters: *_png_base64 - Base64 encoding of PNG images - ; norml - The state when the button is not clicked or the cursor is not hovering over the button - ; active - The state when the button is clicked or the cursor is hovering over the button - ; png_quality - The width and height of PNG imagess - ;======================================================================================================== - PNG( obj:={normal_png_base64:'', active_png_base64:'', png_quality:""} ) - { - active_name := StrReplace(this._name, "`s") . "_ACTIVE" - button_name := StrReplace(this._name, "`s") . "_BUTTON" - ; Normal PNG image (常态的PNG图片) - ; Top button (顶层按钮) (+0x4000000:Top level buttons are displayed below other controls (顶层控件的显示在其他控件下方) ) - MyGui.AddPicture("v" . button_name . " x" . this._x . " y" . this._y . " w" . this._w . " h" . this._h, "HICON:" Base64PNG_to_HICON(obj.normal_png_base64, obj.png_quality)).OnEvent("Click", ButtonFunc) - ; 若PNG的Base64不存在或为空,则返回 - If (!obj.HasOwnProp("active_png_base64") or !obj.active_png_base64) - Return + ; Parameters: pngQuality - The width and height of PNG imagess + ; norml - Base64 encoding of PNG images, The state when the button is not clicked or the cursor is not hovering over the button + ; active - Base64 encoding of PNG images, The state when the button is clicked or the cursor is hovering over the button + ;=========================================================================================================================== + PNG(obj:={name:"", x:"", y:"", w:"", h:"", normal:'', active:'', pngQuality:""}) { + If !IsObject(obj) + Return ExitApp + + activeName := RegExReplace(obj.name, "[\s\r\n]+") . "_ACTIVE" + buttonName := RegExReplace(obj.name, "[\s\r\n]+") . "_BUTTON" ; Active PNG image (活跃态的PNG图片) - MyGui.AddPicture("v" . active_name . " x" . this._x . " y" . this._y . " w" . this._w . " h" . this._h . " Hidden", "HICON:" Base64PNG_to_HICON(obj.active_png_base64, obj.png_quality)) + this.GUI.AddPicture("v" activeName " x" obj.x " y" obj.y " w" obj.w " h" obj.h " Hidden", "HICON:" Base64PNGToHICON(obj.active, obj.pngQuality)) + ; Normal PNG image Button (+0x4000000:Top level buttons are displayed below other controls (顶层控件的显示在其他控件下方) ) + this.GUI.AddPicture("v" buttonName " x" obj.x " y" obj.y " w" obj.w " h" obj.h ' +0x4000000', "HICON:" Base64PNGToHICON(obj.normal, obj.pngQuality)) + this.Obj[obj.name] := this.GUI[buttonName] } - ;======================================================================================================== + + ;=========================================================================================================================== ; Create: Text Button - ; Parameters: norml - The state when the button is not clicked or the cursor is not hovering over the button - ; active - The state when the button is clicked or the cursor is hovering over the button - ; text_options - ; (1)+0xE - Picture control can be drawn by gdip+ - ; (2)+0x200" - vertical center alignment, but it does not support line breaks - ; (3)center" - horizontally center alignment - ; text_margin - Add spaces to the left or right of the text depending on the sign of the value(e.g. the value is a positive number, add a space to the left of the text to adjust the text position.) - ;======================================================================================================== - Text( obj:={R:15, normal_color:"", active_color:"", Text:"", text_options:"+0x200 center", text_margin:"", font_options:"", font:""} ) - { - default_name := StrReplace(this._name, "`s") . "_NORMAL" - active_name := StrReplace(this._name, "`s") . "_ACTIVE" - button_name := StrReplace(this._name, "`s") . "_BUTTON" - obj.R := Obj.HasOwnProp("R") ? ((!obj.R) ? "0" : obj.R*(A_ScreenDPI/96)) : "0" + ; Parameters: norml - The state when the button is not clicked or the cursor is not hovering over the button + ; active - The state when the button is clicked or the cursor is hovering over the button + ; textOpt + ; (1)+0xE - Picture control can be drawn by gdip+ + ; (2)+0x200 - vertical center alignment, but it does not support line breaks + ; (3)center - horizontally center alignment + ; textHorizontalMargin - Horizontal distance of the text control + ;=========================================================================================================================== + Text( obj:={name:"", x:"", y:"", w:"", h:"", R:"", normalColor:"", activeColor:"", Text:"", textOpt:"+0x200 center", textHorizontalMargin:"", fontOpt:"", font:""} ) { + If !IsObject(obj) + Return ExitApp - ; Change to the correct colour format (e.g. 0xff000000) - For obj_name, descriptor in obj.OwnProps() - { - If !Instr(obj_name, "_color") + noSpacesName := RegExReplace(obj.name, "[\s\r\n]+") + defaultName := noSpacesName . "_NORMAL" + activeName := noSpacesName . "_ACTIVE" + buttonName := noSpacesName . "_BUTTON" + obj.R := (!obj.R) ? "0" : obj.R*(A_ScreenDPI/96) + + For propName, value in obj.OwnProps() { ; Change the color format to the correct one (e.g. 0xff000000) + If !Instr(propName, "Color") Continue - Switch StrLen(color:=Trim(descriptor)) - { - Case 6 : Obj.%obj_name% := "0xff" . color ; 不能直接obj.obj_name,因为obj_name是值不是变量,使用%name%调用一个名为name的变量,不理解可用不理解可用obj.DefineProp("",{value:""}) - Case 8 : Obj.%obj_name% := RegExReplace(color, "i)^0x", "0xff") + Switch StrLen(color := Trim(value)) { + Case 6 : obj.%propName% := "0xff" color ; 不能直接obj.propName,因为propName是值不是变量,使用%name%调用一个名为name的变量,不理解可用不理解可用obj.DefineProp("",{value:""}) + Case 8 : obj.%propName% := LTrim(color, "0x") . "0xff" } } - If (obj.HasOwnProp("text_margin") and obj.text_margin) - { - margin := Format("{:" . Ceil(obj.text_margin) . "}", "`s") - obj.Text := (obj.text_margin>0) ? (margin . obj.Text) : (obj.Text . margin) + ; text margin left(文本距离该控件左侧的距离) + If (obj.HasOwnProp("textHorizontalMargin") and (obj.textHorizontalMargin>0)) { + margin := Format("{:" . Ceil(obj.textHorizontalMargin) . "}", A_Space) + obj.Text := (obj.textHorizontalMargin > 0) ? (margin . obj.Text) : (obj.Text . margin) } - ; Normal PNG image (常态图片) - If !Instr(obj.normal_color, "0x00") - { - MyGui.AddPicture("x" . this._x . " y" . this._y . " w" . this._w*(A_ScreenDPI/96) . " h" . this._h*(A_ScreenDPI/96) . " v" . default_name . " +0xE -E0x200 BackgroundTrans") - Gdip_SetPicRoundedRectangle(MyGui[default_name], obj.normal_color, obj.r, isFill:="True") + If !Instr(obj.normalColor, "0x00") { + this.GUI.AddPicture("v" defaultName " x" obj.x " y" obj.y " w" obj.w*(A_ScreenDPI/96) " h" obj.h*(A_ScreenDPI/96) " +0xE -E0x200 BackgroundTrans") + Gdip_SetPicRoundedRectangle(this.GUI[defaultName], obj.normalColor, obj.r, isFill:="True") } ; Active PNG image (活跃态图片) - If !Instr(obj.active_color, "0x00") - { - MyGui.AddPicture("x" . this._x . " y" . this._y . " w" . this._w*(A_ScreenDPI/96) . " h" . this._h*(A_ScreenDPI/96) . " v" . active_name . " +0xE -E0x200 Hidden BackgroundTrans") - Gdip_SetPicRoundedRectangle(MyGui[active_name], obj.active_color, obj.r, isFill:="True") + If !Instr(obj.activeColor, "0x00") { + this.GUI.AddPicture("v" activeName " x" obj.x " y" obj.y " w" obj.w*(A_ScreenDPI/96) " h" obj.h*(A_ScreenDPI/96) " +0xE -E0x200 Hidden BackgroundTrans") + Gdip_SetPicRoundedRectangle(this.GUI[activeName], obj.activeColor, obj.r, isFill:="True") } ; Top text button (顶层文本按钮) - MyGui.AddText("x" . this._x . " y" . this._y . " w" . this._w . " h" . this._h . " v" . button_name . " BackgroundTrans " . obj.text_options, obj.Text) - If (obj.HasOwnProp("font_options") and obj.HasOwnProp("font")) - { - MyGui[button_name].SetFont(obj.font_options, obj.font) - } - - ; If the active_color format is 0x00, the control is simply an image and not a button(若活跃态颜色是0x00,则返回,即创建图片而不是按钮) - If Instr(obj.active_color, "0x00") - Return - ; Set the function of the button (设置按钮功能) - MyGui[button_name].OnEvent("Click", ButtonFunc) + this.GUI.AddText("v" buttonName " x" obj.x " y" obj.y " w" obj.w " h" obj.h " BackgroundTrans " obj.textOpt, obj.Text) + this.GUI[buttonName].SetFont(obj.fontOpt, obj.font) + this.Obj[obj.name] := this.GUI[buttonName] + ; If Instr(obj.activeColor, "0x00") ; If the activeColor format is 0x00, the control is simply an image and not a button + ; Return + ; this.GUI[buttonName].OnEvent("Click", ButtonFunc) ; Set the function of the top text button } - ;======================================================================================================== - ; Create: Logo Text Button - ; Parameters: norml - The state when the button is not clicked or the cursor is not hovering over the button - ; active - The state when the button is clicked or the cursor is hovering over the button - ; text_options - ; (1)+0xE - Picture control can be drawn by gdip+ - ; (2)+0x200" - vertical center alignment, but it does not support line breaks - ; (3)center" - horizontally center alignment - ; logo - ; (1)_png_base64 - Base64 encoding of Logo PNG images - ; (2)_x _y - margin inside the control - ; (3)_quality - The width and height of Logo PNG imagess - ;======================================================================================================== - LogoText( obj:={R:15, normal_color:"", active_color:"", Text:"", text_options:"+0x200 center", text_margin:"", font_options:"", font:"", logo_png_base64:'', logo_x:"", logo_y:"", logo_w:"", logo_h:"", logo_quality:""} ) - { - this.Text(obj) - If !obj.HasOwnProp("logo_png_base64") ; 因为图片没有事件,所以不会被WM_MOUSE检测到,所以在最上层也没事 - Return - obj.logo_h := obj.logo_h - obj.logo_w := obj.logo_w - obj.logo_x := trim(obj.logo_x)="center" ? (this._x + (this._w - obj.logo_w) / 2) : (this._x + obj.logo_x) - obj.logo_y := trim(obj.logo_y)="center" ? (this._y + (this._h - obj.logo_h) / 2) : (this._y + obj.logo_y) - MyGui.AddPicture("x" . obj.logo_x . " y" . obj.logo_y . " w" . obj.logo_w . " h" . obj.logo_h . " BackgroundTrans", "HICON:" Base64PNG_to_HICON(obj.logo_png_base64, height := obj.logo_quality)) - } ;======================================================================================================== ; Create: NewTab - ; Description: Please add the "tab_prop" object at the bottom to your main code before creating the tab + ; Description: Please add the "tabProp" object at the bottom to your main code before creating the tab ; ******************************************************************************************************* - ; tab_prop := {} - ; tab_prop.label_name := ["Home", "Other", "Log", "Help", "About"] - ; tab_prop.label_prop := {distance:"0" ,text_options:"+0x200", font_options:"s10 Bold cffffff", font:"", font_normal_color:"",font_active_color:""} - ; tab_prop.label_active := {margin_left:"", margin_top:"", w:"", h:"", R:"5", color:""} - ; Can be selectively added (可以选择性添加以下对象) - ; tab_prop.label_indicator := {margin_left:"", margin_top:"", w:"", h:"", R:"5", color:""} - ; Can be selectively added (可以选择性添加以下对象) - ; tab_prop.logo_symbol := {margin_left:"", font_name:""} - ; tab_prop.logo_size := ["", "", "", "", ""] - ; tab_prop.logo_unicode := ["", "", "", "", ""] + ; tabProp := {x:'', y:'', w:'', h:''} + ; tabProp.labelName := ['Home', 'Other', 'Log', 'Help', 'About'] ; 输入空格来调整标签按钮里的文本相对按钮的x位置 + ; tabProp.labelProp := {distance:'0' ,textOpt:"+0x200", fontOpt:"s10 Bold cffffff", font:"", fontNormalColor:"",fontActiveColor:""} + ; tabProp.labelActive := {marginLeft:"", marginTop:"", w:"", h:"", R:"5", color:""} + ; ; --Can--be--selectively--added-- (可以选择性添加以下对象) + ; tabProp.labelIndicator := {marginLeft:"", marginTop:"", w:"", h:"", R:"5", color:""} + ; ; --Can--be--selectively--added-- (可以选择性添加以下对象) + ; tabProp.logoSymbol := {marginLeft:'', fontName:'Segoe UI Symbol'} + ; tabProp.logoSize := ["", "", "", "", ""] + ; tabProp.logoUnicode := ["", "", "", "", ""] ; ******************************************************************************************************* - ; Parameters: margin_left - The margin-left of the control inside the tab - ; margin_top - The margin-top of the control inside the tab - ; logo_png_base64 - Base64 encoding of Logo PNG images - ; Note: The dimensions of the drawn image are influenced by DPI scaling.Therefore, after setting the DPI scaling, the width and height of the picture must be multiplied by the DPI scaling value. + ; Parameters: marginLeft - The margin-left of the control inside the tab + ; marginTop - The margin-top of the control inside the tab + ; logo_png_base64 - Base64 encoding of Logo PNG images + ; Note: (1)The dimensions of the drawn image are influenced by DPI scaling.Therefore, after setting the DPI scaling, the width and height of the picture must be multiplied by the DPI scaling value. ; GDIP绘制的图片宽高不受"DPI缩放"影响,因此启动+DPIScale后,需给照片控件的宽高*(A_ScreenDPI/96) - ; The two lengths of "logo_png_base64" and "label_name" have to be equal, and their order must also be the same + ; (2)The two lengths of "logo_png_base64" and "labelName" have to be equal, and their order must also be the same ; Logo图片的数量需与标签数量相等,且映射顺序一致 ;======================================================================================================== - NewTab( tab_prop ) - { - If !isObject(tab_prop) + NewTab(tabProp) { + If !IsObject(tabProp) Return ExitApp ; Set label properties - static label_distance := tab_prop.label_prop.HasOwnProp("distance") ? tab_prop.label_prop.distance:"5" - , active_x := tab_prop.label_active.margin_left="center" ? this._x + ((this._w - tab_prop.label_active.w) / 2) : (this._x + tab_prop.label_active.margin_left) - , active_y := tab_prop.label_active.margin_top ="center" ? this._y + ((this._h - tab_prop.label_active.h) / 2) : (this._y + tab_prop.label_active.margin_top ) - , active_r := (tab_prop.label_active.HasOwnProp("R") and tab_prop.label_active.R!="") ? tab_prop.label_active.R*(A_ScreenDPI/96) : "0" - ; Set logo properties - If (tab_prop.HasOwnProp("label_indicator")) - { - static indicator_x := tab_prop.label_indicator.margin_left="center" ? this._x + ((this._w - tab_prop.label_indicator.w) / 2) : (this._x + tab_prop.label_indicator.margin_left) - , indicator_y := tab_prop.label_indicator.margin_top="center" ? this._y + ((this._h - tab_prop.label_indicator.h) / 2) : (this._y + tab_prop.label_indicator.margin_top) - , indicator_r := (tab_prop.label_indicator.HasOwnProp("R") and tab_prop.label_indicator.R!="") ? tab_prop.label_indicator.R*(A_ScreenDPI/96) : "0" + static labelDistance := tabProp.labelProp.HasOwnProp("distance") ? tabProp.labelProp.distance:"5" + , activeX := tabProp.labelActive.marginLeft="center" ? tabProp.x + ((tabProp.w - tabProp.labelActive.w) / 2) : (tabProp.x + tabProp.labelActive.marginLeft) + , activeY := tabProp.labelActive.marginTop ="center" ? tabProp.y + ((tabProp.h - tabProp.labelActive.h) / 2) : (tabProp.y + tabProp.labelActive.marginTop ) + , activeR := (tabProp.labelActive.HasOwnProp("R") and tabProp.labelActive.R!="") ? tabProp.labelActive.R*(A_ScreenDPI/96) : "0" + ; Set indicator properties + If (tabProp.HasOwnProp("labelIndicator")) { + static indicatorX := tabProp.labelIndicator.marginLeft="center" ? tabProp.x + ((tabProp.w - tabProp.labelIndicator.w) / 2) : (tabProp.x + tabProp.labelIndicator.marginLeft) + , indicatorY := tabProp.labelIndicator.marginTop ="center" ? tabProp.y + ((tabProp.h - tabProp.labelIndicator.h) / 2) : (tabProp.y + tabProp.labelIndicator.marginTop) + , indicatorR := (tabProp.labelIndicator.HasOwnProp("R") and tabProp.labelIndicator.R!="") ? tabProp.labelIndicator.R*(A_ScreenDPI/96) : "0" } ; Set logo properties - If (tab_prop.HasOwnProp("logo_symbol")) - { - static symbol_x := tab_prop.logo_symbol.margin_left="center" ? this._x : (this._x + tab_prop.logo_symbol.margin_left) - , symbol_y := this._y - , symbol_w := this._h - , symbol_h := this._h + If (tabProp.HasOwnProp("logoSymbol")) { + static symbolX := tabProp.logoSymbol.marginLeft="center" ? tabProp.x : (tabProp.x + tabProp.logoSymbol.marginLeft) + , symbolY := tabProp.y + , symbolW := tabProp.h + , symbolH := tabProp.h } ; Change to the correct colour format (e.g. text color:=000000, active color:=0xff000000) - For obj_name in tab_prop.OwnProps() - { - If !RegExMatch(obj_name, "i)label_prop|label_active|label_indicator") + For propName in tabProp.OwnProps() { + If !RegExMatch(propName, "i)labelProp|labelActive|labelIndicator") Continue - For color_name, descriptor in tab_prop.%obj_name%.OwnProps() - { - If !Instr(color_name, "color") + For colorName, value in tabProp.%propName%.OwnProps() { + If !Instr(colorName, "color") Continue - Switch StrLen(color:=Trim(descriptor)) - { - Case 6 : tab_prop.%obj_name%.%color_name% := (color_name = "color") ? ("0xff" . color) : color - Case 8 : tab_prop.%obj_name%.%color_name% := (color_name = "color") ? RegExReplace(color, "i)^0x", "0xff") : RegExReplace(color, "i)^0x") ; 不能直接obj.obj_name,因为obj_name是值不是变量,使用%name%调用一个名为name的变量,不理解可用不理解可用obj.DefineProp("",{value:""}) - Case 10 : tab_prop.%obj_name%.%color_name% := (color_name = "color") ? color : RegExReplace(color, "i)^0x..") + Switch StrLen(color := Trim(value)) { + Case 6 : tabProp.%propName%.%colorName% := (colorName = "color") ? ("0xff" . color) : color + Case 8 : tabProp.%propName%.%colorName% := (colorName = "color") ? (LTrim(color, "0x") . "0xff") : LTrim(color, "0x") + Case 10 : tabProp.%propName%.%colorName% := (colorName = "color") ? color : LTrim(color, "0x") } } } ; Create the Tab control - global Tab := MyGui.AddTab("x0 y0 w0 h0 -wrap -tabstop") - ; Subsequently created controls are added outside of the Tab control (随后创建的控件不添加在标签页控件内) + global Tab := this.GUI.AddTab("x0 y0 w0 h0 -wrap -tabstop") Tab.UseTab() ; Loop to create labels to the tab - Loop tab_prop.label_name.Length - { - active_name := StrReplace(tab_prop.label_name[A_Index], "`s") . "_ACTIVE" ; 使用StrReplace: 控件名称v不支持空格 - focus_name := StrReplace(tab_prop.label_name[A_Index], "`s") . "_FOCUS" - indicator_name := StrReplace(tab_prop.label_name[A_Index], "`s") . "_INDICATOR" - button_name := StrReplace(tab_prop.label_name[A_Index], "`s") . "_Tab_BUTTON" - symbol_name := StrReplace(tab_prop.label_name[A_Index], "`s") . "_SYMBOL" + Loop tabProp.labelName.Length { + labelNoSpacesName := RegExReplace(tabProp.labelName[A_Index], "[\s\r\n]+") ; 使用StrReplace原因: 控件的Opt中,命名时v后不支持空格,因此命名时需去除对象的'labelName'中的空格 + activeName := labelNoSpacesName . "_ACTIVE" + focusName := labelNoSpacesName . "_FOCUS" + indicatorName := labelNoSpacesName . "_INDICATOR" + buttonName := labelNoSpacesName . "_Tab_BUTTON" + symbolName := labelNoSpacesName . "_SYMBOL" ; Create the "label" to Hidden the Tab - Tab.Add([StrReplace(tab_prop.label_name[A_Index], "`s")]) ; StrReplace: 文本按钮名称不包含空格,后续Tab_Click函数根据无空格名称来判断,所以创建隐藏Tab也要去空格 + Tab.Add([labelNoSpacesName]) ; Create "active" Picture (and Set Rounded Corners) - MyGui.AddPicture("v" . active_name . " x" . active_x . " y" . ((this._h + label_distance)*(A_Index-1) + active_y) . " w" . tab_prop.label_active.w*(A_ScreenDPI/96) . " h" . tab_prop.label_active.h*(A_ScreenDPI/96) . " backgroundtrans +0xE -E0x200 Hidden") - Gdip_SetPicRoundedRectangle(MyGui[active_name], "0x1AFFFFFF", active_r, isFill:="True") + this.GUI.AddPicture("v" activeName " x" activeX " y" ((tabProp.h + labelDistance)*(A_Index-1) + activeY) " w" tabProp.labelActive.w*(A_ScreenDPI/96) " h" tabProp.labelActive.h*(A_ScreenDPI/96) " backgroundtrans +0xE -E0x200 Hidden") + Gdip_SetPicRoundedRectangle(this.GUI[activeName], "0x1AFFFFFF", activeR, isFill:="True") ; Create "focus" Picture (and Set Rounded Corners) - MyGui.AddPicture("v" . focus_name . " x" . active_x . " y" . ((this._h + label_distance)*(A_Index-1) + active_y) . " w" . tab_prop.label_active.w*(A_ScreenDPI/96) . " h" . tab_prop.label_active.h*(A_ScreenDPI/96) . " backgroundtrans +0xE -E0x200 Hidden") - Gdip_SetPicRoundedRectangle(MyGui[focus_name], tab_prop.label_active.color, active_r, isFill:="True") + this.GUI.AddPicture("v" focusName " x" activeX " y" ((tabProp.h + labelDistance)*(A_Index-1) + activeY) " w" tabProp.labelActive.w*(A_ScreenDPI/96) " h" tabProp.labelActive.h*(A_ScreenDPI/96) " backgroundtrans +0xE -E0x200 Hidden") + Gdip_SetPicRoundedRectangle(this.GUI[focusName], tabProp.labelActive.color, activeR, isFill:="True") ; Create "indicator" Picture (and Set Rounded Corners) - (tab_prop.HasOwnProp("label_indicator")) ? MyGui.AddPicture("x" . indicator_x . " y" . ((this._h + label_distance)*(A_Index-1) + indicator_y) . " w" . tab_prop.label_indicator.w*(A_ScreenDPI/96) . " h" . tab_prop.label_indicator.h*(A_ScreenDPI/96) . " v" . indicator_name . " backgroundtrans +0xE -E0x200 Hidden") : False - (tab_prop.HasOwnProp("label_indicator")) ? Gdip_SetPicRoundedRectangle(MyGui[indicator_name], tab_prop.label_indicator.color, indicator_r, isFill:="True") : False + If tabProp.HasOwnProp("labelIndicator") { + this.GUI.AddPicture("v" indicatorName " x" indicatorX " y" ((tabProp.h + labelDistance)*(A_Index-1) + indicatorY) " w" tabProp.labelIndicator.w*(A_ScreenDPI/96) " h" tabProp.labelIndicator.h*(A_ScreenDPI/96) " backgroundtrans +0xE -E0x200 Hidden") + Gdip_SetPicRoundedRectangle(this.GUI[indicatorName], tabProp.labelIndicator.color, indicatorR, isFill:="True") + } ; Create "logo" symbol - If tab_prop.HasOwnProp("logo_symbol") - { - If tab_prop.label_name.Capacity != tab_prop.logo_unicode.Capacity ; 标签页数与logo数量不匹 - Return (MsgBox("标签数量与图标数量不等, 或格式不正确")) - FontSymbol( obj:={name:symbol_name, x:symbol_x, y:((this._h + label_distance)*(A_Index-1) + symbol_y), w:symbol_w, h:symbol_h, unicode:tab_prop.logo_unicode[A_Index], font_name:tab_prop.logo_symbol.font_name, text_color:tab_prop.label_prop.font_normal_color, back_color:"trans", font_options:"s" . tab_prop.logo_size[A_Index], text_options:"+0x200 center"} ) + If tabProp.HasOwnProp("logoSymbol") { + If tabProp.labelName.Capacity != tabProp.logoUnicode.Capacity + Return MsgBox("标签数量与图标数量不等, 或格式不正确") + FontSymbol(this.GUI, tabProp.logoSymbol.fontName).Font( {name:symbolName, unicode:tabProp.logoUnicode[A_Index], x:symbolX, y:((tabProp.h + labelDistance)*(A_Index-1) + symbolY), w:symbolW, h:symbolH, textColor:tabProp.labelProp.fontNormalColor, fontOpt:"s" tabProp.logoSize[A_Index], textOpt:'+0x200 center'} ) } - ; Create the "label" to Visible the Tab ( as a top text button) (创建标签至显示的标签页,并作为顶部的文本按钮) - MyGui.AddText("x" . this._x . " y" (this._y + (this._h + label_distance)*(A_Index-1)) . " h" . this._h . " w" . this._w . " v" . button_name . " BackgroundTrans +0x200 " . tab_prop.label_prop.text_options, tab_prop.label_name[A_Index]) - MyGui[button_name].SetFont(tab_prop.label_prop.font_options, tab_prop.label_prop.font) - MyGui[button_name].SetFont("c" . tab_prop.label_prop.font_normal_color) - MyGui[button_name].OnEvent("Click", ButtonFunc) - ; Setting the first label to be the default label (设置第一个标签为默认标签,即设置第一个标签是活跃态) + ; Create the "label" to Visible the Tab ( as a top text button) + this.GUI.AddText("v" buttonName " x" tabProp.x " y" (tabProp.y + (tabProp.h + labelDistance)*(A_Index-1)) " h" tabProp.h " w" tabProp.w " BackgroundTrans +0x200 " tabProp.labelProp.textOpt, tabProp.labelName[A_Index]) + this.GUI[buttonName].SetFont(tabProp.labelProp.fontOpt, tabProp.labelProp.font) + this.GUI[buttonName].SetFont("c" tabProp.labelProp.fontNormalColor) + ; this.GUI[buttonName].OnEvent("Click", ButtonFunc) + this.GUI[buttonName].OnEvent("Click", OnTabClicked) + + ; Setting the first label to be the default tab If (A_Index != 1) Continue - MyGui.Focus_Tab := MyGui[button_name] - MyGui[focus_name].Visible := True - MyGui[button_name].SetFont("c" . tab_prop.label_prop.font_active_color) - (tab_prop.HasOwnProp("label_indicator")) ? (MyGui[indicator_name].Visible := True) : False - (tab_prop.HasOwnProp("logo_symbol")) ? MyGui[symbol_name].Setfont("c" . tab_prop.label_prop.font_active_color) : False + this.GUI.lastTab := this.GUI[buttonName] + this.GUI[focusName].Visible := True + this.GUI[buttonName].SetFont("c" tabProp.labelProp.fontActiveColor) + tabProp.HasOwnProp("labelIndicator") ? (this.GUI[indicatorName].Visible := True) : False + tabProp.HasOwnProp("logoSymbol") ? this.GUI[symbolName].Setfont("c" tabProp.labelProp.fontActiveColor) : False + } + + OnTabClicked(GuiCtrlObj, Info, *) { ; 需配合WM_MOUSEMOVE和WM_MOUSELEAVE使用 + currentTabName := GuiCtrlObj.name + If this.GUI[currentTabName] = this.GUI.lastTab + Return + + Tab.Choose(StrReplace(currentTabName, "_TAB_BUTTON")) ; 切换对应的(隐藏)标签页 + + For name in [this.GUI.lastTab.name, currentTabName] { ; 激活标签页的活跃态 + activeName := StrReplace(name, "_TAB_BUTTON", "_ACTIVE") + focusName := StrReplace(name, "_TAB_BUTTON", "_FOCUS") + indicatorName := StrReplace(name, "_TAB_BUTTON", "_INDICATOR") + logoSymbolName := StrReplace(name, "_TAB_BUTTON", "_SYMBOL") + color := (name=currentTabName) ? tabProp.labelProp.fontActiveColor : tabProp.labelProp.fontNormalColor + + this.GUI[focusName].Visible := (name=currentTabName) ? True:False ; 高亮焦点标签背景 + this.GUI[activeName].Visible := False ; 关闭鼠标下的低亮度高亮 + + this.GUI[name].SetFont("c" color) ; 高亮标签名称 + tabProp.HasOwnProp("logoSymbol") ? this.GUI[logoSymbolName].SetFont("c" color) : False ; 高亮标签图标名称 + tabProp.HasOwnProp("labelIndicator") ? this.GUI[indicatorName].Visible := ((name=currentTabName) ? True:False) : False ; 高亮其指示器名称 + } + + this.GUI.lastTab := this.GUI[currentTabName] ; 上次被点击标签页变为本次 } } } -Gdip_SetPicRoundedRectangle(GuiCtrl, Color, R, isFill) +Gdip_SetPicRoundedRectangle(GuiCtrl, Color, R, isFill:="True") { hwnd := GuiCtrl.Hwnd ; 获取控件hWnd GuiCtrl.GetPos(,,&W,&H) ; 获取控件的宽高 pBitmap := Gdip_CreateBitmap(W, H) ; 创建和控件大小相等的BMP位图 - G := Gdip_GraphicsFromImage(pBitmap) ; 创建画布(在BMP位图上) + G := Gdip_GraphicsFromImage(pBitmap) ; 创建画布(在BMP位图上) Gdip_SetSmoothingMode(G, 4) ; 设置画布平滑模式为抗锯齿 - If isFill="True" - { + if isFill="True" { ; 创建实心圆角矩形背景(注意笔刷画图的xy是相对位图距离,不是窗口距离) pBrushBack := Gdip_BrushCreateSolid(Color) - ;pBrushBack := Gdip_CreateLineBrushFromRect(0, 0, w, h, color, 0xff485563, LinearGradientMode:=0, WrapMode:=1) Gdip_FillRoundedRectangle(G, pBrushBack, 0, 0, W-1, H-1, R*(A_ScreenDPI/192)) Gdip_DeleteBrush(pBrushBack) - } - Else - { + } else { pPen := Gdip_CreatePen(Color, isFill) Gdip_DrawRoundedRectangle(G, pPen, 0, 0, w-1, h-1, R*(A_ScreenDPI/192)) ; "w-1" and "h-1" can make the border appear completely on the picture control Gdip_DeletePen(pPen) @@ -288,6 +256,4 @@ Gdip_SetPicRoundedRectangle(GuiCtrl, Color, R, isFill) ; 开始删除 Gdip_DeleteGraphics(G), Gdip_DisposeImage(pBitmap), DeleteObject(hBitmap) - - Return 0 } diff --git a/lib/Class_ConvertToIconFile.ahk b/lib/Class_ConvertToIconFile.ahk new file mode 100644 index 0000000..fc08e62 --- /dev/null +++ b/lib/Class_ConvertToIconFile.ahk @@ -0,0 +1,178 @@ +/* +` hIconToFile(v1) - https://www.autohotkey.com/boards/viewtopic.php?f=6&t=36733 + hIconToIcon(v2) - https://www.autohotkey.com/boards/viewtopic.php?f=76&t=93750&start=20 + + Function————————————————Description—————————————————————————————————————————————————————————————————————————————————— + ExtractIcon - 从可执行文件、DLL 或图标文件中获取指定索引位置(默认0)的图标句柄,总是返回大图标(32x32) + ExtractIconEx - 同ExtractIcon,但可检索大图标(32x32)或小图标(16x16)的句柄数组 + ExtractAssociatedIcon - 获取作为资源存储在文件中的图标或存储在文件的关联可执行文件中的大图标(32x32)的句柄 + SHGetFileInfo - 检索有关文件系统中的对象的信息,可获取Shell所关联的文件对象(驱动器,文件夹,打印机,普通文件等)的图标 + LoadImage - 加载DLL模块或可执行文件模块或图标文件的"指定分辨率"的图标(注意加载dll图标使用的是其模块) + LoadIcon - 从给定可执行文件的资源中抽取图标,源文件由实例标识,不是由文件名标识,图标由ID标识不是由索引标识 + ————————————————————————————————————————————————————————————————————————————————————————————————————————————————————— + + For example : + ConvertToIconFile.Dll( {dllName:'shell32.dll', index:'#176', size:'128', iconName:'test'} ) + ConvertToIconFile.Dll( {dllName:'shell32.dll', index:'#161', size:'0' , iconName:'test'} ) + ConvertToIconFile.PNG( {path:"C:\Users\11593\Downloads\Company Portal.png", size:'128', iconName:'test'} ) + ConvertToIconFile.PNG( {path:"C:\Users\11593\Downloads\Company Portal.png", size:'0' , iconName:'test'} ) + ConvertToIconFile.File( {path:"C:\Windows\regedit.exe", iconName:'test'} ) +*/ + +Class ConvertToIconFile { + + static Dll(obj:={dllName:'', index:'', size:'', iconName:''}) { + If !IsObject(obj) + Return MsgBox('Please enter the correct format for the object') + If !RegExMatch(obj.dllName, 'i)[\.dll|\.exe]$') + Return Msgbox('Please enter the correct of dllName.`ne.g. shell32.dll',,'iconi') + + obj.size := (!obj.HasOwnProp('size') or !IsNumber(obj.size) or (obj.size < 16)) ? '0' : obj.size + + If !Instr(obj.index, '#') { ; 索引号一般是正整数,但特殊情况下,如Windows API中,一些资源的索引号可能是负数 + hIcon := DllCall("Shell32\ExtractIcon", "Ptr", 0, "Str", obj.dllName, "Uint", (obj.index-1)) + } Else { ; https://www.autohotkey.com/boards/viewtopic.php?f=14&t=45279&p=205246&hilit=MAKEINTRESOURCE#p205246 + iconW := iconH := obj.size + hModule := DllCall("GetModuleHandle", "Str", obj.dllName, "UPtr"), unload := False + (!hModule) ? (hModule := DllCall("LoadLibrary", "Str", obj.dllName, "UPtr"), unload := true) : False + ; hModule := DllCall("Kernel32\LoadLibraryEx", "Str", obj.dllName, "Ptr", 0, "UInt", 0x02, "UPtr") + hIcon := DllCall('User32\LoadImage', "Ptr", hModule, "Str", obj.index, "UInt", 1, "Int", iconW, "Int", iconH, "UInt", 0x00002000) + unload ? DllCall("FreeLibrary", "UPtr", hModule) : False + } + + Loop ; 重复的名称 + obj.iconName := (A_Index = 2) ? obj.iconName '_1' : RegExReplace(obj.iconName, '_\d+$', '_' (A_Index-1)) + Until !FileExist(A_Desktop '\' obj.iconName '.ico') + + this._hIconToFile(hicon, obj.iconName), DllCall("DestroyIcon", "ptr", hIcon) + } + + static File(obj:={path:'', iconName:''}) { + If !IsObject(obj) + Return MsgBox('Please enter the correct format for the object') + If !FileExist(obj.path) + Return Msgbox('The file does not exist: ' obj.path) + + static SHGFI_ICON := 0x100 ; 检索表示文件图标的句柄 + ; static SHGFI_SMALLICON := 0x001 ; 修改 SHGFI_ICON,使函数检索文件的小型图标 + ; static SHGFI_LARGEICON := 0x000 ; 修改 SHGFI_ICON,使函数检索文件的大型图标 + ; static SHGFI_ICON + SHGFI_LARGEICON = 0x100 + ; static SHGFI_ICON + SHGFI_SMALLICON = 0x101 + fileInfo := Buffer(fisize := A_PtrSize + 688) + + DllCall("Shell32\SHGetFileInfoW" + , "Str", obj.path + , "Uint", 0 + , "Ptr", fileInfo + , "UInt", fisize + , "UInt", SHGFI_ICON) + hIcon := (NumGet(fileInfo, 0, "Ptr") ? NumGet(fileInfo, 0, "Ptr") : LoadPicture('shell32.dll', 'icon3')) + + Loop + obj.iconName := (A_Index = 2) ? obj.iconName '_1' : RegExReplace(obj.iconName, '_\d+$', '_' (A_Index-1)) + Until !FileExist(A_Desktop '\' obj.iconName '.ico') + + this._hIconToFile(hIcon, obj.iconName), DllCall("DestroyIcon", "Ptr", hIcon) + } + + static PNG(obj:={path:'', iconName:'', size:''}) { + If !IsObject(obj) + Return MsgBox('Please enter the correct format for the object') + If !FileExist(obj.path) + Return Msgbox('The file does not exist: ' obj.path) + If !RegExMatch(obj.path, 'i)\.png$') + Return Msgbox('This file is not PNG: ' obj.path) + + w := h := obj.size := (!obj.HasOwnProp('size') or !IsNumber(obj.size) or (obj.size < 16)) ? '0' : obj.size + + hBitmap := LoadPicture(obj.path, "GDI+ w" w ' h' h) + hIcon := this._HIconFromHBitmap(hBitmap) + + Loop + obj.iconName := (A_Index = 2) ? obj.iconName '_1' : RegExReplace(obj.iconName, '_\d+$', '_' (A_Index-1)) + Until !FileExist(A_Desktop '\' obj.iconName '.ico') + + this._hIconToFile(hIcon, obj.iconName), DllCall("DestroyIcon", "Ptr", hIcon), DllCall("DeleteObject", "Ptr", hBitmap) + } + + static _hIconToFile(hIcon, iconName) { + static szICONHEADER := 6, szICONDIRENTRY := 16, szBITMAP := 16 + A_PtrSize*2, szBITMAPINFOHEADER := 40 + , IMAGE_BITMAP := 0, flags := (LR_COPYDELETEORG := 0x8) | (LR_CREATEDIBSECTION := 0x2000) + , szDIBSECTION := szBITMAP + szBITMAPINFOHEADER + 8 + A_PtrSize*3 + , copyImageParams := ["UInt", IMAGE_BITMAP, "Int", 0, "Int", 0, "UInt", flags, "Ptr"] + + ICONINFO := Buffer(8 + A_PtrSize*3, 0) + DllCall("GetIconInfo", "Ptr", hIcon, "Ptr", ICONINFO) + if !hbmMask := DllCall("CopyImage", "Ptr", NumGet(ICONINFO, 8 + A_PtrSize, "UPtr"), copyImageParams*) { + MsgBox("CopyImage failed. LastError: " . A_LastError) + Return + } + hbmColor := DllCall("CopyImage", "Ptr", NumGet(ICONINFO, 8 + A_PtrSize*2, "UPtr"), copyImageParams*) + mskDIBSECTION := Buffer(szDIBSECTION, 0) + clrDIBSECTION := Buffer(szDIBSECTION, 0) + DllCall("GetObject", "Ptr", hbmMask , "Int", szDIBSECTION, "Ptr", mskDIBSECTION) + DllCall("GetObject", "Ptr", hbmColor, "Int", szDIBSECTION, "Ptr", clrDIBSECTION) + + clrWidth := NumGet(clrDIBSECTION, 4 , "UInt") + clrHeight := NumGet(clrDIBSECTION, 8 , "UInt") + clrBmWidthBytes := NumGet(clrDIBSECTION, 12, "UInt") + clrBmPlanes := NumGet(clrDIBSECTION, 16, "UShort") + clrBmBitsPixel := NumGet(clrDIBSECTION, 18, "UShort") + clrBits := NumGet(clrDIBSECTION, 16 + A_PtrSize, "UPtr") + colorCount := clrBmBitsPixel >= 8 ? 0 : 1 << (clrBmBitsPixel * clrBmPlanes) + clrDataSize := clrBmWidthBytes * clrHeight + + mskHeight := NumGet(mskDIBSECTION, 8 , "UInt") + mskBmWidthBytes := NumGet(mskDIBSECTION, 12, "UInt") + mskBits := NumGet(mskDIBSECTION, 16 + A_PtrSize, "UPtr") + mskDataSize := mskBmWidthBytes * mskHeight + + iconDataSize := clrDataSize + mskDataSize + dwBytesInRes := szBITMAPINFOHEADER + iconDataSize + dwImageOffset := szICONHEADER + szICONDIRENTRY + + ICONHEADER := Buffer(szICONHEADER, 0) + NumPut("UShort", 1, ICONHEADER, 2) + NumPut("UShort", 1, ICONHEADER, 4) + + ICONDIRENTRY := Buffer(szICONDIRENTRY, 0) + NumPut("UChar" , clrWidth , ICONDIRENTRY, 0) + NumPut("UChar" , clrHeight , ICONDIRENTRY, 1) + NumPut("UChar" , colorCount , ICONDIRENTRY, 2) + NumPut("UShort", clrBmPlanes , ICONDIRENTRY, 4) + NumPut("UShort", clrBmBitsPixel, ICONDIRENTRY, 6) + NumPut("UInt" , dwBytesInRes , ICONDIRENTRY, 8) + NumPut("UInt" , dwImageOffset , ICONDIRENTRY, 12) + + NumPut("UInt", clrHeight*2 , clrDIBSECTION, szBITMAP + 8) + NumPut("UInt", iconDataSize, clrDIBSECTION, szBITMAP + 20) + + File := FileOpen(A_Desktop "\" iconName . '.ico', "w", "cp0") + File.RawWrite(ICONHEADER , szICONHEADER) + File.RawWrite(ICONDIRENTRY, szICONDIRENTRY) + File.RawWrite(clrDIBSECTION.Ptr + szBITMAP, szBITMAPINFOHEADER) + File.RawWrite(clrBits + 0 , clrDataSize) + File.RawWrite(mskBits + 0 , mskDataSize) + File.Close() + + DllCall("DeleteObject", "Ptr", hbmColor) + DllCall("DeleteObject", "Ptr", hbmMask) + } + + static _HIconFromHBitmap(hBitmap, test_w:=0, test_h:=0) { + BITMAP := Buffer(size := 4*4 + A_PtrSize*2, 0) + DllCall("GetObject", "Ptr", hBitmap, "Int", size, "Ptr", BITMAP) + width := NumGet(BITMAP, 4, "UInt"), height := NumGet(BITMAP, 8, "UInt") + hDC := DllCall("GetDC", "Ptr", 0, "Ptr") + hCBM := DllCall("CreateCompatibleBitmap", "Ptr", hDC, "Int", width, "Int", height, "Ptr") + ICONINFO := Buffer(4*2 + A_PtrSize*3, 0) + + NumPut("Int", 1, ICONINFO) + NumPut("Ptr", hCBM, ICONINFO, 4*2 + A_PtrSize) + NumPut("Ptr", hBitmap, ICONINFO, 4*2 + A_PtrSize*2) + + hIcon := DllCall("CreateIconIndirect", "Ptr", ICONINFO, "Ptr") + DllCall("DeleteObject", "Ptr", hCBM), DllCall("ReleaseDC", "Ptr", 0, "Ptr", hDC) + Return hIcon + } +} \ No newline at end of file diff --git a/lib/Class_FontSymbol.ahk b/lib/Class_FontSymbol.ahk new file mode 100644 index 0000000..fb1e93b --- /dev/null +++ b/lib/Class_FontSymbol.ahk @@ -0,0 +1,30 @@ +/* + mygu.SegoeUISymbol := FontSymbol(mainGUI, "Segoe UI Symbol") + mainGUI.SegoeUISymbol.Font( {name:'', unicode:'', x:'', y:'', w:'', h:'', textColor:'', backColor:'', fontOpt:'s12', text_options:'+0x200 center'} ) + Font中的对象可以不添加backColor,默认为透明 +*/ + +Class FontSymbol +{ + __New(GuiObj, Font) => (this.GUI := GuiObj , this.selectedFont := Font) + + Font(obj:={font_name:'',name:'', unicode:'', x:'', y:'', w:'', h:'', textColor:'', backColor:'', fontOpt:'s12', textOpt:'+0x200 center'}) { + If !IsObject(obj) + Return + For propName, value in obj.OwnProps() { + If !Instr(propName, 'color') + Continue + Switch StrLen(color:=value) { + Case 6 : obj.%propName% := (propName='textColor') ? 'c' color : 'Background' color + Case 8 : obj.%propName% := (propName='textColor') ? 'c' RegExReplace(color,'i)^0x') : 'Background' RegExReplace(color,'i)^0x') + Case 10 : obj.%propName% := (propName='textColor') ? 'c' RegExReplace(color, 'i)^0x..') : 'Background' RegExReplace(color, 'i)^0x..') + Default : obj.%propName% := (propName='textColor') ? 'cffffff' : 'BackgroundTrans' + } + } + obj.HasOwnProp("backColor") ? False : obj.backColor := "BackgroundTrans" + this.noSpacesName := RegExReplace(obj.name, "[\s\r\n]+") + this.GUI.AddText('v' this.noSpacesName ' x' obj.x ' y' obj.y ' w' obj.w ' h' obj.h ' ' obj.backColor ' ' obj.textOpt, chr(obj.unicode)) + this.GUI[this.noSpacesName].SetFont(obj.fontOpt ' ' obj.textColor, Trim(this.selectedFont)) + } +} + diff --git a/lib/GuiCtrlTips.ahk b/lib/Class_GuiCtrlTips.ahk similarity index 100% rename from lib/GuiCtrlTips.ahk rename to lib/Class_GuiCtrlTips.ahk diff --git a/lib/Class_ListIcons.ahk b/lib/Class_ListIcons.ahk new file mode 100644 index 0000000..62e23d0 --- /dev/null +++ b/lib/Class_ListIcons.ahk @@ -0,0 +1,285 @@ +; ================================================================ +; Author: TheArkive +; Github: https://github.com/TheArkive/ListIcons_ahk2 +; ListIcons class +; +; Methods: +; +; icons.GetResourceList(sFileName) +; +; USAGE: array := icons.GetResourceList(sFileName) +; +; - Checks %SystemRoot%, %SystemRoot%\System32, and A_ScriptDir for sFileName, or +; just use a full path. +; - Returns array of resource names (ie. #1, #32, #16315, sometimes text names too) +; +; icons.IconPicker(sIconFile:="", parentHwnd:=0, resources:=true) +; +; USAGE: obj := icons.IconPicker(...) +; +; - Specify sIconFile, or pick from the gui list. +; - Specify parentHwnd of parent window for modal effect. +; - Specify resources as false to show index numbers in the list instead of resource names. +; - Return obj has the following properties: +; type: HICON, HBITMAP, HCURSOR +; index: 1-based index number +; file: The file the icon was found in. +; name: The resource name of the icon. Use with DllCall("LoadImage"). +; ================================================================ + +class ListIcons { + Static IconSelectFileList := ["%SystemRoot%\explorer.exe" + , "%SystemRoot%\system32\accessibilitycpl.dll", "%SystemRoot%\system32\SensorsCpl.dll" + , "%SystemRoot%\system32\ddores.dll" , "%SystemRoot%\system32\setupapi.dll" + , "%SystemRoot%\system32\gameux.dll" , "%SystemRoot%\system32\shell32.dll" + , "%SystemRoot%\system32\imageres.dll" , "%SystemRoot%\system32\UIHub.dll" + , "%SystemRoot%\system32\mmcndmgr.dll" , "%SystemRoot%\system32\vpc.exe" + , "%SystemRoot%\system32\mmres.dll" , "%SystemRoot%\system32\wmp.dll" + , "%SystemRoot%\system32\mstscax.dll" , "%SystemRoot%\system32\wmploc.dll" + , "%SystemRoot%\system32\netshell.dll" , "%SystemRoot%\system32\wpdshext.dll" + , "%SystemRoot%\system32\networkmap.dll" , "%SystemRoot%\system32\wucltux.dll" + , "%SystemRoot%\system32\pifmgr.dll" , "%SystemRoot%\system32\xpsrchvw.exe"] + + Static GetResourceList(str) { ; str = file name + fileLoc := [str, A_WinDir "\" str,A_WinDir "\System32\" str] + iconFileExist := false, sFileName := '' + + For A_index, sFile in fileLoc { + If !FileExist(sFile) + Continue + iconFileExist := true, sFileName := sFile + } + + If !iconFileExist { + Msgbox "Specified file does not exist.`r`n`r`nSpecifically: " str + return + } + + hModule := DllCall("GetModuleHandle", "Str", sFileName, "UPtr"), unload := False + (!hModule) ? (hModule := DllCall("LoadLibrary", "Str", sFileName, "UPtr"), unload := True) : False + ; If !hModule + ; hModule := DllCall("LoadLibrary", "Str", sFileName, "UPtr"), unload := true + + cbAddr := CallbackCreate(ObjBindMethod(this,"EnumIcons",List:=[]),,4) + r1 := DllCall("EnumResourceNames", "UPtr", hModule, "Str", "#14", "UPtr", cbAddr, "UPtr", 0) ; #14 + CallbackFree(cbAddr) + + unload ? DllCall("FreeLibrary", "UPtr", hModule) : '' + + return List + } + + Static EnumIcons(List, hModule, sType, sName, lParam) { ; callback for DllCall("EnumResourceNames") + str := (StrLen(sName) > 5) ? StrGet(sName) : '' + val := str ? str : "#" sName + List.Push(val) + + return true + } + + Static AddIconsToList(objLV, IconFile) { + If IconFile { + str := IconFile + fileLoc := [str, A_WinDir "\" str, A_WinDir "\System32\" str], iconFileExist := false + + For A_Index, sFile in fileLoc { + If !FileExist(sFile) + Continue + IconFile := sFile, iconFileExist := true + } + + If !iconFileExist { + Throw Error("Specified file does not exist.",,str) + } + } + + IconFile := StrReplace(IconFile, "%SystemRoot%", A_WinDir) + + If FileExist(IconFile) { + iList := this.GetResourceList(IconFile) + objLV.IconIndexArray := [] + + objLV.Delete() + objLV.Opt("-Redraw") + + ImgList := IL_Create(400,5,1) + objLV.SetImageList(ImgList,0) + + For A_Index, resName in iList { + hPic := LoadPicture(IconFile, "Icon" A_Index, &handleType) + prefix := !handleType ? "HBITMAP" : ((handleType = 2) ? "HCURSOR" : "HICON") + + objLV.IconIndexArray.Push({type:prefix, name:resName, index:A_Index, file:IconFile}) + objLV.Add("Icon" A_Index, A_Index, resName) + + IL_Add(ImgList, prefix ":" hPic) + DllCall("DestroyIcon", "ptr", hPic) + } + + objLV.Opt("+Redraw") + } Else { + Msgbox "Invalid file selected." + } + } + +/* + Static IconPicker(sIconFile:="", hwnd:=0, resources:=true) { + this.resources := resources + If sIconFile { + str := sIconFile + fileLoc := [str, A_WinDir "\" str, A_WinDir "\System32\" str], iconFileExist := false, sFileName := "" + + For A_Index, sFile in fileLoc { + If !FileExist(sFile) + Continue + sIconFile := sFile, iconFileExist := true + } + + If !iconFileExist { + throw Error("Specified file does not exist.",,str) + } + } + + newList := [] + For i, file_name In this.IconSelectFileList + If (FileExist(StrReplace(file_name,"%SystemRoot%",A_WinDir))) + newList.Push(file_name) + this.IconSelectFileList := newList + + hwndStr := WinExist("ahk_id " hwnd) ? " +Owner" hwnd : "" + + IconSelectUserGui := Gui("-MaximizeBox -MinimizeBox" hwndStr,"List Icons") + IconSelectUserGui.OnEvent("close",this.gui_close.Bind(this)) + IconSelectUserGui.IconSelectIndex := "" + + IconSelectUserGui.Add("Text","","File:") + ctl := IconSelectUserGui.Add("ComboBox","vIconFile x+m yp-3 w420",this.IconSelectFileList) + + ctl.OnEvent("change",this.gui_events.Bind(this)) ; ObjBindMethod(this,"gui_events") + ctl.Text := sIconFile + + ctl := IconSelectUserGui.Add("Button","vPickFileBtn x+m yp w20","...") + ctl.OnEvent("click",this.gui_events.Bind(this)) + + LV := IconSelectUserGui.Add("ListView","vIconList xm w480 h220 Icon") + LV.OnEvent("doubleclick",this.gui_events.Bind(this)) + + ctl := IconSelectUserGui.Add("Button","vOkBtn x+-150 y+5 w75","OK") + ctl.OnEvent("click",this.gui_events.Bind(this)) + + ctl := IconSelectUserGui.Add("Button","vCancelBtn x+0 w75","Cancel") + ctl.OnEvent("click",this.gui_events.Bind(this)) + + ctl := IconSelectUserGui.Add("Button","vSwitch x+-480 w75","Show Index") + ctl.OnEvent("click",this.gui_events.Bind(this)) + + If (WinExist("ahk_id " hwnd)) { + p := GuiFromHwnd(hwnd) + p.GetPos(&x,&y,&w,&h), pPos := {x:x, y:y, w:w, h:h} + x := pPos.x + (pPos.w / 2) - (261 * (A_ScreenDPI / 96)) + y := pPos.y + (pPos.h / 2) - (149 * (A_ScreenDPI / 96)) + params := "x" x " y" y + IconSelectUserGui.Show(params) + } Else + IconSelectUserGui.Show() + + (sIconFile) ? this.IconSelectListIcons(IconSelectUserGui,sIconFile) : "" + sIconFile := StrReplace(IconSelectUserGui["IconFile"].Text,"%SystemRoot%",A_WinDir) + + Pause + + If (idx := IconSelectUserGui.IconSelectIndex) { + If !(IconSelectUserGui.IconIndexArray.Has(idx)) { + For index, obj in IconSelectUserGui.IconIndexArray { + If (obj.name = idx) { + oOutput := obj + Break + } + } + } Else + oOutput := IconSelectUserGui.IconIndexArray[idx] + } Else + oOutput := {index:0, type:"", file:"", name:""} + + IconSelectUserGui.Destroy() + + return oOutput + } + + Static gui_events(ctl, info) { + If (ctl.Name = "IconFile") { + IconFile := StrReplace(ctl.Text,"%SystemRoot%",A_WinDir) + this.IconSelectListIcons(ctl.gui,IconFile) + } Else If (ctl.Name = "PickFileBtn") { + IconFile := ctl.gui["IconFile"] + IconFileStr := FileSelect("","C:\Windows\System32","Select an icon file:") + + If (IconFileStr) + this.IconSelectListIcons(ctl.gui,IconFileStr) + } Else if (ctl.Name = "IconList" Or ctl.Name = "OkBtn") { + curCtl := ctl.gui["IconList"] + curRow := curCtl.GetNext() + + If !curRow { + Msgbox "No icon selected." + return + } + + ctl.gui.IconSelectIndex := curCtl.GetText(curRow) + If ctl.Name = "OkBtn" + Pause false + } Else If (ctl.Name = "CancelBtn") { + ctl.gui.IconSelectIndex := 0 + Pause false + } Else If (ctl.Name = "Switch") { + LV := ctl.gui["IconList"] + + If (ctl.Text = "Show Index") { + Loop LV.GetCount() + LV.Modify(A_Index,,ctl.gui.IconIndexArray[A_Index].Index) + ctl.Text := "Show Name" + } Else { + Loop LV.GetCount() + LV.Modify(A_Index,,ctl.gui.IconIndexArray[A_Index].Name) + ctl.Text := "Show Index" + } + } + } + + Static gui_close(_gui) { + _gui.IconSelectIndex := 0 + Pause false + } + + Static IconSelectListIcons(oGui, IconFile) { + IconFile := StrReplace(IconFile, "%SystemRoot%", A_WinDir) + If (FileExist(IconFile)) { + iList := this.GetResourceList(IconFile) + oGui.IconIndexArray := [] + + oGuiLV := oGui["IconList"] + oGuiLV.Delete() + oGuiLV.Opt("-Redraw") + + ImgList := IL_Create(400,5,1) + oGuiLV.SetImageList(ImgList,0) + + MaxIcons := 0 + For A_Index, resName in iList { + hPic := LoadPicture(IconFile,"Icon" A_Index, &handleType) + prefix := !handleType ? "HBITMAP" : ((handleType = 2) ? "HCURSOR" : "HICON") + idx := (this.resources) ? resName : A_Index + + oGui.IconIndexArray.Push({type:prefix, name:resName, index:A_Index, file:IconFile}) + oGuiLV.Add("Icon" A_Index,((this.resources) ? resName : A_Index)) + + IL_Add(ImgList, prefix ":" hPic) + DllCall("DestroyIcon", "ptr", hPic) + } + + oGuiLV.Opt("+Redraw") + } Else + Msgbox "Invalid file selected." + } +*/ +} \ No newline at end of file diff --git a/lib/Class_ModernGUI.ahk b/lib/Class_ModernGUI.ahk new file mode 100644 index 0000000..28e2a92 --- /dev/null +++ b/lib/Class_ModernGUI.ahk @@ -0,0 +1,137 @@ +Class ModernGUI +{ + __New(obj:={GUI:'', x:'center', y:'center', w:'', h:'', backColor:'', GuiOpt:'+DPIScale', GuiNmae:'', GuiFontOpt:'s12 Bold cffffff', GuiFont:'Microsoft YaHei', showOpt:''}) { + If !isObject(obj) + Return MsgBox('Please create an object for the GUI option`n请在你的ModerGui()中创建object(对象)') + this._SetDefaultsProperties() + this._SetGuiProperties(obj) + this._CreateGUI() + } + + ;======================================================================================================== + ; Create: Caption + ; buttonW The width of the close, maximize, and minimize buttons (关闭、最大化、最小化按钮的宽度) + ; png_quality The width and height of PNG imagess ("png_quality"是常态PNG图片和活动态PNG图片的宽高) + ; Note If using this function, please remember to remove the original caption from this.GUI, that is, add "-caption" to the Class--CreateMordenGUI(GuiOpt:''). So there won't be two title bars + ; 若创建标题栏,请记得给this.GUI移除原来的标题栏,即CreateMordenGUI(GuiOpt:'')中添加"-caption",这样就不会有两个标题栏了 + ; Note After using this function to create the caption, if you don't use this class to create controls , remember to subtract the height of the caption from the "y" value of these controls + ; 使用这个函数创建标题栏后,若不使用这个类来创建控件,需要记得给这些控件的y值减去标题的高 + ;======================================================================================================== + CreateCaption(obj:={captionH:'', titleColor:'', backColor:'', buttonW:'', buttonActiveColor:''}) { + + For propName, value in obj.OwnProps() { ; Change to the correct colour format (e.g. ffffff) + If !RegExMatch(propName, 'i)backColor|title_color') ; 无需格式化"buttonActiveColor",后续WindowCrontrolButtons函数会格式化 + Continue + Switch StrLen(color := Trim(value)) { + Case 8 : Obj.%propName% := LTrim(color, '0x') + Case 10 : Obj.%propName% := RegExReplace(color, 'i)^0x..') + } + } + ; Create Windows Crontro Button + this.WindowCrontrolButtons({marginTop:'0', marginRight:'0', buttonW:obj.buttonW, buttonH:obj.caption_h, activeColor:obj.buttonActiveColor, symbol_backcolor:obj.backColor}) + ; Create the caption + this.GUI.AddText('vCaption x0 y0 w' this.W ' h' obj.caption_h ' c' obj.title_color ' Background' obj.backColor ' +0x4000000 +0x200', '`s`s' this.GuiNmae).OnEvent('DoubleClick', (*) => '') + } + + ;======================================================================================================== + ; Create Windows Control Button(关闭、最大化、最小化按钮) + ;======================================================================================================== + WindowCrontrolButtons(obj:={marginTop:'', marginRight:'', buttonW:'', buttonH:'', activeColor:''}) { + Switch StrLen(color := Trim(obj.activeColor)) { ; Change to the correct colour format (e.g. 000000) + Case 6 : obj.activeColor := color + Case 8 : obj.activeColor := LTrim(color, '0x') + Case 10: obj.activeColor := RegExReplace(color, 'i)^0x..') + } + + For key, value in map('WinClose', '0x2716', 'WinMaximize', '0x25A2', 'WinMinimize', '0xE0B8') { ; Create Windows Control Buttons + activeName := key '_ACTIVE' + buttonName := key '_BUTTON' + buttonX := this.w - (obj.marginRight + A_Index * obj.buttonW) + buttonY := obj.marginTop + textColor := (key='WinMaximize') ? '575757' : 'ffffff' + ; 活跃态(不创建最大化的活跃态) + (key!='WinMaximize') ? this.GUI.AddPicture('v' activeName ' x' buttonX ' y' buttonY ' w' obj.buttonW ' h' obj.buttonH ' background' obj.activeColor ' +Hidden -E0x200') : False + ; 文本符号按钮(不创建最大化的按钮) + FontSymbol(this.GUI, "Segoe UI Symbol").Font( {name:buttonName, unicode:value, x:buttonX, y:buttonY, w:obj.buttonW, h:obj.buttonH, textColor:textColor, backColor:'Trans', fontOpt:'s' obj.buttonH/2, textOpt:'+0x200 center'} ) + ; (key!='WinMaximize') ? this.GUI[buttonName].OnEvent('Click', ButtonFunc) : False + (key='WinMinimize') ? this.GUI[buttonName].OnEvent('Click', (*) => WinMinimize(this.GUI)) : False + (key='WinClose') ? this.GUI[buttonName].OnEvent('Click', (*) => ExitApp()) : False + } + + /* + CloseWindowWithFadeEffect(GuiHwnd) { + static TIME := 600 + static AW_BLEND := 0x00080000 ; 淡化效果 + static AW_HIDE := 0x00010000 ; 隐藏窗口 + + ; (IsSet(iconGUI) and (iconGUI is GUI)) ? iconGUI.Destroy() : False + + WinGetPos(,,&OutWidth, &OutHeight, GuiHwnd) + WinSetRegion("0-0 r30-30 w" OutWidth " h" OutHeight, GuiHwnd) ; 关闭窗口时DWM会失效导致圆角消失,影响视觉效果,因此需在关闭前另使其他办法设置圆角 + DllCall("user32\AnimateWindow", "ptr", GuiHwnd, "uint", TIME, "uint", AW_BLEND|AW_HIDE) + ExitApp + } + */ + } + + Show() { + this._FrameShadow(this.GUI.hwnd) + this.GUI.show(this.showOpt) + } + + _SetDefaultsProperties() { + this.w := 520 + this.h := 520 + this.backColor := 'ffffff' + this.GuiOpt := '+DPIScale' + this.GuiNmae := 'ikineticate' + this.GuiFont := 'Microsoft YaHei' + this.GuiFontOpt := 's12 Bold cffffff' + this.showOpt := '' + } + + _SetGuiProperties(obj) { + this.GUI := Obj.GUI + ; If there is no object, or the value is null, or the value is 'center', then take the default value + this.w := Obj.HasOwnProp('w') ? (obj.w ? obj.w : this.w) : this.w + this.h := Obj.HasOwnProp('h') ? (obj.h ? obj.h : this.h) : this.h + this.x := Obj.HasOwnProp('x') ? (obj.x ? (!Instr(obj.x, 'center') ? obj.x : 'center') : 'center') : 'center' + this.y := Obj.HasOwnProp('y') ? (obj.y ? (!Instr(obj.y, 'center') ? obj.y : 'center') : 'center') : 'center' + this.showOpt := Obj.HasOwnProp('showOpt') ? (obj.showOpt .= ' x' this.x ' y' this.y ' w' this.w ' h' this.h) : False + this.GuiOpt := Obj.HasOwnProp('GuiOpt') ? (obj.GuiOpt ? obj.GuiOpt : this.GuiOpt ) : this.GuiOpt + this.GuiNmae := Obj.HasOwnProp('GuiNmae') ? (obj.GuiNmae ? obj.GuiNmae : this.GuiNmae ) : this.GuiNmae + this.GuiFont := Obj.HasOwnProp('GuiFont') ? (obj.GuiFont ? obj.GuiFont : this.GuiFont ) : this.GuiFont + this.GuiFontOpt := Obj.HasOwnProp('GuiFontOpt') ? (obj.GuiFontOpt ? obj.GuiFontOpt : this.GuiFontOpt) : this.GuiFontOpt + + if !obj.HasOwnProp('backColor') or !obj.backColor { ; Change to the correct color format (e.g. ffffff) + this.backColor := 'ffffff' + } else { + this.backColor := (StrLen(obj.backColor)=8 ) ? LTrim(obj.backColor, '0x') : obj.backColor + this.backColor := (StrLen(obj.backColor)=10) ? RegExReplace(obj.backColor, 'i)^0x..') : obj.backColor + } + } + + _CreateGUI() { + global + this.GUI.Title := this.GuiNmae + this.GUI.BackColor := this.backColor + this.GUI.Opt(this.GuiOpt) + this.GUI.OnEvent('Close', (*) => ExitApp) + this.GUI.SetFont(this.GuiFontOpt, this.GuiFont) + this.GUI.activeControl := False ; 用于WM_MOUSEMOVE和标签页按钮,最终目的是避免标签页闪烁 + } + + ; 设置窗口圆角+边框阴影 https://www.autohotkey.com/boards/viewtopic.php?f=82&t=113202&p=560692&hilit=WinSetRegion#p560692 + _FrameShadow(GuiHwnd) { + DllCall('dwmapi.dll\DwmIsCompositionEnabled', 'int*', &dwmEnabled:=0) + static GCL_STYLE := -26 + if !dwmEnabled { + DllCall('user32.dll\SetClassLongPtr', 'ptr', GuiHwnd, 'int', GCL_STYLE, 'ptr', DllCall('user32.dll\GetClassLongPtr', 'ptr', GuiHwnd, 'int', GCL_STYLE) | 0x20000) + } else { + margins := Buffer(16, 0) ; DWM(桌面窗口管理器): 提供的视觉效果有毛玻璃框架、3D窗口变换动画、窗口翻转和高分辨率支持(自带双缓冲) + NumPut('int', 1, 'int', 1, 'int', 1, 'int', 1, margins) + DllCall('dwmapi.dll\DwmSetWindowAttribute', 'ptr', GuiHwnd, 'Int', 2, 'Int*', 2, 'Int', 4) + DllCall('dwmapi.dll\DwmExtendFrameIntoClientArea', 'ptr', GuiHwnd, 'ptr', margins) + } + } +} \ No newline at end of file diff --git a/lib/Class_MyGui.ahk b/lib/Class_MyGui.ahk deleted file mode 100644 index 52ee748..0000000 --- a/lib/Class_MyGui.ahk +++ /dev/null @@ -1,161 +0,0 @@ -; If you use this class to create caption, this variable can automatically subtract the height of the caption from the height of button created by the class -; 若创建了caption,则这个变量可以使后续使用CreateButton类创建的按钮控件的高度自动减去标题的高 -_caption_h := "" - -Class CreateModernGUI -{ - __New( obj:={x:"center", y:"center", w:"", h:"", back_color:"", gui_options:"+DPIScale", gui_name:"", gui_font_options:"s12 Bold cffffff", gui_font:"Microsoft YaHei", show_options:""} ) - { - If !isObject(obj) - Return MsgBox("Please create an object for the GUI option`n请在你的CreateModerGui()中创建对象") - this._SetDefaultsProperties() - this._SetGuiProperties(obj) - this._CreateGUI() - } - - SetFont(options, font) - { - MyGui.SetFont(options, font) - } - - ;======================================================================================================== - ; Create: Caption - ; button_w The width of the close, maximize, and minimize buttons (关闭、最大化、最小化按钮的宽度) - ; png_quality The width and height of PNG imagess ("png_quality"是常态PNG图片和活动态PNG图片的宽高) - ; Note If using this function, please remember to remove the original caption from MyGui, that is, add "-caption" to the Class--CreateMordenGUI(gui_options:""). So there won't be two title bars - ; 若创建标题栏,请记得给MyGui移除原来的标题栏,即CreateMordenGUI(gui_options:"")中添加"-caption",这样就不会有两个标题栏了 - ; Note After using this function to create the caption, if you don't use this class to create controls , remember to subtract the height of the caption from the "y" value of these controls - ; 使用这个函数创建标题栏后,若不使用这个类来创建控件,需要记得给这些控件的y值减去标题的高 - ;======================================================================================================== - CreateCaption( obj:={caption_h:"", title_color:"", back_color:"", button_w:"", button_active_color:""} ) - { - ; Change to the correct colour format (e.g. ffffff) - For obj_name, descriptor in obj.OwnProps() - { - If !RegExMatch(obj_name, "back_color|title_color") ; 不需要格式化"button_active_color" - Continue - Switch StrLen(color:=Trim(descriptor)) - { ; 不可直接使用obj.obj_name,obj_name是值不是变量,使用%name%调用一个名为name的变量 - Case 4 : Obj.%obj_name% := "000000" ; 避免输入trans - Case 8 : Obj.%obj_name% := RegExReplace(color, "i)^0x" ) - Case 10 : Obj.%obj_name% := RegExReplace(color, "i)^0x..") - } - } - ; Create Windows Ctrl button - this.CreateWindowsControlButton({margin_top:"0", margin_right:"0", button_w:obj.button_w, button_h:obj.caption_h, active_color:obj.button_active_color, symbol_backcolor:obj.back_color}) - ; Create a title for the caption - MyGui.AddText("vCaption x0 y0 w" . this.W . " h" . obj.caption_h . " c" . obj.title_color . " Background" . obj.back_color . " +0x4000000 +0x200", "`s`s" . this.gui_name).OnEvent("DoubleClick", (*) => "") - global _caption_h := obj.caption_h ; 使后续使用CreateButton类来创建的按钮控件自动减去标题的高 - } - - ;======================================================================================================== - ; Create Windows Control Button(创建关闭、最大化、最小化按钮) - ;======================================================================================================== - CreateWindowsControlButton( obj:={margin_top:"", margin_right:"", button_w:"", button_h:"", active_color:"", symbol_backcolor:""} ) - { - ; Change to the correct colour format (e.g. 000000) - Switch StrLen(color:=Trim(obj.active_color)) - { - Case 6 : obj.active_color:= color ; 不能直接obj.obj_name,因为这里的obj_name是一个值不是变量 - Case 8 : obj.active_color:= RegExReplace(color,"i)^0x") - Case 10: obj.active_color:= RegExReplace(color, "i)^0x..") - } - ; Create Windows Control Buttons (Replace button icons with font symbols) (创建文本符号的控制窗口按钮) - For key, value in map("Close", "0x2716", "Maximize", "0x25A2", "Minimize", "0xE0B8") - { - active_name := key . "_ACTIVE" - button_name := key . "_BUTTON" - button_x := this.w - (obj.margin_right + A_Index * obj.button_w) - button_y := obj.margin_top - text_color := (key="Maximize") ? "575757" : "ffffff" - ; 常态 - (obj.HasOwnProp("symbol_backcolor")) ? MyGui.AddPicture("x" . button_x . " y" . button_y . " w" . obj.button_w . " h" . obj.button_h . " background" . obj.symbol_backcolor . " -E0x200") : False - ; 活跃态 - (key!="Maximize") ? MyGui.AddPicture("v" active_name " x" . button_x . " y" . button_y . " w" . obj.button_w . " h" . obj.button_h . " background" . obj.active_color . " +Hidden -E0x200") : False - ; 文本按钮 - FontSymbol( {name:button_name, x:button_x, y:button_y, w:obj.button_w, h:obj.button_h, unicode:value, font_name:"Segoe UI Symbol", text_color:text_color, back_color:"Trans", font_options:"s" obj.button_h/2, text_options:"+0x200 center"} ) - (key!="Maximize") ? MyGui[button_name].OnEvent("Click", ButtonFunc) : False - } - } - - GuiShow(options) - { - MyGui.show(options) - } - - _SetDefaultsProperties() - { - this.w := 520 - this.h := 520 - this.back_color := "ffffff" - this.gui_options := " +DPIScale " - this.gui_name := "ikineticate" - this.gui_font := "Microsoft YaHei" - this.gui_font_options := "s12 Bold cffffff" - this.show_options := "" - } - - _SetGuiProperties(obj) - { - ; If there is no object, or the value is null, or the value is 'center', then take the default value - this.w := Obj.HasOwnProp("w") ? (obj.w ? obj.w : this.w) : this.w - this.h := Obj.HasOwnProp("h") ? (obj.h ? obj.h : this.h) : this.h - this.x := Obj.HasOwnProp("x") ? (obj.x ? (!Instr(Trim(obj.x), "center") ? obj.x : "center") : "center") : "center" - this.y := Obj.HasOwnProp("y") ? (obj.y ? (!Instr(Trim(obj.y), "center") ? obj.y : "center") : "center") : "center" - ; Change to the correct color format (e.g. ffffff) - If !obj.HasOwnProp("back_color") or !obj.back_color - { - this.back_color := "ffffff" - } - Else - { - this.back_color:= (StrLen(obj.back_color)=8) ? RegExReplace(obj.back_color, "i)^0x") : obj.back_color - this.back_color:= (StrLen(obj.back_color)=10) ? RegExReplace(obj.back_color, "i)^0x..") : obj.back_color - } - - this.gui_options := Obj.HasOwnProp("gui_options") ? (!obj.gui_options ? this.gui_options : obj.gui_options) : this.gui_options - this.gui_name := Obj.HasOwnProp("gui_name") ? (!obj.gui_name ? this.gui_name : obj.gui_name) : this.gui_name - this.gui_font := Obj.HasOwnProp("gui_font") ? (!obj.gui_font ? this.gui_font : obj.gui_font) : this.gui_font - this.gui_font_options := Obj.HasOwnProp("gui_font_options") ? (!obj.gui_font_options ? this.gui_font_options : obj.gui_font_options) : this.gui_font_options - this.show_options := Obj.HasOwnProp("show_options") ? obj.show_options : "" - this.show_options .= " x" . this.x . " y" . this.y . " w" . this.w . " h" . this.h - } - - _CreateGUI() - { - local hwnd - global - MyGui := Gui(this.gui_options, this.gui_name) - hwnd := MyGui.hwnd - MyGui.BackColor := this.back_color - MyGui.SetFont(this.gui_font_options, this.gui_font) - MyGui.OnEvent("Close", (*) => ExitApp()) - MyGui.active_control := False ; 用于WM_MOUSEMOVE和标签页按钮,最终目的是避免标签页闪烁 - return hwnd - } -} - - - -;========================================================= -; 创建文字符号 -;========================================================= -FontSymbol( obj:={name:"", x:"", y:"", w:"", h:"", unicode:"", font_name:"", text_color:"", back_color:"", font_options:"", text_options:"+0x200 center"} ) -{ - If !IsObject(obj) - Return - For obj_name, descriptor in obj.OwnProps() - { - If !Instr(obj_name, "color") - Continue - Switch StrLen(color:=descriptor) - { - Case 6 : obj.%obj_name% := (obj_name="text_color") ? "c" color : "Background" . color - Case 8 : obj.%obj_name% := (obj_name="text_color") ? "c" RegExReplace(color,"i)^0x") : "Background" . RegExReplace(color,"i)^0x") - Case 10 : obj.%obj_name% := (obj_name="text_color") ? "c" RegExReplace(color, "i)^0x..") : "Background" . RegExReplace(color, "i)^0x..") - Default : obj.%obj_name% := (obj_name="text_color") ? "cffffff" : "BackgroundTrans" - } - } - text := MyGui.AddText("v" RegExReplace(obj.name,"`s") " x" obj.x " y" obj.y " w" obj.w " h" obj.h " " obj.back_color " " obj.text_options, chr(obj.unicode)) - text.SetFont(obj.font_options " " obj.text_color, Trim(obj.font_name)) -} \ No newline at end of file