├── LICENSE ├── MTT.ico ├── MinimizeToTray.au3 ├── README.md ├── cmdline.au3 ├── language_gen ├── HOW_TO_ADD_NEW_LANGUAGE.md ├── de.json ├── en.json ├── fr.json ├── ja.json ├── language_gen.py ├── language_gen.xlsx ├── requirements.txt └── zh.json └── libs ├── BinaryCall.au3 ├── GUIHotkey.au3 └── Json.au3 /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 sandwichdoge 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /MTT.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sandwichdoge/MinimizeToTray/e703f904dd585b45f4a305a2ce08fef9bae566d4/MTT.ico -------------------------------------------------------------------------------- /MinimizeToTray.au3: -------------------------------------------------------------------------------- 1 | #Region ;**** Directives created by AutoIt3Wrapper_GUI **** 2 | #AutoIt3Wrapper_Icon=MTT.ico 3 | #AutoIt3Wrapper_Outfile=MinimizeToTray.Exe 4 | #AutoIt3Wrapper_UseUpx=y 5 | #AutoIt3Wrapper_UseX64=n 6 | #AutoIt3Wrapper_Res_Description=Minimize windows to system tray 7 | #EndRegion ;**** Directives created by AutoIt3Wrapper_GUI **** 8 | 9 | #include-once 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include "libs/GUIHotkey.au3" 16 | #include "libs/Json.au3" 17 | #include "cmdline.au3" 18 | 19 | Global Const $CONFIG_INI = "MTTconf.ini" 20 | 21 | Global Const $DEFAULT_HIDE_WND_HK = "!{f1}" 22 | Global Const $DEFAULT_RESTORE_LAST_WND_HK = "!{f2}" 23 | Global Const $DEFAULT_RESTORE_ALL_WND_HK = "{f10}" 24 | 25 | If CmdlineHasParams() Then 26 | ;//Cmdline mode does not care about tray and GUI whatsoever. 27 | CmdlineRunCliMode() 28 | Exit 29 | EndIf 30 | 31 | 32 | Opt('TrayAutoPause', 0) 33 | Opt('TrayMenuMode', 3) 34 | 35 | ; Pre-allocate the array with a reasonable size to reduce frequent resizing operations 36 | Global $aWindowStack[20][3] 37 | Global $nWindowStackSize = 0 ; Track actual number of windows in the stack 38 | 39 | Global $hMutex = _WinAPI_CreateMutex("MTT_Operation_Mutex") 40 | 41 | Main() 42 | 43 | 44 | ; Read ini config file, set current global hotkeys 45 | Func InitializeConfigs() 46 | Global $sHK_HideWnd = IniRead($CONFIG_INI, "Hotkeys", "HIDE_WINDOW", $DEFAULT_HIDE_WND_HK) 47 | Global $sHK_RestoreLastWnd = IniRead($CONFIG_INI, "Hotkeys", "RESTORE_LAST_WINDOW", $DEFAULT_RESTORE_LAST_WND_HK) 48 | Global $sHK_RestoreAllWnd = IniRead($CONFIG_INI, "Hotkeys", "RESTORE_ALL_WINDOWS", $DEFAULT_RESTORE_ALL_WND_HK) 49 | 50 | Global $sRestoreAllWndsOnExit = IniRead($CONFIG_INI, "Extra", "RESTORE_ALL_WINDOWS_ON_EXIT", "True") 51 | Global $sAltF4EndProcess = IniRead($CONFIG_INI, "Extra", "ALT_F4_FORCE_END_PROCESS", "False") 52 | Global $sRestoreFocus = IniRead($CONFIG_INI, "Extra", "RESTORE_FOCUS", "True") 53 | Global $sAltEscFocusChange = IniRead($CONFIG_INI, "Extra", "ALT_ESC_FOCUS_CHANGE", "True") 54 | 55 | Global $bAltF4EndProcess = TextToBool($sAltF4EndProcess) 56 | Global $bRestoreOnExit = TextToBool($sRestoreAllWndsOnExit) 57 | Global $bRestoreFocus = TextToBool($sRestoreFocus) 58 | Global $bAltEscFocusChange = TextToBool($sAltEscFocusChange) 59 | 60 | Global $sLanguage = IniRead($CONFIG_INI, "Extra", "LANGUAGE", "en") 61 | 62 | HotKeySet($sHK_HideWnd, "HideCurrentWnd") 63 | HotKeySet($sHK_RestoreLastWnd, "RestoreLastWnd") 64 | HotKeySet("!{f4}", "HandleAltF4") 65 | HotKeySet($sHK_RestoreAllWnd, "RestoreAllWnd") 66 | OnAutoItExitRegister("ExitS") 67 | EndFunc ;==>InitializeConfigs 68 | 69 | 70 | Func InitializeLanguage() 71 | Local $sLanguageFile = FileRead("language_gen\" & $sLanguage & ".json") 72 | Local $hJobj = Json_Decode($sLanguageFile) 73 | Global $sTextId_Already_Running = LoadTextFromLanguageJsonObj($hJobj, '["TextId_Already_Running"]') 74 | Global $sTextId_Tray_Restore_All_Windows = LoadTextFromLanguageJsonObj($hJobj, '["TextId_Tray_Restore_All_Windows"]') 75 | Global $sTextId_Tray_Extra = LoadTextFromLanguageJsonObj($hJobj, '["TextId_Tray_Extra"]') 76 | Global $sTextId_Tray_Opt_AltF4_Force_Exit_Desc = LoadTextFromLanguageJsonObj($hJobj, '["TextId_Tray_Opt_AltF4_Force_Exit_Desc"]') 77 | Global $sTextId_Tray_Opt_Restore_On_Exit_Desc = LoadTextFromLanguageJsonObj($hJobj, '["TextId_Tray_Opt_Restore_On_Exit_Desc"]') 78 | Global $sTextId_Tray_Opt_Restore_Focus = LoadTextFromLanguageJsonObj($hJobj, '["TextId_Tray_Opt_Restore_Focus"]') 79 | Global $sTextId_Tray_Opt_Alt_Esc_Focus_Change_Desc = LoadTextFromLanguageJsonObj($hJobj, '["TextId_Tray_Opt_Alt_Esc_Focus_Change_Desc"]') 80 | Global $sTextId_Tray_Edit_Hotkeys = LoadTextFromLanguageJsonObj($hJobj, '["TextId_Tray_Edit_Hotkeys"]') 81 | Global $sTextId_Tray_Quick_Help = LoadTextFromLanguageJsonObj($hJobj, '["TextId_Tray_Quick_Help"]') 82 | Global $sTextId_Tray_Exit = LoadTextFromLanguageJsonObj($hJobj, '["TextId_Tray_Exit"]') 83 | Global $sTextId_GUI_Edit_Hotkeys = LoadTextFromLanguageJsonObj($hJobj, '["TextId_GUI_Edit_Hotkeys"]') 84 | Global $sTextId_GUI_OK = LoadTextFromLanguageJsonObj($hJobj, '["TextId_GUI_OK"]') 85 | Global $sTextId_GUI_Default = LoadTextFromLanguageJsonObj($hJobj, '["TextId_GUI_Default"]') 86 | Global $sTextId_GUI_Hide_Active_Window = LoadTextFromLanguageJsonObj($hJobj, '["TextId_GUI_Hide_Active_Window"]') 87 | Global $sTextId_GUI_Restore_Last_Window = LoadTextFromLanguageJsonObj($hJobj, '["TextId_GUI_Restore_Last_Window"]') 88 | Global $sTextId_GUI_Restore_All_Windows = LoadTextFromLanguageJsonObj($hJobj, '["TextId_GUI_Restore_All_Windows"]') 89 | Global $sTextId_GUI_Warning_Key_Overlap = LoadTextFromLanguageJsonObj($hJobj, '["TextId_GUI_Warning_Key_Overlap"]') 90 | Global $sTextId_GUI_Warning_Key_Empty = LoadTextFromLanguageJsonObj($hJobj, '["TextId_GUI_Warning_Key_Empty"]') 91 | Global $sTextId_GUI_Language = LoadTextFromLanguageJsonObj($hJobj, '["TextId_GUI_Language"]') 92 | Global $sTextId_Msg_Help_1_Press = LoadTextFromLanguageJsonObj($hJobj, '["TextId_Msg_Help_1_Press"]') 93 | Global $sTextId_Msg_Help_2_To_Hide_Active = LoadTextFromLanguageJsonObj($hJobj, '["TextId_Msg_Help_2_To_Hide_Active"]') 94 | Global $sTextId_Msg_Help_3_To_Restore = LoadTextFromLanguageJsonObj($hJobj, '["TextId_Msg_Help_3_To_Restore"]') 95 | Global $sTextId_Msg_Help_4_Stored_In_Tray = LoadTextFromLanguageJsonObj($hJobj, '["TextId_Msg_Help_4_Stored_In_Tray"]') 96 | Global $sTextId_Msg_Help_5_Elevated_Window_Admin = LoadTextFromLanguageJsonObj($hJobj, '["TextId_Msg_Help_5_Elevated_Window_Admin"]') 97 | EndFunc ;==>InitializeLanguage 98 | 99 | 100 | Func InitializeTray() 101 | Global $hTrayRestoreAllWnd 102 | Global $hTrayLine1 103 | Global $hTrayEditHotkeys 104 | Global $hTrayOpt 105 | Global $hTrayHelp 106 | Global $hTrayExit 107 | TrayItemDelete($hTrayRestoreAllWnd) 108 | TrayItemDelete($hTrayLine1) 109 | TrayItemDelete($hTrayEditHotkeys) 110 | TrayItemDelete($hTrayOpt) 111 | TrayItemDelete($hTrayHelp) 112 | TrayItemDelete($hTrayExit) 113 | ; == Tray Creation Section == 114 | $hTrayRestoreAllWnd = TrayCreateItem($sTextId_Tray_Restore_All_Windows & " (" & _GuiCtrlHotkey_NameFromAutoItHK($sHK_RestoreAllWnd) & ")") 115 | $hTrayLine1 = TrayCreateItem("") ; Create a straight line 116 | 117 | $hTrayOpt = TrayCreateMenu($sTextId_Tray_Extra) 118 | Global $hTrayAltF4EndProcess = TrayCreateItem($sTextId_Tray_Opt_AltF4_Force_Exit_Desc, $hTrayOpt) 119 | TrayItemSetState($hTrayAltF4EndProcess, $bAltF4EndProcess) 120 | Global $hTrayRestoreOnExit = TrayCreateItem($sTextId_Tray_Opt_Restore_On_Exit_Desc, $hTrayOpt) 121 | TrayItemSetState($hTrayRestoreOnExit, $bRestoreOnExit) 122 | Global $hTrayRestoreFocus = TrayCreateItem($sTextId_Tray_Opt_Restore_Focus, $hTrayOpt) 123 | TrayItemSetState($hTrayRestoreFocus, $bRestoreFocus) 124 | Global $hTrayAltEscFocusChange = TrayCreateItem($sTextId_Tray_Opt_Alt_Esc_Focus_Change_Desc, $hTrayOpt) 125 | TrayItemSetState($hTrayAltEscFocusChange, $bAltEscFocusChange) ; Set initial check state based on config 126 | 127 | Global $hTrayEditHotkeys = TrayCreateItem($sTextId_Tray_Edit_Hotkeys) 128 | Global $hTrayHelp = TrayCreateItem($sTextId_Tray_Quick_Help) 129 | Global $hTrayExit = TrayCreateItem($sTextId_Tray_Exit) 130 | EndFunc ;==>InitializeTray 131 | 132 | 133 | Func InitializeGUIs() 134 | ; == GUI Creation Section == 135 | Global $hGUIConfigs 136 | GUIDelete($hGUIConfigs) 137 | $hGUIConfigs = GUICreate($sTextId_GUI_Edit_Hotkeys, 300, 300) 138 | Global $hGUIConfigs_Btn_OK = GUICtrlCreateButton($sTextId_GUI_OK, 20, 260, 100, 25) 139 | Global $hGUIConfigs_Btn_Default = GUICtrlCreateButton($sTextId_GUI_Default, 160, 260, 100, 25) 140 | GUICtrlCreateLabel($sTextId_GUI_Hide_Active_Window, 10, 10) 141 | Global $hGUIConfigs_HK_HideWnd = _GUICtrlHotkey_Create($hGUIConfigs, 8, 30) 142 | _GUICtrlHotkey_SetRules($hGUIConfigs_HK_HideWnd, $HKCOMB_NONE, $HOTKEYF_ALT) 143 | _GUICtrlHotkey_SetHotkey($hGUIConfigs_HK_HideWnd, $sHK_HideWnd) 144 | 145 | GUICtrlCreateLabel($sTextId_GUI_Restore_Last_Window, 10, 60) 146 | Global $hGUIConfigs_HK_RestoreLastWnd = _GUICtrlHotkey_Create($hGUIConfigs, 8, 80) 147 | _GUICtrlHotkey_SetRules($hGUIConfigs_HK_RestoreLastWnd, $HKCOMB_NONE, $HOTKEYF_ALT) 148 | _GUICtrlHotkey_SetHotkey($hGUIConfigs_HK_RestoreLastWnd, $sHK_RestoreLastWnd) 149 | 150 | GUICtrlCreateLabel($sTextId_GUI_Restore_All_Windows, 10, 110) 151 | Global $hGUIConfigs_HK_RestoreAllWnd = _GUICtrlHotkey_Create($hGUIConfigs, 8, 130) 152 | _GUICtrlHotkey_SetRules($hGUIConfigs_HK_RestoreAllWnd, $HKCOMB_NONE, $HOTKEYF_ALT) 153 | _GUICtrlHotkey_SetHotkey($hGUIConfigs_HK_RestoreAllWnd, $sHK_RestoreAllWnd) 154 | 155 | GUICtrlCreateLabel($sTextId_GUI_Warning_Key_Overlap, 10, 165, 280, 50) 156 | 157 | Local $sLangDir = @ScriptDir & "\language_gen" ; language_gen is in the same dir as the script/exe 158 | Local $aLangFiles = _FileListToArray($sLangDir, "*.json", $FLTA_FILES) 159 | Local $sLangListString = "" 160 | Local $sCurrentLangValid = False 161 | 162 | If IsArray($aLangFiles) Then 163 | For $i = 1 To $aLangFiles[0] ; Start from index 1, index 0 holds the count 164 | Local $sLangCode = StringTrimRight($aLangFiles[$i], 5) ; Remove ".json" extension 165 | If $sLangListString = "" Then 166 | $sLangListString = $sLangCode 167 | Else 168 | $sLangListString &= "|" & $sLangCode 169 | EndIf 170 | ; Check if the language read from INI is among the found files 171 | If StringLower($sLangCode) = StringLower($sLanguage) Then 172 | $sCurrentLangValid = True 173 | EndIf 174 | Next 175 | EndIf 176 | 177 | ; Fallback if no language files are found or the current language is invalid 178 | If $sLangListString = "" Then 179 | $sLangListString = "en" ; Default to English if no files found 180 | If StringLower($sLanguage) <> "en" Then $sLanguage = "en" ; Force current lang to en if it wasn't 181 | $sCurrentLangValid = True ; 'en' is now considered valid 182 | ElseIf Not $sCurrentLangValid Then 183 | ; If the language from INI wasn't found, default to the first one in the list (or 'en' if available) 184 | Local $aTempLangList = StringSplit($sLangListString, "|") 185 | If _ArraySearch($aTempLangList, "en", 0, 0, 0, 1) > 0 Then ; Check if 'en' exists (case-insensitive) 186 | $sLanguage = "en" 187 | Else 188 | $sLanguage = $aTempLangList[1] ; Default to the first language found 189 | EndIf 190 | ConsoleWrite("!> Warning: Configured language '" & $sLanguage & "' not found. Defaulting to '" & $sLanguage & "'" & @CRLF) 191 | EndIf 192 | 193 | 194 | GUICtrlCreateLabel($sTextId_GUI_Language, 10, 220, 100) 195 | Global $hGUIConfigs_Language = GUICtrlCreateCombo("", 110, 219, 100, 24) ; Create empty first 196 | GUICtrlSetData($hGUIConfigs_Language, $sLangListString, $sLanguage) 197 | EndFunc ;==>InitializeGUIs 198 | 199 | 200 | Func HandleTrayEvents() 201 | $hTrayMsg = TrayGetMsg() 202 | Switch $hTrayMsg 203 | Case $hTrayAltF4EndProcess 204 | ToggleOpt($bAltF4EndProcess, $hTrayAltF4EndProcess) 205 | IniWrite($CONFIG_INI, "Extra", "ALT_F4_FORCE_END_PROCESS", BoolToText($bAltF4EndProcess)) 206 | Case $hTrayRestoreOnExit 207 | ToggleOpt($bRestoreOnExit, $hTrayRestoreOnExit) 208 | IniWrite($CONFIG_INI, "Extra", "RESTORE_ALL_WINDOWS_ON_EXIT", BoolToText($bRestoreOnExit)) 209 | Case $hTrayRestoreFocus 210 | ToggleOpt($bRestoreFocus, $hTrayRestoreFocus) 211 | IniWrite($CONFIG_INI, "Extra", "RESTORE_FOCUS", BoolToText($bRestoreFocus)) 212 | Case $hTrayAltEscFocusChange 213 | ToggleOpt($bAltEscFocusChange, $hTrayAltEscFocusChange) 214 | IniWrite($CONFIG_INI, "Extra", "ALT_ESC_FOCUS_CHANGE", BoolToText($bAltEscFocusChange)) 215 | Case $hTrayRestoreAllWnd 216 | RestoreAllWnd() 217 | Case $hTrayExit 218 | ExitS() 219 | Case $hTrayHelp 220 | Help() 221 | Case $hTrayEditHotkeys 222 | EditHotkeys() 223 | EndSwitch 224 | 225 | ; Only attempt to lock the mutex if there's a tray message to process 226 | If $hTrayMsg = 0 Then Return 227 | 228 | If _WinAPI_WaitForSingleObject($hMutex, 100) <> 0 Then 229 | Return ; Couldn't acquire mutex, skip this cycle 230 | EndIf 231 | 232 | ; Check if a specific window's tray item was clicked 233 | For $i = 0 To $nWindowStackSize - 1 234 | ; Check if the array element is valid before accessing it 235 | If IsHWnd($aWindowStack[$i][0]) And $aWindowStack[$i][1] <> 0 Then 236 | If $hTrayMsg = $aWindowStack[$i][1] Then 237 | RestoreWnd($aWindowStack[$i][0]) 238 | ExitLoop 239 | EndIf 240 | EndIf 241 | Next 242 | 243 | ; Release mutex 244 | _WinAPI_ReleaseMutex($hMutex) 245 | EndFunc ;==>HandleTrayEvents 246 | 247 | 248 | Func EditHotkeys() 249 | GUISetState(@SW_SHOW, $hGUIConfigs) 250 | ; Temporarily disable current hotkeys 251 | HotKeySet($sHK_HideWnd) 252 | HotKeySet($sHK_RestoreLastWnd) 253 | HotKeySet($sHK_RestoreAllWnd) 254 | While 1 255 | $msg = GUIGetMsg() 256 | Switch $msg 257 | Case $GUI_EVENT_CLOSE 258 | ExitLoop 259 | Case $hGUIConfigs_Btn_OK 260 | ; Read GUI and save to config file 261 | $sHK_HideWnd = _GUICtrlHotkey_GetHotkey($hGUIConfigs_HK_HideWnd) 262 | $sHK_RestoreLastWnd = _GUICtrlHotkey_GetHotkey($hGUIConfigs_HK_RestoreLastWnd) 263 | $sHK_RestoreAllWnd = _GUICtrlHotkey_GetHotkey($hGUIConfigs_HK_RestoreAllWnd) 264 | 265 | ; Validate new hotkeys 266 | If $sHK_HideWnd = "" Then 267 | MsgBox(16, "", $sTextId_GUI_Warning_Key_Empty) 268 | ContinueLoop 269 | EndIf 270 | 271 | ; Save new hotkeys to config ini file 272 | IniWrite($CONFIG_INI, "Hotkeys", "HIDE_WINDOW", $sHK_HideWnd) 273 | IniWrite($CONFIG_INI, "Hotkeys", "RESTORE_LAST_WINDOW", $sHK_RestoreLastWnd) 274 | IniWrite($CONFIG_INI, "Hotkeys", "RESTORE_ALL_WINDOWS", $sHK_RestoreAllWnd) 275 | 276 | $sLanguage = GUICtrlRead($hGUIConfigs_Language) 277 | IniWrite($CONFIG_INI, "Extra", "LANGUAGE", $sLanguage) 278 | 279 | ; Update Tray Text for Restore All Windows 280 | TrayItemSetText($hTrayRestoreAllWnd, $sTextId_GUI_Restore_All_Windows & " (" & _GuiCtrlHotkey_NameFromAutoItHK($sHK_RestoreAllWnd) & ")") 281 | 282 | ; Reinitialize UI Language 283 | InitializeLanguage() 284 | InitializeTray() 285 | InitializeGUIs() 286 | 287 | ExitLoop 288 | Case $hGUIConfigs_Btn_Default 289 | _GUICtrlHotkey_SetHotkey($hGUIConfigs_HK_HideWnd, $DEFAULT_HIDE_WND_HK) 290 | _GUICtrlHotkey_SetHotkey($hGUIConfigs_HK_RestoreLastWnd, $DEFAULT_RESTORE_LAST_WND_HK) 291 | _GUICtrlHotkey_SetHotkey($hGUIConfigs_HK_RestoreAllWnd, $DEFAULT_RESTORE_ALL_WND_HK) 292 | EndSwitch 293 | WEnd 294 | 295 | ; Reenable hotkeys 296 | HotKeySet($sHK_HideWnd, "HideCurrentWnd") 297 | HotKeySet($sHK_RestoreLastWnd, "RestoreLastWnd") 298 | HotKeySet($sHK_RestoreAllWnd, "RestoreAllWnd") 299 | GUISetState(@SW_HIDE, $hGUIConfigs) 300 | EndFunc ;==>EditHotkeys 301 | 302 | 303 | Func ToggleOpt(ByRef $bFlag, ByRef $hTrayItem) 304 | $bFlag = Not $bFlag 305 | 306 | Local $nTrayItemState = TrayItemGetState($hTrayItem) 307 | If BitAND($nTrayItemState, 1) Then ; CHECKED 308 | TrayItemSetState($hTrayItem, 4) ; Set to UNCHECKED 309 | ElseIf BitAND($nTrayItemState, 4) Then ; UNCHECKED 310 | TrayItemSetState($hTrayItem, 1) ; Set to CHECKED 311 | Else ; Default / Initial state might not be CHECKED or UNCHECKED explicitly 312 | If $bFlag Then 313 | TrayItemSetState($hTrayItem, 1) ; Set to CHECKED 314 | Else 315 | TrayItemSetState($hTrayItem, 4) ; Set to UNCHECKED 316 | EndIf 317 | EndIf 318 | 319 | EndFunc ;==>ToggleOpt 320 | 321 | 322 | Func RestoreLastWnd() 323 | ; Restore window from top of stack 324 | If $nWindowStackSize > 0 Then 325 | Local $nLastIndex = $nWindowStackSize - 1 326 | RestoreWnd($aWindowStack[$nLastIndex][0]) 327 | EndIf 328 | EndFunc ;==>RestoreLastWnd 329 | 330 | 331 | Func RestoreWnd($hfWnd) 332 | ; Try to acquire mutex with timeout to prevent deadlocks 333 | If _WinAPI_WaitForSingleObject($hMutex, 1000) <> 0 Then 334 | ConsoleWrite("!> Warning: Could not acquire mutex to restore window." & @CRLF) 335 | Return 336 | EndIf 337 | 338 | Local $nIndex = -1 339 | Local $hTrayItemToDelete = 0 340 | 341 | ; Find the window in our stack and get its tray item handle 342 | For $i = 0 To $nWindowStackSize - 1 343 | If $aWindowStack[$i][0] = $hfWnd Then 344 | $nIndex = $i 345 | $hTrayItemToDelete = $aWindowStack[$i][1] 346 | ExitLoop 347 | EndIf 348 | Next 349 | 350 | ; Check if the window handle is still valid BEFORE trying to show/activate 351 | If WindowExists($hfWnd) Then 352 | WinSetState($hfWnd, "", @SW_SHOW) 353 | If $bRestoreFocus = True Then 354 | WinActivate($hfWnd) 355 | EndIf 356 | Else 357 | ConsoleWrite("!> Info: Window handle " & $hfWnd & " is no longer valid. Cleaning up tray item." & @CRLF) 358 | EndIf 359 | 360 | ; Remove from our stack and delete tray item IF found 361 | If $nIndex >= 0 Then 362 | TrayItemDelete($hTrayItemToDelete) ; Use the stored handle 363 | 364 | If $nIndex < $nWindowStackSize - 1 Then 365 | ; Move the last element to fill the gap 366 | $aWindowStack[$nIndex][0] = $aWindowStack[$nWindowStackSize - 1][0] 367 | $aWindowStack[$nIndex][1] = $aWindowStack[$nWindowStackSize - 1][1] 368 | $aWindowStack[$nIndex][2] = $aWindowStack[$nWindowStackSize - 1][2] 369 | EndIf 370 | 371 | $nWindowStackSize -= 1 372 | EndIf 373 | 374 | ; Release mutex 375 | _WinAPI_ReleaseMutex($hMutex) 376 | EndFunc ;==>RestoreWnd 377 | 378 | 379 | Func HideCurrentWnd() 380 | Local $hCurrentWndToHide = WinGetHandle("[ACTIVE]") 381 | 382 | ; If there's no active window or we got the desktop/shell, don't proceed. 383 | If $hCurrentWndToHide = 0 Then Return 384 | If _WinAPI_GetClassName($hCurrentWndToHide) = "Progman" Then Return 385 | 386 | If IsWindowInStack($hCurrentWndToHide) Then 387 | ; Window is already hidden, no need to hide it again 388 | Return 389 | EndIf 390 | 391 | If $bAltEscFocusChange Then 392 | ; Send Alt+Esc. This typically shifts focus to the window that would become active if the current one was minimized. 393 | Send("!{ESC}") 394 | 395 | ; Give Windows a brief moment to process the Alt+Esc and change focus. 396 | ; Adjust this value if needed (50-150ms is usually sufficient). 397 | Sleep(100) 398 | EndIf 399 | 400 | ; Now, hide the window we originally targeted (which may or may not still be active, depending on the toggle setting). 401 | HideWnd($hCurrentWndToHide) 402 | 403 | EndFunc ;==>HideCurrentWnd 404 | 405 | 406 | ; Function to check if a window is in the stack 407 | Func IsWindowInStack($hWnd) 408 | For $i = 0 To $nWindowStackSize - 1 409 | If $aWindowStack[$i][0] = $hWnd Then 410 | Return True 411 | EndIf 412 | Next 413 | Return False 414 | EndFunc ;==>IsWindowInStack 415 | 416 | 417 | Func RestoreAllWnd() 418 | ; Try to acquire mutex 419 | If _WinAPI_WaitForSingleObject($hMutex, 1000) <> 0 Then 420 | ConsoleWrite("!> Warning: Could not acquire mutex to restore all windows." & @CRLF) 421 | Return 422 | EndIf 423 | 424 | If $nWindowStackSize > 0 Then 425 | Local $hLastValidWindow = 0 426 | 427 | For $i = 0 To $nWindowStackSize - 1 428 | Local $hWnd = $aWindowStack[$i][0] 429 | Local $hTrayItem = $aWindowStack[$i][1] 430 | 431 | ; Check if the window handle is still valid BEFORE trying to show/activate 432 | If WindowExists($hWnd) Then 433 | WinSetState($hWnd, "", @SW_SHOW) 434 | $hLastValidWindow = $hWnd ; Keep track of the last valid window shown 435 | Else 436 | ConsoleWrite("!> Info: Window handle " & $hWnd & " is no longer valid during RestoreAll. Cleaning up tray item." & @CRLF) 437 | EndIf 438 | 439 | ; Always delete the tray item 440 | TrayItemDelete($hTrayItem) 441 | Next 442 | 443 | ; Bring focus to the last valid window that was restored, if requested 444 | If $bRestoreFocus = True And IsHWnd($hLastValidWindow) Then 445 | WinActivate($hLastValidWindow) 446 | EndIf 447 | 448 | ; Reset the window stack completely 449 | $nWindowStackSize = 0 450 | EndIf 451 | 452 | ; Release mutex 453 | _WinAPI_ReleaseMutex($hMutex) 454 | EndFunc ;==>RestoreAllWnd 455 | 456 | 457 | Func CloseWnd() 458 | ; Add error handling for process closing 459 | Local $hWnd = WinGetHandle("[ACTIVE]") 460 | If $hWnd = 0 Then 461 | ConsoleWrite("!> Error: No active window to close." & @CRLF) 462 | Return 463 | EndIf 464 | 465 | Local $iPID = WinGetProcess($hWnd) 466 | If $iPID <= 0 Then ; Check if PID is valid (greater than 0) 467 | ConsoleWrite("!> Error: Couldn't get process ID for window handle " & $hWnd & "." & @CRLF) 468 | Return 469 | EndIf 470 | 471 | ProcessClose($iPID) 472 | If @error Then 473 | ConsoleWrite("!> Warning: Failed to close process with PID " & $iPID & ". It might require elevated privileges or is unresponsive." & @CRLF) 474 | EndIf 475 | EndFunc ;==>CloseWnd 476 | 477 | 478 | Func HandleAltF4() 479 | If $bAltF4EndProcess = True Then 480 | CloseWnd() 481 | Else 482 | ; Temporarily disable the Alt+F4 hotkey to pass it through 483 | HotKeySet("!{f4}") 484 | Send("!{f4}") 485 | 486 | ; Add a small delay before re-enabling the hotkey 487 | ; This helps prevent hotkey registration issues 488 | Sleep(50) 489 | HotKeySet("!{f4}", "HandleAltF4") 490 | EndIf 491 | EndFunc ;==>HandleAltF4 492 | 493 | 494 | Func LoadTextFromLanguageJsonObj(ByRef $hJobj, $sKey) 495 | If Not IsObj($hJobj) Then 496 | ConsoleWrite("!> Error: Invalid JSON object in LoadTextFromLanguageJsonObj" & @CRLF) 497 | Return "Error: Invalid language configuration" 498 | EndIf 499 | 500 | $sValue = Json_Get($hJobj, $sKey) 501 | If $sValue Then 502 | Return $sValue 503 | Else 504 | ConsoleWrite("!> Warning: Language key not found: " & $sKey & @CRLF) 505 | Return "LangKeyNotFound: " & $sKey 506 | EndIf 507 | EndFunc ;==>LoadTextFromLanguageJsonObj 508 | 509 | 510 | Func Help() 511 | MsgBox(64, "MinimizeToTray", $sTextId_Msg_Help_1_Press & " [" & _GuiCtrlHotkey_NameFromAutoItHK($sHK_HideWnd) & "] " & $sTextId_Msg_Help_2_To_Hide_Active & @CRLF _ 512 | & $sTextId_Msg_Help_1_Press & " [" & _GuiCtrlHotkey_NameFromAutoItHK($sHK_RestoreLastWnd) & "] " & $sTextId_Msg_Help_3_To_Restore & @CRLF _ 513 | & $sTextId_Msg_Help_4_Stored_In_Tray & @CRLF _ 514 | & $sTextId_Msg_Help_5_Elevated_Window_Admin & @CRLF & @CRLF _ 515 | & "https://github.com/sandwichdoge/MinimizeToTray") 516 | EndFunc ;==>Help 517 | 518 | 519 | Func ExitS() 520 | If $bRestoreOnExit Then 521 | RestoreAllWnd() 522 | EndIf 523 | 524 | ; Clean up mutex properly 525 | If $hMutex Then 526 | _WinAPI_CloseHandle($hMutex) 527 | EndIf 528 | 529 | Exit 530 | EndFunc ;==>ExitS 531 | 532 | 533 | Func TextToBool($txt) 534 | If StringLower($txt) = "true" Then 535 | Return True 536 | Else 537 | Return False 538 | EndIf 539 | EndFunc ;==>TextToBool 540 | 541 | 542 | Func BoolToText($bool) 543 | If $bool Then 544 | Return "True" 545 | Else 546 | Return "False" 547 | EndIf 548 | EndFunc ;==>BoolToText 549 | 550 | 551 | Func LimitWindowTitle($sTitle, $iMaxLength = 50) 552 | If StringLen($sTitle) > $iMaxLength Then 553 | Return StringLeft($sTitle, $iMaxLength - 3) & "..." 554 | Else 555 | Return $sTitle 556 | EndIf 557 | EndFunc ;==>LimitWindowTitle 558 | 559 | 560 | Func WindowExists($hWnd) 561 | Return WinExists($hWnd) <> 0 562 | EndFunc ;==>WindowExists 563 | 564 | 565 | Func HideWnd($hfWnd) 566 | ; Try to acquire mutex with timeout 567 | If _WinAPI_WaitForSingleObject($hMutex, 1000) <> 0 Then 568 | ConsoleWrite("!> Warning: Could not acquire mutex to hide window." & @CRLF) 569 | Return 570 | EndIf 571 | 572 | ; Get window title for tray menu 573 | Local $sTitle = WinGetTitle($hfWnd) 574 | If @error Then $sTitle = "[Error Getting Title]" 575 | If $sTitle = "" Then $sTitle = "[No Title]" 576 | 577 | ; Limit the title length for better tray display 578 | $sTitle = LimitWindowTitle($sTitle, 50) 579 | 580 | ; Hide the window 581 | WinSetState($hfWnd, "", @SW_HIDE) 582 | If @error Then ; Check if hiding failed (e.g., window closed between check and hide) 583 | ConsoleWrite("!> Warning: Failed to hide window handle " & $hfWnd & ". It might have closed." & @CRLF) 584 | _WinAPI_ReleaseMutex($hMutex) 585 | Return 586 | EndIf 587 | 588 | Local $hTrayWnd = TrayCreateItem($sTitle, -1, 0) 589 | 590 | ; Check if we need to resize the array 591 | If $nWindowStackSize >= UBound($aWindowStack) Then 592 | ; Resize the array in larger chunks (double the size) to reduce resize operations 593 | Local $iNewSize = UBound($aWindowStack) * 2 594 | ConsoleWrite("*> Info: Resizing window stack array to " & $iNewSize & @CRLF) 595 | ReDim $aWindowStack[$iNewSize][3] 596 | If @error Then 597 | ConsoleWrite("!> Error: Failed to resize window stack array." & @CRLF) 598 | TrayItemDelete($hTrayWnd) ; Clean up the tray item we just created 599 | _WinAPI_ReleaseMutex($hMutex) 600 | Return ; Cannot add window if resize failed 601 | EndIf 602 | EndIf 603 | 604 | ; Add to our window stack 605 | $aWindowStack[$nWindowStackSize][0] = $hfWnd ; Window handle 606 | $aWindowStack[$nWindowStackSize][1] = $hTrayWnd ; Tray item handle 607 | $aWindowStack[$nWindowStackSize][2] = $sTitle ; Window title 608 | $nWindowStackSize += 1 609 | 610 | ; Release mutex 611 | _WinAPI_ReleaseMutex($hMutex) 612 | EndFunc ;==>HideWnd 613 | 614 | 615 | Func Main() 616 | InitializeConfigs() 617 | InitializeLanguage() 618 | InitializeTray() 619 | InitializeGUIs() 620 | 621 | ;//Exit if MTT is already running. 622 | If _Singleton("MTT", 1) = 0 Then 623 | TrayTip("MinimizeToTray", $sTextId_Already_Running, 2) 624 | Sleep(2000) 625 | Exit 626 | EndIf 627 | 628 | TrayTip("MinimizeToTray", $sTextId_Msg_Help_1_Press & " [" & _GuiCtrlHotkey_NameFromAutoItHK($sHK_HideWnd) & "] " & $sTextId_Msg_Help_2_To_Hide_Active & @CRLF _ 629 | & $sTextId_Msg_Help_1_Press & " [" & _GuiCtrlHotkey_NameFromAutoItHK($sHK_RestoreLastWnd) & "] " & $sTextId_Msg_Help_3_To_Restore & @CRLF _ 630 | & $sTextId_Msg_Help_4_Stored_In_Tray, 5) 631 | 632 | While 1 633 | HandleTrayEvents() 634 | WEnd 635 | EndFunc ;==>Main 636 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # MinimizeToTray 2 | 3 | MinimizeToTray is a simple application for Windows. It helps reduce taskbar clutter by allowing you to minimize any open window directly to the system tray. Minimized windows can be easily restored whenever needed. 4 | 5 | No installation required. 6 | 7 | ![image](https://github.com/user-attachments/assets/c2a1ae90-6998-461b-bd60-b6085a318c7d) 8 | 9 | 10 | **Basic Usage:** 11 | 12 | 1. Launch the MinimizeToTray application. 13 | 2. To minimize the active window to the system tray, press **Alt+F1** (configurable). 14 | 3. To restore the last window you minimized, press **Alt+F2** (configurable). 15 | 4. Alternatively, right-click the MinimizeToTray icon in the system tray to see a list of all minimized applications. Click any application in the list to restore its window. 16 | 17 | Some processes may need MinimizeToTray to be run with Admin privileges to be hidden. 18 | 19 | **How to build and run from source:** 20 | 1. Install AutoIt3. 21 | 2. Use Aut2exe on MinimizeToTray.au3 to build an executable file. 22 | 3. Or simply run the script with AutoIt3.exe. 23 | 24 | https://www.softpedia.com/get/PORTABLE-SOFTWARE/System/System-Enhancements/Minimize-ToTray.shtml 25 | 26 | Download: https://github.com/sandwichdoge/MinimizeToTray/releases/ 27 | -------------------------------------------------------------------------------- /cmdline.au3: -------------------------------------------------------------------------------- 1 | #include-once 2 | #include 3 | #include "MinimizeToTray.au3" 4 | 5 | Func CmdlineHasParams() 6 | Return UBound($CmdLine) > 1 7 | EndFunc 8 | 9 | Func _GetTitleFromProcName($sProcessName) 10 | $aAllProcesses = ProcessList() 11 | 12 | Dim $aDetectedProcesses[0] 13 | For $i = 0 To UBound($aAllProcesses) - 1 14 | If $aAllProcesses[$i][0] == $sProcessName Then 15 | _ArrayAdd($aDetectedProcesses, $aAllProcesses[$i][1]) 16 | EndIf 17 | Next 18 | 19 | $aAllWnds = WinList() 20 | 21 | Local $aDetectedWndTitles[0] 22 | For $i = 0 To UBound($aAllWnds) - 1 23 | $sWndTitle = $aAllWnds[$i][0] 24 | If $sWndTitle == "" Then 25 | ContinueLoop 26 | EndIf 27 | $sPID = WinGetProcess($sWndTitle) ; Got PID 28 | For $j = 0 To UBound($aDetectedProcesses) - 1 29 | If $sPID == $aDetectedProcesses[$j] Then 30 | _ArrayAdd($aDetectedWndTitles, $sWndTitle) 31 | EndIf 32 | Next 33 | Next 34 | 35 | Return $aDetectedWndTitles 36 | EndFunc 37 | 38 | Func CmdlineValidateParams() 39 | ; Can't hide and show at the same time 40 | If _CmdLine_FlagExists('H') And _CmdLine_FlagExists('S') Then 41 | MsgBox(0, "MTT", "Error. Can't hide and show window at the same time.", 10) 42 | Return False 43 | EndIf 44 | 45 | ; No -p or invalid arg value for -p 46 | If Not _CmdLine_KeyExists('p') And Not _CmdLine_KeyEXists('t') Then 47 | MsgBox(0, "MTT", "Error. Need to specify a process name to hide with -p or a window title with -t.", 10) 48 | Return False 49 | EndIf 50 | 51 | If _CmdLine_KeyExists('p') and _CmdLine_Get('p') == '' Then 52 | Return False 53 | EndIf 54 | 55 | If _CmdLine_KeyExists('t') and _CmdLine_Get('t') == '' Then 56 | Return False 57 | EndIf 58 | 59 | Return True 60 | EndFunc 61 | 62 | Func CmdlineShowHelp() 63 | MsgBox(64, "MTT", "Cmdline options: " & @CRLF _ 64 | & "We may hide/show windows based on either their title or process name:" & @CRLF _ 65 | & "-p " & @CRLF _ 66 | & "-t " & @CRLF _ 67 | & "-H: To hide all visible window created by a process." & @CRLF _ 68 | & "-S: To show/restore previously hidden window." & @CRLF & @CRLF _ 69 | & "Example for hiding all open firefox windows:" & @CRLF _ 70 | & "Minimize.exe -p firefox.exe -H") 71 | EndFunc 72 | 73 | Func _GetAllPossibleWnds($sWndTitle) 74 | Local $aRet[0] 75 | $aAllWnds = WinList() 76 | For $i = 0 To UBound($aAllWnds) - 1 77 | If StringInStr($aAllWnds[$i][0], $sWndTitle) Then 78 | _ArrayAdd($aRet, $aAllWnds[$i][0]) 79 | EndIf 80 | Next 81 | 82 | Return $aRet 83 | EndFunc 84 | 85 | Func CmdlineRunCliMode() 86 | If Not CmdlineHasParams() Then 87 | Return 88 | EndIf 89 | 90 | If _CmdLine_FlagExists('h') Then 91 | CmdlineShowHelp() 92 | Return 93 | EndIf 94 | 95 | If Not CmdlineValidateParams() Then 96 | Return 97 | EndIf 98 | 99 | If _CmdLine_KeyExists('p') Then 100 | $sProcessNameToHide = _CmdLine_Get('p') 101 | $aDetectedWndTitles = _GetTitleFromProcName($sProcessNameToHide) 102 | ElseIf _CmdLine_KeyExists('t') Then 103 | $sWndTitle = _CmdLine_Get('t') 104 | $aDetectedWndTitles = _GetAllPossibleWnds($sWndTitle) 105 | EndIf 106 | For $i = 0 To UBound($aDetectedWndTitles) - 1 107 | $sWndTitle = $aDetectedWndTitles[$i] 108 | If _CmdLine_FlagExists('H') Then 109 | WinSetState($sWndTitle, '', @SW_HIDE) 110 | ElseIf _CmdLine_FlagExists('S') Then 111 | WinSetState($sWndTitle, '', @SW_SHOW) 112 | EndIf 113 | Next 114 | EndFunc 115 | 116 | 117 | ;CmdLine UDF 118 | ;https://www.autoitscript.com/forum/topic/169610-cmdline-udf-get-valueexistenceflag/ 119 | Func _CmdLine_Get($sKey, $mDefault = Null) 120 | For $i = 1 To $CmdLine[0] 121 | If $CmdLine[$i] = "/" & $sKey OR $CmdLine[$i] = "-" & $sKey OR $CmdLine[$i] = "--" & $sKey Then 122 | If $CmdLine[0] >= $i+1 Then 123 | Return $CmdLine[$i+1] 124 | EndIf 125 | EndIf 126 | Next 127 | Return $mDefault 128 | EndFunc 129 | 130 | Func _CmdLine_KeyExists($sKey) 131 | For $i = 1 To $CmdLine[0] 132 | If $CmdLine[$i] = "/" & $sKey OR $CmdLine[$i] = "-" & $sKey OR $CmdLine[$i] = "--" & $sKey Then 133 | Return True 134 | EndIf 135 | Next 136 | Return False 137 | EndFunc 138 | 139 | Func _CmdLine_ValueExists($sValue) 140 | For $i = 1 To $CmdLine[0] 141 | If $CmdLine[$i] = $sValue Then 142 | Return True 143 | EndIf 144 | Next 145 | Return False 146 | EndFunc 147 | 148 | Func _CmdLine_FlagEnabled($sKey) 149 | For $i = 1 To $CmdLine[0] 150 | If StringRegExp($CmdLine[$i], "\+([a-zA-Z]*)" & $sKey & "([a-zA-Z]*)") Then 151 | Return True 152 | EndIf 153 | Next 154 | Return False 155 | EndFunc 156 | 157 | Func _CmdLine_FlagDisabled($sKey) 158 | For $i = 1 To $CmdLine[0] 159 | If StringRegExp($CmdLine[$i], "\-([a-zA-Z]*)" & $sKey & "([a-zA-Z]*)") Then 160 | Return True 161 | EndIf 162 | Next 163 | Return False 164 | EndFunc 165 | 166 | Func _CmdLine_FlagExists($sKey) 167 | For $i = 1 To $CmdLine[0] 168 | If StringRegExp($CmdLine[$i], "(\+|\-)([a-zA-Z]*)" & $sKey & "([a-zA-Z]*)") Then 169 | Return True 170 | EndIf 171 | Next 172 | Return False 173 | EndFunc 174 | 175 | Func _CmdLine_GetValByIndex($iIndex, $mDefault = Null) 176 | If $CmdLine[0] >= $iIndex Then 177 | Return $CmdLine[$iIndex] 178 | Else 179 | Return $mDefault 180 | EndIf 181 | EndFunc 182 | -------------------------------------------------------------------------------- /language_gen/HOW_TO_ADD_NEW_LANGUAGE.md: -------------------------------------------------------------------------------- 1 | - Edit Excel file language_gen.xlsx, add a column representing the new language. 2 | - Run ```python3 language_gen.py```. 3 | - Done. 4 | -------------------------------------------------------------------------------- /language_gen/de.json: -------------------------------------------------------------------------------- 1 | { 2 | "key" : "de", 3 | "TextId_Already_Running" : "Eine Instanz von MinimizeToTray läuft bereits.", 4 | "TextId_Tray_Restore_All_Windows" : "Alle Fenster wiederherstellen", 5 | "TextId_Tray_Extra" : "Extra", 6 | "TextId_Tray_Opt_AltF4_Force_Exit_Desc" : "Alt-F4 erzwingt das Beenden des Fensters", 7 | "TextId_Tray_Opt_Restore_On_Exit_Desc" : "Versteckte Fenster beim Beenden wiederherstellen", 8 | "TextId_Tray_Opt_Save_Legacy_Windows_Desc" : "Legacy-Fenster speichern", 9 | "TextId_Tray_Opt_Alt_Esc_Focus_Change_Desc": "Automatisches Alt+Esc für Fokuswechsel beim Verstecken", 10 | "TextId_Tray_Opt_Restore_Focus" : "Fokus auf wiederhergestellte Fenster zurücksetzen", 11 | "TextId_Tray_Edit_Hotkeys" : "Konfigurationen", 12 | "TextId_Tray_Quick_Help" : "Schnelle Hilfe", 13 | "TextId_Tray_Exit" : "Verlassen", 14 | "TextId_GUI_Edit_Hotkeys" : "Hotkeys bearbeiten", 15 | "TextId_GUI_OK" : "Okay", 16 | "TextId_GUI_Default" : "Voreinstellungen", 17 | "TextId_GUI_Hide_Active_Window" : "Aktives Fenster ausblenden", 18 | "TextId_GUI_Restore_Last_Window" : "Letztes Fenster wiederherstellen", 19 | "TextId_GUI_Restore_All_Windows" : "Alle ausgeblendeten Fenster wiederherstellen", 20 | "TextId_GUI_Warning_Key_Overlap" : "Die ESC-Taste und ALT+F4 können nicht ausgewählt werden, da sie die System-Hotkeys stören würden.", 21 | "TextId_GUI_Warning_Key_Empty" : "Hotkeys dürfen nicht leer sein.", 22 | "TextId_GUI_Language" : "Sprache", 23 | "TextId_Msg_Help_1_Press" : "Drücke", 24 | "TextId_Msg_Help_2_To_Hide_Active" : "um das derzeit aktive Fenster auszublenden.", 25 | "TextId_Msg_Help_3_To_Restore" : "um das letzte verborgene Fenster wiederherzustellen.", 26 | "TextId_Msg_Help_4_Stored_In_Tray" : "Versteckte Fenster werden im MTT Tray-Icon gespeichert.", 27 | "TextId_Msg_Help_5_Elevated_Window_Admin" : "Wenn das Fenster, das Sie ausblenden möchten, auf die Verwaltungsebene gehoben wird, müssen Sie MTT als Administrator ausführen." 28 | } -------------------------------------------------------------------------------- /language_gen/en.json: -------------------------------------------------------------------------------- 1 | { 2 | "key" : "en", 3 | "TextId_Already_Running" : "An instance of MinimizeToTray is already running.", 4 | "TextId_Tray_Restore_All_Windows" : "Restore all windows", 5 | "TextId_Tray_Extra" : "Extra", 6 | "TextId_Tray_Opt_AltF4_Force_Exit_Desc" : "Alt-F4 forces window's process to exit", 7 | "TextId_Tray_Opt_Restore_On_Exit_Desc" : "Restore hidden windows on exit", 8 | "TextId_Tray_Opt_Save_Legacy_Windows_Desc" : "Save legacy windows", 9 | "TextId_Tray_Opt_Alt_Esc_Focus_Change_Desc" : "Auto Alt+Esc for smooth focus on hide", 10 | "TextId_Tray_Opt_Restore_Focus" : "Return focus to restored windows", 11 | "TextId_Tray_Edit_Hotkeys" : "Configs", 12 | "TextId_Tray_Quick_Help" : "Quick Help", 13 | "TextId_Tray_Exit" : "Exit", 14 | "TextId_GUI_Edit_Hotkeys" : "Edit Hotkeys", 15 | "TextId_GUI_OK" : "OK", 16 | "TextId_GUI_Default" : "Default", 17 | "TextId_GUI_Hide_Active_Window" : "Hide active window", 18 | "TextId_GUI_Restore_Last_Window" : "Restore last window", 19 | "TextId_GUI_Restore_All_Windows" : "Restore all hidden windows", 20 | "TextId_GUI_Warning_Key_Overlap" : "ESC key and ALT-F4 cannot be selected because they will interfere with system hotkeys.", 21 | "TextId_GUI_Warning_Key_Empty" : "Hotkeys must not be empty.", 22 | "TextId_GUI_Language" : "Language", 23 | "TextId_Msg_Help_1_Press" : "Press", 24 | "TextId_Msg_Help_2_To_Hide_Active" : "to hide currently active Window.", 25 | "TextId_Msg_Help_3_To_Restore" : "to restore last hidden Window.", 26 | "TextId_Msg_Help_4_Stored_In_Tray" : "Hidden Windows are stored in MTT tray icon.", 27 | "TextId_Msg_Help_5_Elevated_Window_Admin" : "If the window you want to hide is elevated to administrative level, you must run MTT as Administrator." 28 | } -------------------------------------------------------------------------------- /language_gen/fr.json: -------------------------------------------------------------------------------- 1 | { 2 | "key": "fr", 3 | "TextId_Already_Running": "Une instance de MinimizeToTray est déjà en cours d'exécution.", 4 | "TextId_Tray_Restore_All_Windows": "Restaurer toutes les fenêtres", 5 | "TextId_Tray_Extra": "Extra", 6 | "TextId_Tray_Opt_AltF4_Force_Exit_Desc": "Alt-F4 force le processus de la fenêtre à quitter", 7 | "TextId_Tray_Opt_Restore_On_Exit_Desc": "Restaurer les fenêtres masquées en quittant", 8 | "TextId_Tray_Opt_Save_Legacy_Windows_Desc": "Enregistrer les anciennes fenêtres", 9 | "TextId_Tray_Opt_Alt_Esc_Focus_Change_Desc": "Alt+Échap auto pour un changement de focus fluide lors du masquage", 10 | "TextId_Tray_Opt_Restore_Focus": "Revenir au focus sur les fenêtres restaurées", 11 | "TextId_Tray_Edit_Hotkeys": "Configurations", 12 | "TextId_Tray_Quick_Help": "Aide rapide", 13 | "TextId_Tray_Exit": "Quitter", 14 | "TextId_GUI_Edit_Hotkeys": "Éditer les touches de raccourci", 15 | "TextId_GUI_OK": "OK", 16 | "TextId_GUI_Default": "Par défaut", 17 | "TextId_GUI_Hide_Active_Window": "Masquer la fenêtre active", 18 | "TextId_GUI_Restore_Last_Window": "Restaurer la dernière fenêtre", 19 | "TextId_GUI_Restore_All_Windows": "Restaurez toutes les fenêtres masquées", 20 | "TextId_GUI_Warning_Key_Overlap": "Les touches ESC et ALT-F4 ne peuvent pas être choisies car elles interfèrent avec les raccourcis clavier du système.", 21 | "TextId_GUI_Warning_Key_Empty": "Les touches de raccourci ne doivent pas être vides.", 22 | "TextId_GUI_Language": "Langage", 23 | "TextId_Msg_Help_1_Press": "Appuyer", 24 | "TextId_Msg_Help_2_To_Hide_Active": "pour masquer la fenêtre actuellement active.", 25 | "TextId_Msg_Help_3_To_Restore": "pour restaurer la dernière fenêtre masquée.", 26 | "TextId_Msg_Help_4_Stored_In_Tray": "Les fenêtres masquées sont stockées dans l'icône de la barre d'état MTT.", 27 | "TextId_Msg_Help_5_Elevated_Window_Admin": "Si la fenêtre que vous souhaitez masquer est élevée au niveau administratif, vous devez exécuter MTT en tant qu'administrateur." 28 | } -------------------------------------------------------------------------------- /language_gen/ja.json: -------------------------------------------------------------------------------- 1 | { 2 | "key" : "ja", 3 | "TextId_Already_Running" : "MinimizeToTray のインスタンスはすでに実行されています。", 4 | "TextId_Tray_Restore_All_Windows" : "すべてのウィンドウを復元", 5 | "TextId_Tray_Extra" : "拡張機能の設定", 6 | "TextId_Tray_Opt_AltF4_Force_Exit_Desc" : "Alt + F4 でウィンドウのプロセスを強制終了", 7 | "TextId_Tray_Opt_Restore_On_Exit_Desc" : "終了時に非表示のウィンドウを復元", 8 | "TextId_Tray_Opt_Save_Legacy_Windows_Desc" : "従来のウィンドウを保存", 9 | "TextId_Tray_Opt_Alt_Esc_Focus_Change_Desc" : "非表示時にフォーカスを変更するには、Alt + Esc キーを押す", 10 | "TextId_Tray_Opt_Restore_Focus" : "復元されたウィンドウにフォーカスを戻す", 11 | "TextId_Tray_Edit_Hotkeys" : "設定", 12 | "TextId_Tray_Quick_Help" : "クイックヘルプ", 13 | "TextId_Tray_Exit" : "終了", 14 | "TextId_GUI_Edit_Hotkeys" : "ホットキーの編集", 15 | "TextId_GUI_OK" : "OK", 16 | "TextId_GUI_Default" : "既定", 17 | "TextId_GUI_Hide_Active_Window" : "アクティブなウィンドウを非表示", 18 | "TextId_GUI_Restore_Last_Window" : "最後のウィンドウを復元", 19 | "TextId_GUI_Restore_All_Windows" : "非表示のウィンドウをすべて復元", 20 | "TextId_GUI_Warning_Key_Overlap" : "ESC キーと ALT-F4 はシステムホットキーと干渉するため選択できません。", 21 | "TextId_GUI_Warning_Key_Empty" : "ホットキーは空にできません。", 22 | "TextId_GUI_Language" : "言語", 23 | "TextId_Msg_Help_1_Press" : "押す", 24 | "TextId_Msg_Help_2_To_Hide_Active" : "現在アクティブなウィンドウを非表示する。", 25 | "TextId_Msg_Help_3_To_Restore" : "最後に非表示にしたウィンドウを復元する。", 26 | "TextId_Msg_Help_4_Stored_In_Tray" : "非表示のウィンドウは MTT トレイ アイコンに保存されます。", 27 | "TextId_Msg_Help_5_Elevated_Window_Admin" : "非表示にするウィンドウが管理者レベルに昇格されている場合は、MTT を管理者として実行する必要があります。" 28 | } 29 | -------------------------------------------------------------------------------- /language_gen/language_gen.py: -------------------------------------------------------------------------------- 1 | 2 | import xlrd 3 | 4 | workbook = xlrd.open_workbook("language_gen.xlsx") 5 | sheet = workbook.sheet_by_index(0) 6 | data = [sheet.row_values(rowx) for rowx in range(sheet.nrows)] 7 | 8 | def write_file(path, data): 9 | print('Writing to', path) 10 | h = open(path, 'w', encoding='utf-8') 11 | h.write(data) 12 | h.close() 13 | 14 | 15 | # TODO: check to make sure all lines are equal 16 | 17 | 18 | for index, i in enumerate(data): 19 | if data[index] == None: 20 | data[index] = list(filter(None, data[index])) 21 | 22 | langtest = data[1][1:] 23 | langtest = list(filter(None, langtest)) 24 | print('Total number of languages: ' + str(len(langtest))) 25 | print(langtest) 26 | 27 | data = data[1:] 28 | col = 1 29 | for language in langtest: 30 | if col > len(langtest): 31 | break 32 | final = '' 33 | for line in data: 34 | if not line: 35 | continue 36 | fields = line 37 | if not fields[0]: 38 | continue 39 | final += '\"' + fields[0] + '\"' #key 40 | final += ' : ' 41 | final += '\"' + fields[col] + '\"' 42 | final += ',\n' 43 | 44 | col += 1 45 | 46 | final = '{\n' + final 47 | final = final[:-2] 48 | final += '\n}' 49 | 50 | 51 | write_file(language + '.json', final) 52 | -------------------------------------------------------------------------------- /language_gen/language_gen.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sandwichdoge/MinimizeToTray/e703f904dd585b45f4a305a2ce08fef9bae566d4/language_gen/language_gen.xlsx -------------------------------------------------------------------------------- /language_gen/requirements.txt: -------------------------------------------------------------------------------- 1 | xlrd==1.2.0 2 | -------------------------------------------------------------------------------- /language_gen/zh.json: -------------------------------------------------------------------------------- 1 | { 2 | "key" : "简中", 3 | "TextId_Already_Running" : "MinimizeToTray 已经运行", 4 | "TextId_Tray_Restore_All_Windows" : "还原所有窗口", 5 | "TextId_Tray_Extra" : "扩展设置", 6 | "TextId_Tray_Opt_AltF4_Force_Exit_Desc" : "Alt-F4 强制退出窗口进程", 7 | "TextId_Tray_Opt_Restore_On_Exit_Desc" : "退出时还原隐藏的窗口", 8 | "TextId_Tray_Opt_Save_Legacy_Windows_Desc" : "保存遗留窗口", 9 | "TextId_Tray_Opt_Alt_Esc_Focus_Change_Desc": "隐藏时自动 Alt+Esc 以平滑切换焦点", 10 | "TextId_Tray_Opt_Restore_Focus" : "将焦点返回给还原窗口", 11 | "TextId_Tray_Edit_Hotkeys" : "设置快捷键", 12 | "TextId_Tray_Quick_Help" : "快速帮助", 13 | "TextId_Tray_Exit" : "退出", 14 | "TextId_GUI_Edit_Hotkeys" : "编辑快捷键", 15 | "TextId_GUI_OK" : "确定", 16 | "TextId_GUI_Default" : "默认", 17 | "TextId_GUI_Hide_Active_Window" : "隐藏活动窗口", 18 | "TextId_GUI_Restore_Last_Window" : "还原最后一个窗口", 19 | "TextId_GUI_Restore_All_Windows" : "还原所有隐藏窗口", 20 | "TextId_GUI_Warning_Key_Overlap" : "不要将ESC键和ALT-F4设置为快捷键,因为它们会和系统快捷键冲突", 21 | "TextId_GUI_Warning_Key_Empty" : "快捷键不能为空", 22 | "TextId_GUI_Language" : "切换语言", 23 | "TextId_Msg_Help_1_Press" : "按", 24 | "TextId_Msg_Help_2_To_Hide_Active" : "以隐藏当前活动窗口", 25 | "TextId_Msg_Help_3_To_Restore" : "以还原最后隐藏的窗口", 26 | "TextId_Msg_Help_4_Stored_In_Tray" : "隐藏的窗口存储在MTT托盘图标中", 27 | "TextId_Msg_Help_5_Elevated_Window_Admin" : "如果要隐藏的窗口是以管理员身份打开,则MTT也必须以管理员身份运行才能将其隐藏" 28 | } -------------------------------------------------------------------------------- /libs/BinaryCall.au3: -------------------------------------------------------------------------------- 1 | ; ============================================================================= 2 | ; AutoIt BinaryCall UDF (2014.7.24) 3 | ; Purpose: Allocate, Decompress, And Prepare Binary Machine Code 4 | ; Author: Ward 5 | ; ============================================================================= 6 | 7 | #Include-once 8 | 9 | Global $__BinaryCall_Kernel32dll = DllOpen('kernel32.dll') 10 | Global $__BinaryCall_Msvcrtdll = DllOpen('msvcrt.dll') 11 | Global $__BinaryCall_LastError = "" 12 | 13 | Func _BinaryCall_GetProcAddress($Module, $Proc) 14 | Local $Ret = DllCall($__BinaryCall_Kernel32dll, 'ptr', 'GetProcAddress', 'ptr', $Module, 'str', $Proc) 15 | If @Error Or Not $Ret[0] Then Return SetError(1, @Error, 0) 16 | Return $Ret[0] 17 | EndFunc 18 | 19 | Func _BinaryCall_LoadLibrary($Filename) 20 | Local $Ret = DllCall($__BinaryCall_Kernel32dll, "handle", "LoadLibraryW", "wstr", $Filename) 21 | If @Error Then Return SetError(1, @Error, 0) 22 | Return $Ret[0] 23 | EndFunc 24 | 25 | Func _BinaryCall_lstrlenA($Ptr) 26 | Local $Ret = DllCall($__BinaryCall_Kernel32dll, "int", "lstrlenA", "ptr", $Ptr) 27 | If @Error Then Return SetError(1, @Error, 0) 28 | Return $Ret[0] 29 | EndFunc 30 | 31 | Func _BinaryCall_Alloc($Code, $Padding = 0) 32 | Local $Length = BinaryLen($Code) + $Padding 33 | Local $Ret = DllCall($__BinaryCall_Kernel32dll, "ptr", "VirtualAlloc", "ptr", 0, "ulong_ptr", $Length, "dword", 0x1000, "dword", 0x40) 34 | If @Error Or Not $Ret[0] Then Return SetError(1, @Error, 0) 35 | If BinaryLen($Code) Then 36 | Local $Buffer = DllStructCreate("byte[" & $Length & "]", $Ret[0]) 37 | DllStructSetData($Buffer, 1, $Code) 38 | EndIf 39 | Return $Ret[0] 40 | EndFunc 41 | 42 | Func _BinaryCall_RegionSize($Ptr) 43 | Local $Buffer = DllStructCreate("ptr;ptr;dword;uint_ptr;dword;dword;dword") 44 | Local $Ret = DllCall($__BinaryCall_Kernel32dll, "int", "VirtualQuery", "ptr", $Ptr, "ptr", DllStructGetPtr($Buffer), "uint_ptr", DllStructGetSize($Buffer)) 45 | If @Error Or $Ret[0] = 0 Then Return SetError(1, @Error, 0) 46 | Return DllStructGetData($Buffer, 4) 47 | EndFunc 48 | 49 | Func _BinaryCall_Free($Ptr) 50 | Local $Ret = DllCall($__BinaryCall_Kernel32dll, "bool", "VirtualFree", "ptr", $Ptr, "ulong_ptr", 0, "dword", 0x8000) 51 | If @Error Or $Ret[0] = 0 Then 52 | $Ret = DllCall($__BinaryCall_Kernel32dll, "bool", "GlobalFree", "ptr", $Ptr) 53 | If @Error Or $Ret[0] <> 0 Then Return SetError(1, @Error, False) 54 | EndIf 55 | Return True 56 | EndFunc 57 | 58 | Func _BinaryCall_Release($CodeBase) 59 | Local $Ret = _BinaryCall_Free($CodeBase) 60 | Return SetError(@Error, @Extended, $Ret) 61 | EndFunc 62 | 63 | Func _BinaryCall_MemorySearch($Ptr, $Length, $Binary) 64 | Static $CodeBase 65 | If Not $CodeBase Then 66 | If @AutoItX64 Then 67 | $CodeBase = _BinaryCall_Create('0x4883EC084D85C94889C8742C4C39CA72254C29CA488D141131C9EB0848FFC14C39C97414448A1408453A140874EE48FFC04839D076E231C05AC3', '', 0, True, False) 68 | Else 69 | $CodeBase = _BinaryCall_Create('0x5589E58B4D14578B4508568B550C538B7D1085C9742139CA721B29CA8D341031D2EB054239CA740F8A1C17381C1074F34039F076EA31C05B5E5F5DC3', '', 0, True, False) 70 | EndIf 71 | If Not $CodeBase Then Return SetError(1, 0, 0) 72 | EndIf 73 | 74 | $Binary = Binary($Binary) 75 | Local $Buffer = DllStructCreate("byte[" & BinaryLen($Binary) & "]") 76 | DllStructSetData($Buffer, 1, $Binary) 77 | 78 | Local $Ret = DllCallAddress("ptr:cdecl", $CodeBase, "ptr", $Ptr, "uint", $Length, "ptr", DllStructGetPtr($Buffer), "uint", DllStructGetSize($Buffer)) 79 | Return $Ret[0] 80 | EndFunc 81 | 82 | Func _BinaryCall_Base64Decode($Src) 83 | Static $CodeBase 84 | If Not $CodeBase Then 85 | If @AutoItX64 Then 86 | $CodeBase = _BinaryCall_Create('0x41544989CAB9FF000000555756E8BE000000534881EC000100004889E7F3A44C89D6E98A0000004439C87E0731C0E98D0000000FB66E01440FB626FFC00FB65E020FB62C2C460FB62424408A3C1C0FB65E034189EB41C1E4024183E3308A1C1C41C1FB044509E34080FF634189CC45881C08744C440FB6DFC1E5044489DF4088E883E73CC1FF0209C7418D44240241887C08014883C10380FB63742488D841C1E3064883C60483E03F4409D841884408FF89F389C84429D339D30F8C67FFFFFF4881C4000100005B5E5F5D415CC35EC3E8F9FFFFFF000000000000000000000000000000000000000000000000000000000000000000000000000000000000003E0000003F3435363738393A3B3C3D00000063000000000102030405060708090A0B0C0D0E0F101112131415161718190000000000001A1B1C1D1E1F202122232425262728292A2B2C2D2E2F30313233', '', 132, True, False) 87 | Else 88 | $CodeBase = _BinaryCall_Create('0x55B9FF00000089E531C05756E8F10000005381EC0C0100008B55088DBDF5FEFFFFF3A4E9C00000003B45140F8FC20000000FB65C0A028A9C1DF5FEFFFF889DF3FEFFFF0FB65C0A038A9C1DF5FEFFFF889DF2FEFFFF0FB65C0A018985E8FEFFFF0FB69C1DF5FEFFFF899DECFEFFFF0FB63C0A89DE83E630C1FE040FB6BC3DF5FEFFFFC1E70209FE8B7D1089F3881C074080BDF3FEFFFF63745C0FB6B5F3FEFFFF8BBDECFEFFFF8B9DE8FEFFFF89F083E03CC1E704C1F80209F88B7D1088441F0189D883C00280BDF2FEFFFF6374278A85F2FEFFFFC1E60683C10483E03F09F088441F0289D883C0033B4D0C0F8C37FFFFFFEB0231C081C40C0100005B5E5F5DC35EC3E8F9FFFFFF000000000000000000000000000000000000000000000000000000000000000000000000000000000000003E0000003F3435363738393A3B3C3D00000063000000000102030405060708090A0B0C0D0E0F101112131415161718190000000000001A1B1C1D1E1F202122232425262728292A2B2C2D2E2F30313233', '', 132, True, False) 89 | EndIf 90 | If Not $CodeBase Then Return SetError(1, 0, Binary("")) 91 | EndIf 92 | 93 | $Src = String($Src) 94 | Local $SrcLen = StringLen($Src) 95 | Local $SrcBuf = DllStructCreate("char[" & $SrcLen & "]") 96 | DllStructSetData($SrcBuf, 1, $Src) 97 | 98 | Local $DstLen = Int(($SrcLen + 2) / 4) * 3 + 1 99 | Local $DstBuf = DllStructCreate("byte[" & $DstLen & "]") 100 | 101 | Local $Ret = DllCallAddress("uint:cdecl", $CodeBase, "ptr", DllStructGetPtr($SrcBuf), "uint", $SrcLen, "ptr", DllStructGetPtr($DstBuf), "uint", $DstLen) 102 | If $Ret[0] = 0 Then Return SetError(2, 0, Binary("")) 103 | Return BinaryMid(DllStructGetData($DstBuf, 1), 1, $Ret[0]) 104 | EndFunc 105 | 106 | Func _BinaryCall_Base64Encode($Src) 107 | Static $CodeBase 108 | If Not $CodeBase Then 109 | If @AutoItX64 Then 110 | $CodeBase = _BinaryCall_Create('AwAAAARiAQAAAAAAAAArkuFQDAlvIp0qAgbDnjr76UDZs1EPNIP2K18t9s6SNTbd43IB7HfdyPM8VfD/o36z4AmSW2m2AIsC6Af3fKNsHU4BdQKGd0PQXHxPSX0iNqp1YAKovksqQna06NeKMoOYqryTUX4WgpHjokhp6zY2sEFSIjcL7dW3FDoNVz4bGPyZHRvjFwmqvr7YGlNYKwNoh+SYCXmIgVPVZ63Vz1fbT33/QFpWmWOeBRqs4J+c8Qp6zJFsK345Pjw0I8kMSsnho4F4oNzQ2OsAbmIioaQ6Ma2ziw5NH+M+t4SpEeHDnBdUTTL20sxWZ0yKruFAsBIRoHvM7LYcid2eBV2d5roSjnkwMG0g69LNjs1fHjbI/9iU/hJwpSsgl4fltXdZG659/li13UFY89M7UfckiZ9XOeBM0zadgNsy8r8M3rEAAA==') 111 | Else 112 | $CodeBase = _BinaryCall_Create('AwAAAARVAQAAAAAAAAAqr7blBndrIGnmhhfXD7R1fkOTKhicg1W6MCtStbz+CsneBEg0bbHH1sqTLmLfY7A6LqZl6LYWT5ULVj6MXgugPbBn9wKsSU2ZCcBBPNkx09HVPdUaKnbqghDGj/C5SHoF+A/5g+UgE1C5zJZORjJ8ljs5lt2Y9lA4BsY7jVKX2vmDvHK1NnSR6nVwh7Pb+Po/UpNcy5sObVWDKkYSCCtCIjKIYqOe3c6k8Xsp4eritCUprXEVvCFi7K5Z6HFXdm3nZsFcE+eSJ1WkRnVQbWcmpjGMGka61C68+CI7tsQ13UnCFWNSpDrCbzUejMZh8HdPgEc5vCg3pKMKin/NavNpB6+87Y9y7HIxmKsPdjDT30u9hUKWnYiRe3nrwKyVDsiYpKU/Nse368jHag5B5or3UKA+nb2+eY8JwzgA') 113 | EndIf 114 | If Not $CodeBase Then Return SetError(1, 0, Binary("")) 115 | EndIf 116 | 117 | $Src = Binary($Src) 118 | Local $SrcLen = BinaryLen($Src) 119 | Local $SrcBuf = DllStructCreate("byte[" & $SrcLen & "]") 120 | DllStructSetData($SrcBuf, 1, $Src) 121 | 122 | Local $DstLen = Int(($SrcLen + 2) / 3) * 4 + 1 123 | Local $DstBuf = DllStructCreate("char[" & $DstLen & "]") 124 | 125 | Local $Ret = DllCallAddress("uint:cdecl", $CodeBase, "ptr", DllStructGetPtr($SrcBuf), "uint", $SrcLen, "ptr", DllStructGetPtr($DstBuf), "uint", $DstLen) 126 | If $Ret[0] = 0 Then Return Binary("") 127 | Return StringMid(DllStructGetData($DstBuf, 1), 1, $Ret[0]) 128 | EndFunc 129 | 130 | Func _BinaryCall_LzmaDecompress($Src) 131 | Static $CodeBase 132 | If Not $CodeBase Then 133 | If @AutoItX64 Then 134 | $CodeBase = _BinaryCall_Create(_BinaryCall_Base64Decode('QVcxwEFWQVVBVFVXSInXVkiJzlMx20iB7OgAAABEiiFBgPzgdgnpyQAAAEGD7C1BiMf/wEGA/Cx38THA6wRBg+wJQYjG/8BBgPwId/GLRglEi24FQQ+2zkyJRCQoRQ+2/0HB5xBBiQFBD7bEAcG4AAMAANPgjYQAcA4AAEhjyOjIBAAATInpSInF6L0EAABIicMxwEyJ8kSI4EyLRCQoiNQl//8A/0QJ+EiF24lFAHQoTYXtdCNIjVfzSI1MJDhIg8YNTIkEJE2J6UmJ2EiJ7+g2AAAAicbrBb4BAAAASInp6IQEAACF9nQKSInZMdvodgQAAEiJ2EiBxOgAAABbXl9dQVxBXUFeQV/DVVNBV0FWQVVBVEFQTQHBQVFNicVRVkgB8lJIieX8SYn0iwdMjX8Eik8Cg8r/0+L30olV6Ijhg8r/0+L30olV5ADBiUXsuAEAAACJReCJRdyJRdhIiUXQRSnJKfaDy/8A0bgAAwAA0+BIjYg2BwAAuAAEAARMif/R6fOrvwUAAADoUAMAAP/PdfdEie9EicgrfSDB4ARBifpEI1XoRAHQTY0cR+hAAwAAD4WTAAAAik3sI33k0+eA6Qj22dPuAfe4AQAAAEiNPH++AAEAAMHnCEGD+QdNjbR/bA4AAHI0TInvSCt90A+2P9HnQYnzIf5BAfNPjRxe6O8CAACJwcHuCIPhATnOvgABAAB1DjnGd9jrDE2J8+jQAgAAOfBy9EyJ76pEiclBg/kEcg65AwAAAEGD+QpyA4PBA0EpyelDAgAAT42cT4ABAADomgIAAHUsi0XcQYP5B4lF4BnAi1XY99CLTdCD4AOJVdxBicGJTdhNjbdkBgAA6akAAABPjZxPmAEAAOhfAgAAdUZEicjB4AREAdBNjZxH4AEAAOhHAgAAdWpBg/kHuQkAAAByA4PBAkGJyUyJ70grfdBIO30gD4L9AQAAigdIA33QqumzAQAAT42cT7ABAADoCgIAAIt12HQhT42cT8gBAADo+AEAAIt13HQJi03ci3XgiU3gi03YiU3ci03QiU3YiXXQQYP5B7kIAAAAcgODwQNBiclNjbdoCgAATYnz6LsBAAB1FESJ0CnJweADvggAAABJjXxGBOs2TY1eAuicAQAAdRpEidC5CAAAAMHgA74IAAAASY28RgQBAADrEUmNvgQCAAC5EAAAAL4AAQAAiU3MuAEAAABJifvoYQEAAInCKfJy8gNVzEGD+QSJVcwPg7kAAABBg8EHuQMAAAA50XICidHB4Qa4AQAAAEmNvE9gAwAAvkAAAABJifvoHwEAAEGJwkEp8nLwQYP6BHJ4RInWRIlV0NHug2XQAf/Og03QAkGD+g5zFYnx0mXQi0XQRCnQTY20R14FAADrLIPuBOi6AAAA0evRZdBBOdhyBv9F0EEp2P/OdedNjbdEBgAAwWXQBL4EAAAAvwEAAACJ+E2J8+ioAAAAqAF0Awl90NHn/8516+sERIlV0P9F0EyJ74tNzEiJ+IPBAkgrRSBIOUXQd1RIif5IK3XQSItVGKyqSDnXcwT/yXX1SYn9D7bwTDttGA+C9fz//+gwAAAAKcBIi1UQTCtlCESJIkiLVWBMK20gRIkqSIPEKEFcQV1BXUFfW13DXli4AQAAAOvSgfsAAAABcgHDweMITDtlAHPmQcHgCEWKBCRJg8QBwynATY0cQ4H7AAAAAXMVweMITDtlAHPBQcHgCEWKBCRJg8QBidlBD7cTwekLD6/KQTnIcxOJy7kACAAAKdHB6QVmQQELAcDDKcvB6gVBKchmQSkTAcCDwAHDSLj////////////gbXN2Y3J0LmRsbHxtYWxsb2MASLj////////////gZnJlZQA=')) 135 | Else 136 | $CodeBase = _BinaryCall_Create(_BinaryCall_Base64Decode('VYnlVzH/VlOD7EyLXQiKC4D54A+HxQAAADHA6wWD6S2I0ID5LI1QAXfziEXmMcDrBYPpCYjQgPkIjVABd/OIReWLRRSITeSLUwkPtsmLcwWJEA+2ReUBwbgAAwAA0+CNhABwDgAAiQQk6EcEAACJNCSJRdToPAQAAItV1InHi0Xkhf+JArgBAAAAdDaF9nQyi0UQg8MNiRQkiXQkFIl8JBCJRCQYjUXgiUQkDItFDIlcJASD6A2JRCQI6CkAAACLVdSJRdSJFCToAQQAAItF1IXAdAqJPCQx/+jwAwAAg8RMifhbXl9dw1dWU1WJ5YtFJAFFKFD8i3UYAXUcVot1FK2SUopO/oPI/9Pg99BQiPGDyP/T4PfQUADRifeD7AwpwEBQUFBQUFcp9laDy/+4AAMAANPgjYg2BwAAuAAEAATR6fOragVZ6MoCAADi+Yt9/ItF8Ct9JCH4iUXosADoywIAAA+FhQAAAIpN9CN97NPngOkI9tnT7lgB916NPH/B5wg8B1qNjH5sDgAAUVa+AAEAAFCwAXI0i338K33cD7Y/i23M0eeJ8SH+AfGNbE0A6JgCAACJwcHuCIPhATnOvgABAAB1DjnwctfrDIttzOh5AgAAOfBy9FqD+gSJ0XIJg/oKsQNyArEGKcpS60mwwOhJAgAAdRRYX1pZWln/NCRRUrpkBgAAsQDrb7DM6CwCAAB1LLDw6BMCAAB1U1g8B7AJcgKwC1CLdfwrddw7dSQPgs8BAACsi338qumOAQAAsNjo9wEAAIt12HQbsOTo6wEAAIt11HQJi3XQi03UiU3Qi03YiU3Ui03ciU3YiXXcWF9ZumgKAACxCAH6Ulc8B4jIcgIEA1CLbczovAEAAHUUi0Xoi33MweADKclqCF6NfEcE6zWLbcyDxQLomwEAAHUYi0Xoi33MweADaghZaghejbxHBAEAAOsQvwQCAAADfcxqEFm+AAEAAIlN5CnAQIn96GYBAACJwSnxcvMBTeSDfcQED4OwAAAAg0XEB4tN5IP5BHIDagNZi33IweEGKcBAakBejbxPYAMAAIn96CoBAACJwSnxcvOJTeiJTdyD+QRyc4nOg2XcAdHug03cAk6D+Q5zGbivAgAAKciJ8dJl3ANF3NHgA0XIiUXM6y2D7gToowAAANHr0WXcOV3gcgb/RdwpXeBOdei4RAYAAANFyIlFzMFl3ARqBF4p/0eJ+IttzOi0AAAAqAF0Awl93NHnTnXs6wD/RdyLTeSDwQKLffyJ+CtFJDlF3HdIif4rddyLVSisqjnXcwNJdfeJffwPtvA7fSgPgnH9///oKAAAACnAjWwkPItVIIt1+Ct1GIkyi1Usi338K30kiTrJW15fw15YKcBA69qB+wAAAAFyAcPB4whWi3X4O3Ucc+SLReDB4AisiUXgiXX4XsOLTcQPtsDB4QQDRegByOsGD7bAA0XEi23IjWxFACnAjWxFAIH7AAAAAXMci0wkOMFkJCAIO0wkXHOcihH/RCQ4weMIiFQkIInZD7dVAMHpCw+vyjlMJCBzF4nLuQAIAAAp0cHpBWYBTQABwI1sJEDDweoFKUwkICnLZilVAAHAg8ABjWwkQMO4///////gbXN2Y3J0LmRsbHxtYWxsb2MAuP//////4GZyZWUA')) 137 | EndIf 138 | If Not $CodeBase Then Return SetError(1, 0, Binary("")) 139 | EndIf 140 | 141 | $Src = Binary($Src) 142 | Local $SrcLen = BinaryLen($Src) 143 | Local $SrcBuf = DllStructCreate("byte[" & $SrcLen & "]") 144 | DllStructSetData($SrcBuf, 1, $Src) 145 | 146 | Local $Ret = DllCallAddress("ptr:cdecl", $CodeBase, "ptr", DllStructGetPtr($SrcBuf), "uint_ptr", $SrcLen, "uint_ptr*", 0, "uint*", 0) 147 | If $Ret[0] Then 148 | Local $DstBuf = DllStructCreate("byte[" & $Ret[3] & "]", $Ret[0]) 149 | Local $Output = DllStructGetData($DstBuf, 1) 150 | DllCall($__BinaryCall_Msvcrtdll, "none:cdecl", "free", "ptr", $Ret[0]) 151 | 152 | Return $Output 153 | EndIf 154 | Return SetError(2, 0, Binary("")) 155 | EndFunc 156 | 157 | Func _BinaryCall_Relocation($Base, $Reloc) 158 | Local $Size = Int(BinaryMid($Reloc, 1, 2)) 159 | 160 | For $i = 3 To BinaryLen($Reloc) Step $Size 161 | Local $Offset = Int(BinaryMid($Reloc, $i, $Size)) 162 | Local $Ptr = $Base + $Offset 163 | DllStructSetData(DllStructCreate("ptr", $Ptr), 1, DllStructGetData(DllStructCreate("ptr", $Ptr), 1) + $Base) 164 | Next 165 | EndFunc 166 | 167 | Func _BinaryCall_ImportLibrary($Base, $Length) 168 | Local $JmpBin, $JmpOff, $JmpLen, $DllName, $ProcName 169 | If @AutoItX64 Then 170 | $JmpBin = Binary("0x48B8FFFFFFFFFFFFFFFFFFE0") 171 | $JmpOff = 2 172 | Else 173 | $JmpBin = Binary("0xB8FFFFFFFFFFE0") 174 | $JmpOff = 1 175 | EndIf 176 | $JmpLen = BinaryLen($JmpBin) 177 | 178 | Do 179 | Local $Ptr = _BinaryCall_MemorySearch($Base, $Length, $JmpBin) 180 | If $Ptr = 0 Then ExitLoop 181 | 182 | Local $StringPtr = $Ptr + $JmpLen 183 | Local $StringLen = _BinaryCall_lstrlenA($StringPtr) 184 | Local $String = DllStructGetData(DllStructCreate("char[" & $StringLen & "]", $StringPtr), 1) 185 | Local $Split = StringSplit($String, "|") 186 | 187 | If $Split[0] = 1 Then 188 | $ProcName = $Split[1] 189 | ElseIf $Split[0] = 2 Then 190 | If $Split[1] Then $DllName = $Split[1] 191 | $ProcName = $Split[2] 192 | EndIf 193 | 194 | If $DllName And $ProcName Then 195 | Local $Handle = _BinaryCall_LoadLibrary($DllName) 196 | If Not $Handle Then 197 | $__BinaryCall_LastError = "LoadLibrary fail on " & $DllName 198 | Return SetError(1, 0, False) 199 | EndIf 200 | 201 | Local $Proc = _BinaryCall_GetProcAddress($Handle, $ProcName) 202 | If Not $Proc Then 203 | $__BinaryCall_LastError = "GetProcAddress failed on " & $ProcName 204 | Return SetError(2, 0, False) 205 | EndIf 206 | 207 | DllStructSetData(DllStructCreate("ptr", $Ptr + $JmpOff), 1, $Proc) 208 | EndIf 209 | 210 | Local $Diff = Int($Ptr - $Base + $JmpLen + $StringLen + 1) 211 | $Base += $Diff 212 | $Length -= $Diff 213 | 214 | Until $Length <= $JmpLen 215 | Return True 216 | EndFunc 217 | 218 | Func _BinaryCall_CodePrepare($Code) 219 | If Not $Code Then Return "" 220 | If IsBinary($Code) Then Return $Code 221 | 222 | $Code = String($Code) 223 | If StringLeft($Code, 2) = "0x" Then Return Binary($Code) 224 | If StringIsXDigit($Code) Then Return Binary("0x" & $Code) 225 | 226 | Return _BinaryCall_LzmaDecompress(_BinaryCall_Base64Decode($Code)) 227 | EndFunc 228 | 229 | Func _BinaryCall_SymbolFind($CodeBase, $Identify, $Length = Default) 230 | $Identify = Binary($Identify) 231 | 232 | If IsKeyword($Length) Then 233 | $Length = _BinaryCall_RegionSize($CodeBase) 234 | EndIf 235 | 236 | Local $Ptr = _BinaryCall_MemorySearch($CodeBase, $Length, $Identify) 237 | If $Ptr = 0 Then Return SetError(1, 0, 0) 238 | 239 | Return $Ptr + BinaryLen($Identify) 240 | EndFunc 241 | 242 | Func _BinaryCall_SymbolList($CodeBase, $Symbol) 243 | If Not IsArray($Symbol) Or $CodeBase = 0 Then Return SetError(1, 0, 0) 244 | 245 | Local $Tag = "" 246 | For $i = 0 To UBound($Symbol) - 1 247 | $Tag &= "ptr " & $Symbol[$i] & ";" 248 | Next 249 | 250 | Local $SymbolList = DllStructCreate($Tag) 251 | If @Error Then Return SetError(1, 0, 0) 252 | 253 | For $i = 0 To UBound($Symbol) - 1 254 | $CodeBase = _BinaryCall_SymbolFind($CodeBase, $Symbol[$i]) 255 | DllStructSetData($SymbolList, $Symbol[$i], $CodeBase) 256 | Next 257 | Return $SymbolList 258 | EndFunc 259 | 260 | Func _BinaryCall_Create($Code, $Reloc = '', $Padding = 0, $ReleaseOnExit = True, $LibraryImport = True) 261 | Local $BinaryCode = _BinaryCall_CodePrepare($Code) 262 | If Not $BinaryCode Then Return SetError(1, 0, 0) 263 | 264 | Local $BinaryCodeLen = BinaryLen($BinaryCode) 265 | Local $TotalCodeLen = $BinaryCodeLen + $Padding 266 | 267 | Local $CodeBase = _BinaryCall_Alloc($BinaryCode, $Padding) 268 | If Not $CodeBase Then Return SetError(2, 0, 0) 269 | 270 | If $Reloc Then 271 | $Reloc = _BinaryCall_CodePrepare($Reloc) 272 | If Not $Reloc Then Return SetError(3, 0, 0) 273 | _BinaryCall_Relocation($CodeBase, $Reloc) 274 | EndIf 275 | 276 | If $LibraryImport Then 277 | If Not _BinaryCall_ImportLibrary($CodeBase, $BinaryCodeLen) Then 278 | _BinaryCall_Free($CodeBase) 279 | Return SetError(4, 0, 0) 280 | EndIf 281 | EndIf 282 | 283 | If $ReleaseOnExit Then 284 | _BinaryCall_ReleaseOnExit($CodeBase) 285 | EndIf 286 | 287 | Return SetError(0, $TotalCodeLen, $CodeBase) 288 | EndFunc 289 | 290 | Func _BinaryCall_CommandLineToArgv($CommandLine, ByRef $Argc, $IsUnicode = False) 291 | Static $SymbolList 292 | If Not IsDllStruct($SymbolList) Then 293 | Local $Code 294 | If @AutoItX64 Then 295 | $Code = 'AwAAAASuAgAAAAAAAAAkL48ClEB9jTEOeYv4yYTosNjFNgf81Ag4vS2VP4y4wxFa+4yMI7GDB7CG+xn4JE3cdEVvk8cMp4oIuS3DgTxlcKHGVIg94tvzG/256bizZfGtAETQUCPQjW5+JSx2C/Y4C0VNJMKTlSCHiV5AzXRZ5gw3WFghbtkCCFxWOX+RDSI2oH/vROEOnqc0jfKTo17EBjqX+dW3QxrUe45xsbyYTZ9ccIGySgcOAxetbRiSxQnz8BOMbJyfrbZbuVJyGpKrXFLh/5MlBZ09Cim9qgflbGzmkrGStT9QL1f+O2krzyOzgaWWqhWL6S+y0G32RWVi0uMLR/JOGLEW/+Yg/4bzkeC0lKELT+RmWAatNa38BRfaitROMN12moRDHM6LYD1lzPLnaiefSQRVti561sxni/AFkYoCb5Lkuyw4RIn/r/flRiUg5w48YkqBBd9rXkaXrEoKwPg6rmOvOCZadu//B6HN4+Ipq5aYNuZMxSJXmxwXVRSQZVpSfLS2ATZMd9/Y7kLqrKy1H4V76SgI/d9OKApfKSbQ8ZaKIHBCsoluEip3UDOB82Z21zd933UH5l0laGWLIrTz7xVGkecjo0NQzR7LyhhoV3xszlIuw2v8q0Q/S9LxB5G6tYbOXo7lLjNIZc0derZz7DNeeeJ9dQE9hp8unubaTBpulPxTNtRjog==' 296 | Else 297 | $Code = 'AwAAAAR6AgAAAAAAAABcQfD553vjya/3DmalU0BKqABevUb/60GZ55rMwmzpQfPSRUlIl04lEiS8RDrXpS0EoBUe+uzDgZd37nVu9wsJ4fykqYvLoMz3ApxQbTBKleOIRSla6I0V8dNP3P7rHeUfjH0jCho0RvhhVpf0o4ht/iZptauxaoy1zQ19TkPZ/vf5Im8ecY6qEdHNzjo2H60jVwiOJ+1J47TmQRwxJ+yKLakq8QNxtKkRIB9B9ugfo3NAL0QslDxbyU0dSgw2aOPxV+uttLzYNnWbLBZVQbchcKgLRjC/32U3Op576sOYFolB1Nj4/33c7MRgtGLjlZfTB/4yNvd4/E+u3U6/Q4MYApCfWF4R/d9CAdiwgIjCYUkGDExKjFtHbAWXfWh9kQ7Q/GWUjsfF9BtHO6924Cy1Ou+BUKksqsxmIKP4dBjvvmz9OHc1FdtR9I63XKyYtlUnqVRtKwlNrYAZVCSFsyAefMbteq1ihU33sCsLkAnp1LRZ2wofgT1/JtT8+GO2s/n52D18wM70RH2n5uJJv8tlxQc1lwbmo4XQvcbcE91U2j9glvt2wC1pkP0hF23Nr/iiIEZHIPAOAHvhervlHE830LSHyUx8yh5Tjojr0gdLvQ==' 298 | EndIf 299 | Local $CodeBase = _BinaryCall_Create($Code) 300 | If @Error Then Return SetError(1, 0, 0) 301 | 302 | Local $Symbol[] = ["ToArgvW","ToArgvA"] 303 | $SymbolList = _BinaryCall_SymbolList($CodeBase, $Symbol) 304 | If @Error Then Return SetError(1, 0, 0) 305 | EndIf 306 | 307 | Local $Ret 308 | If $IsUnicode Then 309 | $Ret = DllCallAddress("ptr:cdecl", DllStructGetData($SymbolList, "ToArgvW"), "wstr", $CommandLine, "int*", 0) 310 | Else 311 | $Ret = DllCallAddress("ptr:cdecl", DllStructGetData($SymbolList, "ToArgvA"), "str", $CommandLine, "int*", 0) 312 | EndIf 313 | 314 | If Not @Error And $Ret[0] <> 0 Then 315 | _BinaryCall_ReleaseOnExit($Ret[0]) 316 | $Argc = $Ret[2] 317 | Return $Ret[0] 318 | Else 319 | Return SetError(2, 0, 0) 320 | EndIf 321 | EndFunc 322 | 323 | Func _BinaryCall_StdioRedirect($Filename = "CON", $Flag = 1 + 2 + 4) 324 | Static $SymbolList 325 | If Not IsDllStruct($SymbolList) Then 326 | Local $Code, $Reloc 327 | If @AutoItX64 Then 328 | $Code = 'AwAAAASjAQAAAAAAAAAkL48ClEB9jTEOeYv4yYTosNjFM1rLNdMULriZUDxTj+ZdkQ01F5zKL+WDCScfQKKLn66EDmcA+gXIkPcZV4lyz8VPw8BPZlNB5KymydM15kCA+uqvmBc1V0NJfzgsF0Amhn0JhM/ZIguYCHxywMQ1SgKxUb05dxDg8WlX/2aPfSolcX47+4/72lPDNTeT7d7XRdm0ND+eCauuQcRH2YOahare9ASxuU4IMHCh2rbZYHwmTNRiQUB/8dLGtph93yhmwdHtyMPLX2x5n6sdA1mxua9htLsLTulE05LLmXbRYXylDz0A' 329 | $Reloc = 'AwAAAAQIAAAAAAAAAAABAB7T+CzGn9ScQAC=' 330 | Else 331 | $Code = 'AwAAAASVAQAAAAAAAABcQfD553vjya/3DmalU0BKqABaUcndypZ3mTYUkHxlLV/lKZPrXYWXgNATjyiowkUQGDVYUy5THQwK4zYdU7xuGf7qfVDELc1SNbiW3NgD4D6N6ZM7auI1jPaThsPfA/ouBcx2aVQX36fjmViTZ8ZLzafjJeR7d5OG5s9sAoIzFLTZsqrFlkIJedqDAOfhA/0mMrkavTWnsio6yTbic1dER0DcEsXpLn0vBNErKHoagLzAgofHNLeFRw5yHWz5owR5CYL7rgiv2k51neHBWGx97A==' 332 | $Reloc = 'AwAAAAQgAAAAAAAAAAABABfyHS/VRkdjBBzbtGPD6vtmVH/IsGHYvPsTv2lGuqJxGlAA' 333 | EndIf 334 | 335 | Local $CodeBase = _BinaryCall_Create($Code, $Reloc) 336 | If @Error Then Return SetError(1, 0, 0) 337 | 338 | Local $Symbol[] = ["StdinRedirect","StdoutRedirect","StderrRedirect"] 339 | $SymbolList = _BinaryCall_SymbolList($CodeBase, $Symbol) 340 | If @Error Then Return SetError(1, 0, 0) 341 | EndIf 342 | 343 | If BitAND($Flag, 1) Then DllCallAddress("none:cdecl", DllStructGetData($SymbolList, "StdinRedirect"), "str", $Filename) 344 | If BitAND($Flag, 2) Then DllCallAddress("none:cdecl", DllStructGetData($SymbolList, "StdoutRedirect"), "str", $Filename) 345 | If BitAND($Flag, 4) Then DllCallAddress("none:cdecl", DllStructGetData($SymbolList, "StderrRedirect"), "str", $Filename) 346 | EndFunc 347 | 348 | Func _BinaryCall_StdinRedirect($Filename = "CON") 349 | Local $Ret = _BinaryCall_StdioRedirect($Filename, 1) 350 | Return SetError(@Error, @Extended, $Ret) 351 | EndFunc 352 | 353 | Func _BinaryCall_StdoutRedirect($Filename = "CON") 354 | Local $Ret = _BinaryCall_StdioRedirect($Filename, 2) 355 | Return SetError(@Error, @Extended, $Ret) 356 | EndFunc 357 | 358 | Func _BinaryCall_StderrRedirect($Filename = "CON") 359 | Local $Ret = _BinaryCall_StdioRedirect($Filename, 4) 360 | Return SetError(@Error, @Extended, $Ret) 361 | EndFunc 362 | 363 | Func _BinaryCall_ReleaseOnExit($Ptr) 364 | OnAutoItExitRegister('__BinaryCall_DoRelease') 365 | __BinaryCall_ReleaseOnExit_Handle($Ptr) 366 | EndFunc 367 | 368 | Func __BinaryCall_DoRelease() 369 | __BinaryCall_ReleaseOnExit_Handle() 370 | EndFunc 371 | 372 | Func __BinaryCall_ReleaseOnExit_Handle($Ptr = Default) 373 | Static $PtrList 374 | 375 | If @NumParams = 0 Then 376 | If IsArray($PtrList) Then 377 | For $i = 1 To $PtrList[0] 378 | _BinaryCall_Free($PtrList[$i]) 379 | Next 380 | EndIf 381 | Else 382 | If Not IsArray($PtrList) Then 383 | Local $InitArray[1] = [0] 384 | $PtrList = $InitArray 385 | EndIf 386 | 387 | If IsPtr($Ptr) Then 388 | Local $Array = $PtrList 389 | Local $Size = UBound($Array) 390 | ReDim $Array[$Size + 1] 391 | $Array[$Size] = $Ptr 392 | $Array[0] += 1 393 | $PtrList = $Array 394 | EndIf 395 | EndIf 396 | EndFunc 397 | -------------------------------------------------------------------------------- /libs/GUIHotkey.au3: -------------------------------------------------------------------------------- 1 | 2 | #include-once 3 | #include "WindowsConstants.au3" 4 | #include "WinAPI.au3" 5 | #include "SendMessage.au3" 6 | #include "UDFGlobalID.au3" 7 | ;#AutoIt3Wrapper_Au3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6 8 | 9 | ; #INDEX# ======================================================================================================================= 10 | ; Title .........: GUIHotkey.au3 11 | ; AutoIt Version : 3.3.0.0+ 12 | ; Minimum OS ....: Windows NT 3.51, Windows 95 13 | ; Language ......: English 14 | ; Description ...: Creation and management of hotkey controls. 15 | ; Author(s) .....: Mat 16 | ; Forum link ....: http://www.autoitscript.com/forum/index.php?showtopic=107965 17 | ; MSDN link .....: http://msdn.microsoft.com/en-us/library/bb775233(VS.85).aspx 18 | ; =============================================================================================================================== 19 | 20 | ; #VARIABLES# =================================================================================================================== 21 | Global Const $__HOTKEYCONSTANT_ClassName = "msctls_hotkey32" 22 | Global $Debug_HK 23 | ; =============================================================================================================================== 24 | 25 | ; #CONSTANTS# =================================================================================================================== 26 | 27 | ; Hotkey Messages. For internal use mainly. 28 | Global Const $HKM_SETHOTKEY = $WM_USER + 1 29 | Global Const $HKM_GETHOTKEY = $WM_USER + 2 30 | Global Const $HKM_SETRULES = $WM_USER + 3 31 | 32 | ; Modifier keys. 33 | Global Const $HOTKEYF_SHIFT = 0x01 ; SHIFT key 34 | Global Const $HOTKEYF_CONTROL = 0x02 ; CONTROL key 35 | Global Const $HOTKEYF_ALT = 0x04 ; ALT key 36 | Global Const $HOTKEYF_EXT = 0x08 ; EXTENDED key 37 | 38 | ; Invalid Key Combinations. For use with _GUICtrlHotkey_SetRules second parameter $iCombInv 39 | Global Const $HKCOMB_NONE = 0x01 ; Unmodified keys 40 | Global Const $HKCOMB_S = 0x02 ; SHIFT 41 | Global Const $HKCOMB_C = 0x04 ; CTRL 42 | Global Const $HKCOMB_A = 0x08 ; ALT 43 | Global Const $HKCOMB_SC = 0x10 ; SHIFT + CTRL 44 | Global Const $HKCOMB_SA = 0x20 ; SHIFT + ALT 45 | Global Const $HKCOMB_CA = 0x40 ; CTRL + ALT 46 | Global Const $HKCOMB_SCA = 0x80 ; SHIFT + CTRL + ALT 47 | ; =============================================================================================================================== 48 | 49 | ; #CURRENT# ===================================================================================================================== 50 | ; _GUICtrlHotkey_Create 51 | ; _GUICtrlHotkey_Delete 52 | ; _GUICtrlHotkey_GetHotkey 53 | ; _GUICtrlHotkey_GetHotkeyCode 54 | ; _GUICtrlHotkey_GetHotkeyName 55 | ; _GUICtrlHotkey_SetHotkey 56 | ; _GUICtrlHotkey_SetHotkeyCode 57 | ; _GUICtrlHotkey_SetHotkeyName 58 | ; _GUICtrlHotkey_SetRules 59 | ; =============================================================================================================================== 60 | 61 | ; #FUNCTION# ==================================================================================================================== 62 | ; Name...........: _GUICtrlHotkey_Create 63 | ; Description ...: Creates a Hotkey control. 64 | ; Syntax.........: _GUICtrlHotkey_Create($hWnd, $vHotkey, $iX, $iY [, $iWidth [, $iHeight [, $iStyle [, $iExStyle]]] ) 65 | ; Parameters ....: $hWnd - A handle to the parent window. 66 | ; $iX - Horizontal position of the control 67 | ; $iY - Vertical position of the control 68 | ; $iWidth - Control width (default is 200) 69 | ; $iHeight - Control height (default is 20) 70 | ; $iStyle - Control style: 71 | ; |Default: $WS_OVERLAPPED 72 | ; |Forced: $WS_CHILD, $WS_VISIBLE 73 | ; $iExStyle - Control extended style 74 | ; |Default: $WS_EX_CLIENTEDGE 75 | ; Return values .: Success - Handle to the control 76 | ; Failure - Returns zero and sets the @error flag. 77 | ; Author ........: Mat 78 | ; Modified.......: 79 | ; Remarks .......: 80 | ; Related .......: 81 | ; Link ..........: 82 | ; Example .......: Yes 83 | ; =============================================================================================================================== 84 | 85 | Func _GUICtrlHotkey_Create($hWnd, $iX, $iY, $iWidth = -1, $iHeight = -1, $iStyle = -1, $iStyleEx = -1) 86 | If (Not IsHWnd($hWnd)) Or (Not WinExists($hWnd)) Then Return SetError(1, 0, 0) ; hWnd is invalid 87 | 88 | If $iWidth = -1 Then $iWidth = 200 89 | If $iHeight = -1 Then $iHeight = 20 90 | If $iStyle = -1 Then $iStyle = $WS_OVERLAPPED 91 | If $iStyleEx = -1 Then $iStyleEx = $WS_EX_CLIENTEDGE 92 | 93 | $iStyle = BitOR($iStyle, $WS_VISIBLE, $WS_CHILD) ; forced styles 94 | 95 | Local $nCtrlID = __UDF_GetNextGlobalID($hWnd) 96 | If @error Then Return SetError(@error, @extended, 0) 97 | 98 | Local $hRet = _WinAPI_CreateWindowEx($iStyleEx, $__HOTKEYCONSTANT_ClassName, "", $iStyle, $iX, $iY, $iWidth, $iHeight, $hWnd, $nCtrlID) 99 | If @error Then Return SetError(@error, @extended, 0) 100 | 101 | Return $hRet 102 | EndFunc ;==>_GUICtrlHotkey_Create 103 | 104 | ; #FUNCTION# ==================================================================================================================== 105 | ; Name...........: _GUICtrlHotkey_Delete 106 | ; Description ...: Deletes the control and tidies up. 107 | ; Syntax.........: _GUICtrlHotkey_Delete($hHotkey) 108 | ; Parameters ....: $hHotkey - A handle to the Hotkey control. 109 | ; Return values .: Success - 1 110 | ; Failure - 0 111 | ; Author ........: Mat 112 | ; Modified.......: 113 | ; Remarks .......: Should be called before exit, especially if the user sets his own fonts. 114 | ; Related .......: _GUICtrlHotkey_Create 115 | ; Link ..........: 116 | ; Example .......: Yes 117 | ; =============================================================================================================================== 118 | 119 | Func _GUICtrlHotkey_Delete($hHotkey) 120 | If Not WinExists($hHotkey) Then Return SetError(1, 0, 0) 121 | 122 | ; Release the font handle 123 | Local $hFont = _SendMessage($hHotkey, $WM_GETFONT) 124 | If $hFont = 0 Then Return SetExtended(1, 1) 125 | _WinAPI_DeleteObject($hFont) 126 | 127 | ; Destroy the window 128 | _WinAPI_DestroyWindow($hHotkey) 129 | If @error Then Return SetError(@error, @extended, 0) 130 | 131 | Return 1 132 | EndFunc ; ==> _GUICtrlHotkey_Delete 133 | 134 | ; #FUNCTION# ==================================================================================================================== 135 | ; Name...........: _GUICtrlHotkey_GetHotkey 136 | ; Description ...: Gets the Send style code for the hotkey control 137 | ; Syntax.........: _GUICtrlHotkey_GetHotkey($hHotkey) 138 | ; Parameters ....: $hHotkey - A handle to the Hotkey control. 139 | ; Return values .: Returns a string with the send syntax that can be used directly with functions such as HotkeySet. 140 | ; Author ........: Mat 141 | ; Modified.......: 142 | ; Remarks .......: See send for details on the return string 143 | ; Related .......: Send, HotkeySet, _GUICtrlHotkey_GetHotkeyCode 144 | ; Link ..........: 145 | ; Example .......: Yes 146 | ; =============================================================================================================================== 147 | 148 | Func _GUICtrlHotkey_GetHotkey($hHotkey) 149 | If Not WinExists($hHotkey) Then Return SetError(1, 0, 0) 150 | 151 | Local $iHotkey = _GUICtrlhotkey_GetHotkeyCode($hHotkey) 152 | If $iHotkey = 0 Then Return "" 153 | 154 | Local $sRet = "" 155 | Local $iHiByte = BitShift($iHotkey, 8) 156 | Local $iLoByte = BitAND($iHotkey, 0xFF) 157 | 158 | If BitAND($iHiByte, $HOTKEYF_CONTROL) Then $sRet &= "^" 159 | If BitAND($iHiByte, $HOTKEYF_SHIFT) Then $sRet &= "+" 160 | If BitAND($iHiByte, $HOTKEYF_ALT) Then $sRet &= "!" 161 | 162 | If BitAND($iHiByte, $HOTKEYF_EXT) Then 163 | Switch $iLoByte 164 | Case 33 165 | $sRet &= "{PGUP}" 166 | Case 34 167 | $sRet &= "{PGDN}" 168 | Case 35 169 | $sRet &= "{END}" 170 | Case 36 171 | $sRet &= "{HOME}" 172 | Case 37 173 | $sRet &= "{LEFT}" 174 | Case 38 175 | $sRet &= "{UP}" 176 | Case 39 177 | $sRet &= "{RIGHT}" 178 | Case 40 179 | $sRet &= "{DOWN}" 180 | Case 45 181 | $sRet &= "{INS}" 182 | Case 111 183 | $sRet &= "{NUMPADDIV}" 184 | Case 144 185 | $sRet &= "{NUMLOCK}" 186 | EndSwitch 187 | Else 188 | Switch $iLoByte 189 | Case 0 190 | Case 20 191 | $sRet &= "{CAPSLOCK}" 192 | Case 96 To 105 193 | $sRet &= "{NUMPAD" & ($iLoByte - 96) & "}" 194 | Case 106 195 | $sRet &= "{NUMPADMULT}" 196 | Case 107 197 | $sRet &= "{NUMPADADD}" 198 | Case 109 199 | $sRet &= "{NUMPADSUB}" 200 | Case 110 201 | $sRet &= "{NUMPADDOT}" 202 | Case 112 To 123 203 | $sRet &= "{F" & ($iLoByte - 111) & "}" 204 | Case 145 205 | $sRet &= "{SCROLLLOCK}" 206 | Case 186 207 | $sRet &= ";" 208 | Case 187 209 | $sRet &= "=" 210 | Case 128 To 191 211 | $sRet &= Chr($iLoByte - 144) 212 | Case 192 213 | $sRet &= "`" 214 | Case 222 215 | $sRet &= "'" 216 | Case 193 To 255 217 | $sRet &= Chr($iLoByte - 128) 218 | Case Else 219 | $sRet &= Chr($iLoByte) 220 | EndSwitch 221 | EndIf 222 | 223 | Return $sRet 224 | EndFunc ;==>_GUICtrlHotkey_GetHotkey 225 | 226 | ; #FUNCTION# ==================================================================================================================== 227 | ; Name...........: _GUICtrlHotkey_GetHotkeyCode 228 | ; Description ...: Gets the virtual key code and modifier flags of a hot key from a hot key control. 229 | ; Syntax.........: _GUICtrlHotkey_GetHotkeyCode($hHotkey) 230 | ; Parameters ....: $hHotkey - A handle to the Hotkey control. 231 | ; Return values .: Success - Returns the virtual key code and modifier flags. The LOBYTE of the LOWORD is the virtual key code of the hot key. 232 | ; The HIBYTE of the LOWORD is the key modifier that specifies the keys that define a hot key combination. 233 | ; The modifier flags can be a combination of the following values. 234 | ; |$HOTKEYF_ALT: ALT key 235 | ; |$HOTKEYF_CONTROL: CONTROL key 236 | ; |$HOTKEYF_EXT: Extended key 237 | ; |$HOTKEYF_SHIFT: SHIFT key 238 | ; Failure - The function will return zero if hotkey control shows "none", @Error is set to 1 if control does not exist. 239 | ; Author ........: Mat 240 | ; Modified.......: 241 | ; Remarks .......: To return more user friendly codes, see the _GUICtrlHotkey_GetHotkey function. 242 | ; Related .......: 243 | ; Link ..........: http://msdn.microsoft.com/en-us/library/bb775235(VS.85).aspx 244 | ; Example .......: Yes 245 | ; =============================================================================================================================== 246 | 247 | Func _GUICtrlhotkey_GetHotkeyCode($hHotkey) 248 | If Not WinExists($hHotkey) Then Return SetError(1, 0, 0) 249 | 250 | Return _SendMessage($hHotkey, $HKM_GETHOTKEY, 0, 0) 251 | EndFunc ;==>_GUICtrlhotkey_GetHotkeyCode 252 | 253 | 254 | Func _GuiCtrlHotkey_NameFromCode($iHotkey) 255 | If $iHotkey = 0 Then Return "" 256 | 257 | Local $sRet = "" 258 | Local $iHiByte = BitShift($iHotkey, 8) 259 | Local $iLoByte = BitAND($iHotkey, 0xFF) 260 | 261 | If BitAND($iHiByte, $HOTKEYF_CONTROL) Then $sRet &= "CTRL+" 262 | If BitAND($iHiByte, $HOTKEYF_SHIFT) Then $sRet &= "SHIFT+" 263 | If BitAND($iHiByte, $HOTKEYF_ALT) Then $sRet &= "ALT+" 264 | 265 | If BitAND($iHiByte, $HOTKEYF_EXT) Then 266 | Switch $iLoByte 267 | Case 33 268 | $sRet &= "PGUP" 269 | Case 34 270 | $sRet &= "PGDN" 271 | Case 35 272 | $sRet &= "END" 273 | Case 36 274 | $sRet &= "HOME" 275 | Case 37 276 | $sRet &= "LEFT" 277 | Case 38 278 | $sRet &= "UP" 279 | Case 39 280 | $sRet &= "RIGHT" 281 | Case 40 282 | $sRet &= "DOWN" 283 | Case 45 284 | $sRet &= "INSERT" 285 | Case 111 286 | $sRet &= "NUM DIVIDE" 287 | Case 144 288 | $sRet &= "NUM LOCK" 289 | EndSwitch 290 | Else 291 | Switch $iLoByte 292 | Case 0 293 | Case 20 294 | $sRet &= "CAPSLOCK" 295 | Case 96 To 105 296 | $sRet &= "NUM " & ($iLoByte - 96) & "" 297 | Case 106 298 | $sRet &= "NUMMULT" ; Seems to be an exception... 299 | Case 107 300 | $sRet &= "NUM PLUS" 301 | Case 109 302 | $sRet &= "NUM SUB" 303 | Case 110 304 | $sRet &= "NUM DECIMAL" 305 | Case 112 To 123 306 | $sRet &= "F" & ($iLoByte - 111) 307 | Case 145 308 | $sRet &= "SCROLL LOCK" 309 | Case 186 310 | $sRet &= ";" 311 | Case 187 312 | $sRet &= "=" 313 | Case 128 To 191 314 | $sRet &= Chr($iLoByte - 144) 315 | Case 192 316 | $sRet &= "`" 317 | Case 222 318 | $sRet &= "'" 319 | Case 193 To 255 320 | $sRet &= Chr($iLoByte - 128) 321 | Case Else 322 | $sRet &= Chr($iLoByte) 323 | EndSwitch 324 | EndIf 325 | 326 | Return $sRet 327 | EndFunc 328 | 329 | ; #FUNCTION# ==================================================================================================================== 330 | ; Name...........: _GUICtrlHotkey_GetHotkeyName 331 | ; Description ...: Gets a User friendly string for the hotkey control 332 | ; Syntax.........: _GUICtrlHotkey_GetHotkeyName($hHotkey) 333 | ; Parameters ....: $hHotkey - A handle to the Hotkey control. 334 | ; Return values .: Returns a string with the hotkey, 335 | ; Author ........: Mat 336 | ; Modified.......: 337 | ; Remarks .......: 338 | ; Related .......: _GUICtrlHotkey_GetHotkeyCode 339 | ; Link ..........: 340 | ; Example .......: Yes 341 | ; =============================================================================================================================== 342 | 343 | Func _GUICtrlHotkey_GetHotkeyName($hHotkey) 344 | If Not WinExists($hHotkey) Then Return SetError(1, 0, 0) 345 | 346 | Local $iHotkey = _GUICtrlhotkey_GetHotkeyCode($hHotkey) 347 | $sRet = _GUICtrlHotkey_NameFromCode($iHotkey) 348 | 349 | Return $sRet 350 | EndFunc ;==>_GUICtrlHotkey_GetHotkeyName 351 | 352 | ; #FUNCTION# ==================================================================================================================== 353 | ; Name...........: _GUICtrlHotkey_SetFont 354 | ; Description ...: Sets the font for the control 355 | ; Syntax.........: _GUICtrlHotkey_SetFont($hHotkey, $nSize [, $nWeight [, $nAttribute [, $sFace [, $nQuality = 2]]]] ) 356 | ; Parameters ....: $hHotkey - The control handle of the hotkey control. (NB: This function will work with other controls 357 | ; but will through up an error if $Debug_HK is set to true. Comment out that line to convert. 358 | ; Return values .: Success - 1 359 | ; Failure - 0 360 | ; Author ........: Mat 361 | ; Modified.......: 362 | ; Remarks .......: To use font specific constants, FontConstants.au3 must be used. There are constants for weight and quality. 363 | ; Related .......: 364 | ; Link ..........: SetFont: http://msdn.microsoft.com/en-us/library/ms632642(VS.85).aspx 365 | ; CreateFont: http://msdn.microsoft.com/en-us/library/dd183499(VS.85).aspx 366 | ; Example .......: Yes 367 | ; =============================================================================================================================== 368 | 369 | Func _GUICtrlHotkey_SetFont($hHotkey, $nSize, $nWeight = 400, $nAttribute = 0, $sFace = "Arial", $nQuality = 2) 370 | If Not WinExists($hHotkey) Then Return SetError(1, 0, 0) 371 | 372 | Local $hDC, $nHeight, $fItalic = False, $fUnderline = False, $fStrikeout = False, $hFont, $hFont_Old 373 | 374 | ; Convert the size to height. (See CreateFont for MSDN example) 375 | $hDC = _WinAPI_GetDC($hHotkey) 376 | If @error Then Return SetError(@error, @extended, 0) 377 | $nHeight = _WinAPI_MulDiv($nSize, _WinAPI_GetDeviceCaps($hDC, 90), 72) ; 90 = LOGPIXELSY 378 | _WinAPI_ReleaseDC($hHotkey, $hDC) 379 | 380 | ; convert attributes 381 | If BitAND($nAttribute, 2) Then $fItalic = True 382 | If BitAND($nAttribute, 4) Then $fUnderline = True 383 | If BitAND($nAttribute, 8) Then $fStrikeout = True 384 | 385 | ; Get the handle for the old font 386 | $hFont_Old = _SendMessage($hHotkey, $WM_GETFONT) 387 | 388 | ; Create the font 389 | $hFont = _WinAPI_CreateFont($nHeight, 0, 0, 0, $nWeight, $fItalic, $fUnderline, $fStrikeOut, 1, 0, 0, $nQuality, 0, $sFace) 390 | If @error Then Return SetError(@error, @extended, 0) 391 | 392 | ; Send the message and clear up. 393 | _WinAPI_SetFont($hHotkey, $hFont, True) 394 | If @error Then 395 | _WinAPI_DeleteObject($hFont) 396 | Return SetError(@error, @extended, 0) 397 | EndIf 398 | 399 | ; Delete the old font 400 | If $hFont_Old Then _WinAPI_DeleteObject($hFont_Old) 401 | 402 | Return 1 403 | EndFunc ;==>_GUIHotkey_SetFont 404 | 405 | 406 | Func _GuiCtrlHotkey_CodeFromAutoItHK($sHotKey) 407 | Local $iHiByte = 0 408 | Local $iLoByte = 0 409 | 410 | $sHotkey = StringReplace($sHotkey, "^", "") 411 | If @extended Then $iHiByte += $HOTKEYF_CONTROL 412 | 413 | $sHotkey = StringReplace($sHotkey, "+", "") 414 | If @extended Then $iHiByte += $HOTKEYF_SHIFT 415 | 416 | $sHotkey = StringReplace($sHotkey, "!", "") 417 | If @extended Then $iHiByte += $HOTKEYF_ALT 418 | 419 | While 1 420 | Switch $sHotkey 421 | Case "{PGUP}" 422 | $iLoByte += 33 423 | Case "{PGDN}" 424 | $iLoByte += 34 425 | Case "{END}" 426 | $iLoByte += 35 427 | Case "{HOME}" 428 | $iLoByte += 36 429 | Case "{LEFT}" 430 | $iLoByte += 37 431 | Case "{UP}" 432 | $iLoByte += 38 433 | Case "{RIGHT}" 434 | $iLoByte += 39 435 | Case "{DOWN}" 436 | $iLoByte += 40 437 | Case "{INS}" 438 | $iLoByte += 45 439 | Case "{NUMPADDIV}" 440 | $iLoByte += 111 441 | Case "{NUMLOCK}" 442 | $iLoByte += 144 443 | Case Else 444 | Switch $sHotkey 445 | Case "{CAPSLOCK}" 446 | $iLoByte = 20 447 | Case "{NUMPADMULT}" 448 | $iLoByte = 106 449 | Case "{NUMPADADD}" 450 | $iLoByte = 107 451 | Case "{NUMPADSUB}" 452 | $iLoByte = 109 453 | Case "{NUMPADDOT}" 454 | $iLoByte = 110 455 | Case "{SCROLLLOCK}" 456 | $iLoByte = 145 457 | Case ";" 458 | $iLoByte = 186 459 | Case "=" 460 | $iLoByte = 187 461 | Case "`" 462 | $iLoByte = 192 463 | Case "'" 464 | $iLoByte = 222 465 | Case Else 466 | While 1 467 | For $i = 16 To 47 468 | If $sHotkey = Chr($i) Then 469 | $iLoByte = $i + 144 470 | ExitLoop 2 471 | EndIf 472 | Next 473 | For $i = 65 To 127 474 | If $sHotkey = Chr($i) Then 475 | $iLoByte = $i 476 | ExitLoop 2 477 | EndIf 478 | Next 479 | For $i = 0 To 9 480 | If $sHotkey = "{numpad" & $i & "}" Then 481 | $iLoByte = $i + 96 482 | ExitLoop 2 483 | EndIf 484 | Next 485 | For $i = 1 To 12 486 | If $sHotkey = "{f" & $i & "}" Then 487 | $iLoByte = $i + 111 488 | ExitLoop 2 489 | EndIf 490 | Next 491 | $iLoByte = Asc($sHotkey) 492 | ExitLoop 493 | WEnd 494 | EndSwitch 495 | ExitLoop 496 | EndSwitch 497 | $iHiByte += $HOTKEYF_EXT 498 | ExitLoop 499 | WEnd 500 | $iRet = BitShift($iHiByte, -8) + $iLoByte 501 | Return $iRet 502 | EndFunc 503 | 504 | ; #FUNCTION# ==================================================================================================================== 505 | ; Name...........: _GUICtrlHotkey_SetHotkey 506 | ; Description ...: Sets the hot key combination for a hot key control in send form. 507 | ; Syntax.........: _GUICtrlHotkey_SetHotkey($hHotkey, $sHotkey) 508 | ; Parameters ....: $hHotkey - A handle to the Hotkey control. 509 | ; $sHotkey - A string in send form showing the hotkey. 510 | ; Return values .: Success - 1 511 | ; Failure - 0 512 | ; Author ........: Mat 513 | ; Modified.......: 514 | ; Remarks .......: 515 | ; Related .......: _GUICtrlHotkey_GetHotkey, _GUICtrlHotkey_SetHotKeyCode 516 | ; Link ..........: 517 | ; Example .......: Yes 518 | ; =============================================================================================================================== 519 | 520 | Func _GUICtrlHotkey_SetHotkey($hHotkey, $sHotkey) 521 | If Not WinExists($hHotkey) Then Return SetError(1, 0, 0) 522 | If $sHotkey = "" Then _ ; Set hotkey control to "none" 523 | Return _GUICtrlHotkey_SetHotkeyCode($hHotkey, 0) 524 | 525 | Return _GUICtrlHotkey_SetHotkeyCode($hHotkey, _GuiCtrlHotkey_CodeFromAutoItHK($sHotkey)) 526 | EndFunc ;==>_GUICtrlHotkey_SetHotkey 527 | 528 | ; #FUNCTION# ==================================================================================================================== 529 | ; Name...........: _GUICtrlHotkey_SetHotkeyCode 530 | ; Description ...: Sets the hot key combination for a hot key control. 531 | ; Syntax.........: _GUICtrlHotkey_SetHotkeyCode($hHotkey, $iHotkey) 532 | ; Parameters ....: $hHotkey - A handle to the Hotkey control. 533 | ; $iHotkey - A value to show the code for the hotkey. 534 | ; Return values .: Success - 1 535 | ; Failure - 0 536 | ; Author ........: Mat 537 | ; Modified.......: 538 | ; Remarks .......: 539 | ; Related .......: _GUICtrlHotkey_GetHotkeyCode, _GUICtrlHotkey_SetHotKey 540 | ; Link ..........: http://msdn.microsoft.com/en-us/library/bb775236(VS.85).aspx 541 | ; Example .......: Yes 542 | ; =============================================================================================================================== 543 | 544 | Func _GUICtrlHotkey_SetHotkeyCode($hHotkey, $iHotkey) 545 | If Not WinExists($hHotkey) Then Return SetError(1, 0, 0) 546 | 547 | _SendMessage($hHotkey, $HKM_SETHOTKEY, $iHotkey, 0) 548 | Return 1 549 | EndFunc ;==>_GUICtrlHotkey_SetHotkeyCode 550 | 551 | ; #FUNCTION# ==================================================================================================================== 552 | ; Name...........: _GUICtrlHotkey_SetHotkeyName 553 | ; Description ...: Sets the hot key combination for a hot key control in user friendly form. 554 | ; Syntax.........: _GUICtrlHotkey_SetHotkey($hHotkey, $sHotkey) 555 | ; Parameters ....: $hHotkey - A handle to the Hotkey control. 556 | ; $sHotkey - A string in the normal form form showing the hotkey. (SHIFT+V) 557 | ; Return values .: Success - 1 558 | ; Failure - 0 559 | ; Author ........: Mat 560 | ; Modified.......: 561 | ; Remarks .......: 562 | ; Related .......: _GUICtrlHotkey_GetHotkeyName, _GUICtrlHotkey_SetHotKeyCode 563 | ; Link ..........: 564 | ; Example .......: Yes 565 | ; =============================================================================================================================== 566 | 567 | Func _GUICtrlHotkey_SetHotkeyName($hHotkey, $sHotkey) 568 | If Not WinExists($hHotkey) Then Return SetError(1, 0, 0) 569 | If $sHotkey = "" Then _ ; Set hotkey control to "none" 570 | Return _GUICtrlHotkey_SetHotkeyCode($hHotkey, 0) 571 | 572 | Local $iHiByte = 0 573 | Local $iLoByte = 0 574 | 575 | $sHotkey = StringStripWS($sHotkey, 8) 576 | 577 | $sHotkey = StringReplace($sHotkey, "CTRL+", "") 578 | If @extended Then $iHiByte += $HOTKEYF_CONTROL 579 | 580 | $sHotkey = StringReplace($sHotkey, "SHIFT+", "") 581 | If @extended Then $iHiByte += $HOTKEYF_SHIFT 582 | 583 | $sHotkey = StringReplace($sHotkey, "ALT+", "") 584 | If @extended Then $iHiByte += $HOTKEYF_ALT 585 | 586 | Switch $sHotkey 587 | Case "CAPSLOCK" 588 | $iLoByte = 20 589 | Case "NUMMULT" 590 | $iLoByte = 106 591 | Case "NUMPLUS" 592 | $iLoByte = 107 593 | Case "NUMSUB" 594 | $iLoByte = 109 595 | Case "NUMDECIMAL" 596 | $iLoByte = 110 597 | Case "SCROLLLOCK" 598 | $iLoByte = 145 599 | Case ";" 600 | $iLoByte = 186 601 | Case "=" 602 | $iLoByte = 187 603 | Case "`" 604 | $iLoByte = 192 605 | Case "'" 606 | $iLoByte = 222 607 | Case Else 608 | While 1 609 | For $i = 16 To 47 610 | If $sHotkey = Chr($i) Then 611 | $iLoByte = $i + 144 612 | ExitLoop 2 613 | EndIf 614 | Next 615 | For $i = 65 To 127 616 | If $sHotkey = Chr($i) Then 617 | $iLoByte = $i 618 | ExitLoop 2 619 | EndIf 620 | Next 621 | For $i = 0 To 9 622 | If $sHotkey = "NUM" & $i Then 623 | $iLoByte = $i + 96 624 | ExitLoop 2 625 | EndIf 626 | Next 627 | For $i = 1 To 12 628 | If $sHotkey = "F" & $i Then 629 | $iLoByte = $i + 111 630 | ExitLoop 2 631 | EndIf 632 | Next 633 | $iLoByte = Asc($sHotkey) 634 | ExitLoop 635 | WEnd 636 | EndSwitch 637 | 638 | Return _GUICtrlHotkey_SetHotkeyCode($hHotkey, BitShift($iHiByte, -8) + $iLoByte) 639 | EndFunc ;==>_GUICtrlHotkey_SetHotkeyName 640 | 641 | ; #FUNCTION# ==================================================================================================================== 642 | ; Name...........: _GUICtrlHotkey_SetRules 643 | ; Description ...: Defines the invalid combinations and the default modifier combination for a hot key control. 644 | ; Syntax.........: _GUICtrlHotkey_SetRules($hHotkey, $iCombInv, $iModInv) 645 | ; Parameters ....: $hHotkey - A handle to the Hotkey control. 646 | ; $iCombInv - A value to specify the invalid key combinations. Can be a combination of the following: 647 | ; |$HKCOMB_A: ALT 648 | ; |$HKCOMB_C: CTRL 649 | ; |$HKCOMB_CA: CTRL+ALT 650 | ; |$HKCOMB_NONE: Unmodified keys 651 | ; |$HKCOMB_S: SHIFT 652 | ; |$HKCOMB_SA: SHIFT+ALT 653 | ; |$HKCOMB_SC: SHIFT+CTRL 654 | ; |$HKCOMB_SCA: SHIFT+CTRL+ALT 655 | ; $iModInv - The key combination to use when the user enters an invalid combination. Can be a combination of the following: 656 | ; |$HOTKEYF_ALT: ALT key 657 | ; |$HOTKEYF_CONTROL: CONTROL key 658 | ; |$HOTKEYF_EXT: Extended key 659 | ; |$HOTKEYF_SHIFT: SHIFT key 660 | ; Return values .: No return value. 661 | ; Author ........: Mat 662 | ; Modified.......: 663 | ; Remarks .......: For multiple values, you should use the BitOR function. 664 | ; Related .......: 665 | ; Link ..........: http://msdn.microsoft.com/en-us/library/bb775237(VS.85).aspx 666 | ; Example .......: Yes 667 | ; =============================================================================================================================== 668 | 669 | Func _GUICtrlHotkey_SetRules($hHotkey, $iCombInv, $iModInv) 670 | If Not WinExists($hHotkey) Then Return SetError(1, 0, 0) 671 | 672 | _SendMessage($hHotkey, $HKM_SETRULES, $iCombInv, $iModInv) 673 | EndFunc ;==>_GUICtrlHotkey_SetRules 674 | 675 | 676 | Func _GuiCtrlHotkey_NameFromAutoItHK($sHotkey) 677 | $iHotkey = _GuiCtrlHotkey_CodeFromAutoItHK($sHotkey) 678 | $sName = _GuiCtrlHotkey_NameFromCode($iHotkey) 679 | Return $sName 680 | EndFunc -------------------------------------------------------------------------------- /libs/Json.au3: -------------------------------------------------------------------------------- 1 | ; ============================================================================================================================ 2 | ; File : Json.au3 (2018.12.29) 3 | ; Purpose : A Non-Strict JavaScript Object Notation (JSON) Parser UDF 4 | ; Author : Ward 5 | ; Dependency: BinaryCall.au3 6 | ; Website : http://www.json.org/index.html 7 | ; 8 | ; Source : jsmn.c 9 | ; Author : zserge 10 | ; Website : http://zserge.com/jsmn.html 11 | ; 12 | ; Source : json_string_encode.c, json_string_decode.c 13 | ; Author : Ward 14 | ; Jos - Added Json_Dump() 15 | ; TheXMan - Json_ObjGetItems and some Json_Dump Fixes. 16 | ; Jos - Changed Json_ObjGet() and Json_ObjExists() to allow for multilevel object in string. 17 | ; ============================================================================================================================ 18 | 19 | ; ============================================================================================================================ 20 | ; Public Functions: 21 | ; Json_StringEncode($String, $Option = 0) 22 | ; Json_StringDecode($String) 23 | ; Json_IsObject(ByRef $Object) 24 | ; Json_IsNull(ByRef $Null) 25 | ; Json_Encode($Data, $Option = 0, $Indent = Default, $ArraySep = Default, $ObjectSep = Default, $ColonSep = Default) 26 | ; Json_Decode($Json, $InitTokenCount = 1000) 27 | ; Json_ObjCreate() 28 | ; Json_ObjPut(ByRef $Object, $Key, $Value) 29 | ; Json_ObjGet(ByRef $Object, $Key) 30 | ; Json_ObjDelete(ByRef $Object, $Key) 31 | ; Json_ObjExists(ByRef $Object, $Key) 32 | ; Json_ObjGetCount(ByRef $Object) 33 | ; Json_ObjGetKeys(ByRef $Object) 34 | ; Json_ObjGetItems(ByRef $Object) 35 | ; Json_ObjClear(ByRef $Object) 36 | ; Json_Put(ByRef $Var, $Notation, $Data, $CheckExists = False) 37 | ; Json_Get(ByRef $Var, $Notation) 38 | ; Json_Dump($String) 39 | ; ============================================================================================================================ 40 | 41 | #include-once 42 | #include "BinaryCall.au3" 43 | 44 | ; The following constants can be combined to form options for Json_Encode() 45 | Global Const $JSON_UNESCAPED_UNICODE = 1 ; Encode multibyte Unicode characters literally 46 | Global Const $JSON_UNESCAPED_SLASHES = 2 ; Don't escape / 47 | Global Const $JSON_HEX_TAG = 4 ; All < and > are converted to \u003C and \u003E 48 | Global Const $JSON_HEX_AMP = 8 ; All &s are converted to \u0026 49 | Global Const $JSON_HEX_APOS = 16 ; All ' are converted to \u0027 50 | Global Const $JSON_HEX_QUOT = 32 ; All " are converted to \u0022 51 | Global Const $JSON_UNESCAPED_ASCII = 64 ; Don't escape ascii charcters between chr(1) ~ chr(0x1f) 52 | Global Const $JSON_PRETTY_PRINT = 128 ; Use whitespace in returned data to format it 53 | Global Const $JSON_STRICT_PRINT = 256 ; Make sure returned JSON string is RFC4627 compliant 54 | Global Const $JSON_UNQUOTED_STRING = 512 ; Output unquoted string if possible (conflicting with $Json_STRICT_PRINT) 55 | 56 | ; Error value returnd by Json_Decode() 57 | Global Const $JSMN_ERROR_NOMEM = -1 ; Not enough tokens were provided 58 | Global Const $JSMN_ERROR_INVAL = -2 ; Invalid character inside JSON string 59 | Global Const $JSMN_ERROR_PART = -3 ; The string is not a full JSON packet, more bytes expected 60 | Global $Total_JSON_DUMP_Output = "" 61 | 62 | Func __Jsmn_RuntimeLoader($ProcName = "") 63 | Static $SymbolList 64 | If Not IsDllStruct($SymbolList) Then 65 | Local $Code 66 | If @AutoItX64 Then 67 | $Code = 'AwAAAAQfCAAAAAAAAAA1HbEvgTNrvX54gCiWSTVmt5v7RCdoFJ/zhkKmwcm8yVqZPjJBoVhNHHAIzrHWKbZh1J0QAUaHB5zyQTilTmWa9O0OKeLrk/Jg+o7CmMzjEk74uPongdHv37nwYXvg97fiHvjP2bBzI9gxSkKq9Cqh/GxSHIlZPYyW76pXUt//25Aqs2Icfpyay/NFd50rW7eMliH5ynkrp16HM1afithVrO+LpSaz/IojowApmXnBHUncHliDqbkx6/AODUkyDm1hj+AiEZ9Me1Jy+hBQ1/wC/YnuuYSJvNAKp6XDnyc8Nwr54Uqx5SbUW2CezwQQ7aXX/HFiHSKpQcFW/gi8oSx5nsoxUXVjxeNI/L7z6GF2mfu3Tnpt7hliWEdA2r2VB+TIM7Pgwl9X3Ge0T3KJQUaRtLJZcPvVtOuKXr2Q9wy7hl80hVRrt9zYrbjBHXLrRx/HeIMkZwxhmKo/dD/vvaNgE+BdU8eeJqFBJK2alrK2rh2WkRynftyepm1WrdKrz/5KhQPp/4PqH+9IADDjoGBbfvJQXdT+yiO8DtfrVnd+JOEKsKEsdgeM3UXx5r6tEHO9rYWbzbnyEiX7WozZemry+vBZMMtHn1aA63+RcDQED73xOsnj00/9E5Z6hszM5Hi8vi6Hw3iOgf3cHwcXG44aau0JpuA2DlrUvnJOYkNnY+bECeSdAR1UQkFNyqRoH2xm4Y7gYMCPsFtPBlwwleEKI27SsUq1ZHVQvFCoef7DXgf/GwPCAvwDMIQfb3hJtIVubOkASRQZVNIJ/y4KPrn/gcASV7fvMjE34loltTVlyqprUWxpI51tN6vhTOLAp+CHseKxWaf9g1wdbVs0e/5xAiqgJbmKNi9OYbhV/blpp3SL63XKxGiHdxhK1aR+4rUY4eckNbaHfW7ob+q7aBoHSs6LVX9lWakb/xWxwQdwcX/7/C+TcQSOOg6rLoWZ8wur9qp+QwzoCbXkf04OYpvD5kqgEiwQnB90kLtcA+2XSbDRu+aq02eNNCzgkZujeL/HjVISjf2EuQKSsZkBhS15eiXoRgPaUoQ5586VS7t7rhM8ng5LiVzoUQIZ0pNKxWWqD+gXRBvOMIXY2yd0Ei4sE5KFIEhbs3u8vwP7nFLIpZ/RembPTuc0ZlguGJgJ2F5iApfia+C2tRYRNjVCqECCveWw6P2Btfaq9gw7cWWmJflIQbjxtccDqsn52cftLqXSna9zk05mYdJSV8z2W7vM1YJ5Rd82v0j3kau710A/kQrN41bdaxmKjL+gvSRlOLB1bpvkCtf9+h+eVA4XIkIXKFydr1OjMZ8wq2FIxPJXskAe4YMgwQmeWZXMK1KBbLB3yQR1YOYaaHk1fNea9KsXgs5YLbiP/noAusz76oEDo/DJh1aw7cUwdhboVPg1bNq88mRb5RGa13KDK9uEET7OA02KbSL+Q4HOtyasLUoVrZzVyd8iZPoGrV36vHnj+yvG4fq6F/fkug/sBRp186yVZQVmdAgFd+WiRLnUjxHUKJ6xBbpt4FTP42E/PzPw3JlDb0UQtXTDnIL0CWqbns2E7rZ5PBwrwQYwvBn/gaEeLVGDSh84DfW4zknIneGnYDXdVEHC+ITzejAnNxb1duB+w2aVTk64iXsKHETq53GMH6DuFi0oUeEFb/xp0HsRyNC8vBjOq3Kk7NZHxCQLh7UATFttG7sH+VIqGjjNwmraGJ0C92XhpQwSgfAb3KHucCHGTTti0sn6cgS3vb36BkjGKsRhXVuoQCFH96bvTYtl8paQQW9ufRfvxPqmU0sALdR0fIvZwd7Z8z0UoEec6b1Sul4e60REj/H4scb6N2ryHBR9ua5N1YxJu1uwgoLXUL2wT9ZPBjPjySUzeqXikUIKKYgNlWy+VlNIiWWTPtKpCTr508logA==' 68 | Else 69 | $Code = 'AwAAAASFBwAAAAAAAAA1HbEvgTNrvX54gCiqsa1mt5v7RCdoAFjCfVE40DZbE5UfabA9UKuHrjqOMbvjSoB2zBJTEYEQejBREnPrXL3VwpVOW+L9SSfo0rTfA8U2W+Veqo1uy0dOsPhl7vAHbBHrvJNfEUe8TT0q2eaTX2LeWpyrFEm4I3mhDJY/E9cpWf0A78e+y4c7NxewvcVvAakIHE8Xb8fgtqCTVQj3Q1eso7n1fKQj5YsQ20A86Gy9fz8dky78raeZnhYayn0b1riSUKxGVnWja2i02OvAVM3tCCvXwcbSkHTRjuIAbMu2mXF1UpKci3i/GzPmbxo9n/3aX/jpR6UvxMZuaEDEij4yzfZv7EyK9WCNBXxMmtTp3Uv6MZsK+nopXO3C0xFzZA/zQObwP3zhJ4sdatzMhFi9GAM70R4kgMzsxQDNArueXj+UFzbCCFZ89zXs22F7Ixi0FyFTk3jhH56dBaN65S+gtPztNGzEUmtk4M8IanhQSw8xCXr0x0MPDpDFDZs3aN5TtTPYmyk3psk7OrmofCQGG5cRcqEt9902qtxQDOHumfuCPMvU+oMjzLzBVEDnBbj+tY3y1jvgGbmEJguAgfB04tSeAt/2618ksnJJK+dbBkDLxjB4xrFr3uIFFadJQWUckl5vfh4MVXbsFA1hG49lqWDa7uSuPCnOhv8Yql376I4U4gfcF8LcgorkxS+64urv2nMUq6AkBEMQ8bdkI64oKLFfO7fGxh5iMNZuLoutDn2ll3nq4rPi4kOyAtfhW0UPyjvqNtXJ/h0Wik5Mi8z7BVxaURTDk81TP8y9+tzjySB/uGfHFAzjF8DUY1vqJCgn0GQ8ANtiiElX/+Wnc9HWi2bEEXItbm4yv97QrEPvJG9nPRBKWGiAQsIA5J+WryX5NrfEfRPk0QQwyl16lpHlw6l0UMuk7S21xjQgyWo0MywfzoBWW7+t4HH9sqavvP4dYAw81BxXqVHQhefUOS23en4bFUPWE98pAN6bul+kS767vDK34yTC3lA2a8wLrBEilmFhdB74fxbAl+db91PivhwF/CR4Igxr35uLdof7+jAYyACopQzmsbHpvAAwT2lapLix8H03nztAC3fBqFSPBVdIv12lsrrDw4dfhJEzq7AbL/Y7L/nIcBsQ/3UyVnZk4kZP1KzyPCBLLIQNpCVgOLJzQuyaQ6k2QCBy0eJ0ppUyfp54LjwVg0X7bwncYbAomG4ZcFwTQnC2AX3oYG5n6Bz4SLLjxrFsY+v/SVa+GqH8uePBh1TPkHVNmzjXXymEf5jROlnd+EjfQdRyitkjPrg2HiQxxDcVhCh5J2L5+6CY9eIaYgrbd8zJnzAD8KnowHwh2bi4JLgmt7ktJ1XGizox7cWf3/Dod56KAcaIrSVw9XzYybdJCf0YRA6yrwPWXbwnzc/4+UDkmegi+AoCEMoue+cC7vnYVdmlbq/YLE/DWJX383oz2Ryq8anFrZ8jYvdoh8WI+dIugYL2SwRjmBoSwn56XIaot/QpMo3pYJIa4o8aZIZrjvB7BXO5aCDeMuZdUMT6AXGAGF1AeAWxFd2XIo1coR+OplMNDuYia8YAtnSTJ9JwGYWi2dJz3xrxsTQpBONf3yn8LVf8eH+o5eXc7lzCtHlDB+YyI8V9PyMsUPOeyvpB3rr9fDfNy263Zx33zTi5jldgP2OetUqGfbwl+0+zNYnrg64bluyIN/Awt1doDCQkCKpKXxuPaem/SyCHrKjg' 70 | EndIf 71 | 72 | Local $Symbol[] = ["jsmn_parse", "jsmn_init", "json_string_decode", "json_string_encode"] 73 | Local $CodeBase = _BinaryCall_Create($Code) 74 | If @error Then Exit MsgBox(16, "Json", "Startup Failure!") 75 | 76 | $SymbolList = _BinaryCall_SymbolList($CodeBase, $Symbol) 77 | If @error Then Exit MsgBox(16, "Json", "Startup Failure!") 78 | EndIf 79 | If $ProcName Then Return DllStructGetData($SymbolList, $ProcName) 80 | EndFunc ;==>__Jsmn_RuntimeLoader 81 | 82 | Func Json_StringEncode($String, $Option = 0) 83 | Static $Json_StringEncode = __Jsmn_RuntimeLoader("json_string_encode") 84 | Local $Length = StringLen($String) * 6 + 1 85 | Local $Buffer = DllStructCreate("wchar[" & $Length & "]") 86 | Local $Ret = DllCallAddress("int:cdecl", $Json_StringEncode, "wstr", $String, "ptr", DllStructGetPtr($Buffer), "uint", $Length, "int", $Option) 87 | Return SetError($Ret[0], 0, DllStructGetData($Buffer, 1)) 88 | EndFunc ;==>Json_StringEncode 89 | 90 | Func Json_StringDecode($String) 91 | Static $Json_StringDecode = __Jsmn_RuntimeLoader("json_string_decode") 92 | Local $Length = StringLen($String) + 1 93 | Local $Buffer = DllStructCreate("wchar[" & $Length & "]") 94 | Local $Ret = DllCallAddress("int:cdecl", $Json_StringDecode, "wstr", $String, "ptr", DllStructGetPtr($Buffer), "uint", $Length) 95 | Return SetError($Ret[0], 0, DllStructGetData($Buffer, 1)) 96 | EndFunc ;==>Json_StringDecode 97 | 98 | Func Json_Decode($Json, $InitTokenCount = 1000) 99 | Static $Jsmn_Init = __Jsmn_RuntimeLoader("jsmn_init"), $Jsmn_Parse = __Jsmn_RuntimeLoader("jsmn_parse") 100 | If $Json = "" Then $Json = '""' 101 | Local $TokenList, $Ret 102 | Local $Parser = DllStructCreate("uint pos;int toknext;int toksuper") 103 | Do 104 | DllCallAddress("none:cdecl", $Jsmn_Init, "ptr", DllStructGetPtr($Parser)) 105 | $TokenList = DllStructCreate("byte[" & ($InitTokenCount * 20) & "]") 106 | $Ret = DllCallAddress("int:cdecl", $Jsmn_Parse, "ptr", DllStructGetPtr($Parser), "wstr", $Json, "ptr", DllStructGetPtr($TokenList), "uint", $InitTokenCount) 107 | $InitTokenCount *= 2 108 | Until $Ret[0] <> $JSMN_ERROR_NOMEM 109 | 110 | Local $Next = 0 111 | Return SetError($Ret[0], 0, _Json_Token($Json, DllStructGetPtr($TokenList), $Next)) 112 | EndFunc ;==>Json_Decode 113 | 114 | Func _Json_Token(ByRef $Json, $Ptr, ByRef $Next) 115 | If $Next = -1 Then Return Null 116 | 117 | Local $Token = DllStructCreate("int;int;int;int", $Ptr + ($Next * 20)) 118 | Local $Type = DllStructGetData($Token, 1) 119 | Local $Start = DllStructGetData($Token, 2) 120 | Local $End = DllStructGetData($Token, 3) 121 | Local $Size = DllStructGetData($Token, 4) 122 | $Next += 1 123 | 124 | If $Type = 0 And $Start = 0 And $End = 0 And $Size = 0 Then ; Null Item 125 | $Next = -1 126 | Return Null 127 | EndIf 128 | 129 | Switch $Type 130 | Case 0 ; Json_PRIMITIVE 131 | Local $Primitive = StringMid($Json, $Start + 1, $End - $Start) 132 | Switch $Primitive 133 | Case "true" 134 | Return True 135 | Case "false" 136 | Return False 137 | Case "null" 138 | Return Null 139 | Case Else 140 | If StringRegExp($Primitive, "^[+\-0-9]") Then 141 | Return Number($Primitive) 142 | Else 143 | Return Json_StringDecode($Primitive) 144 | EndIf 145 | EndSwitch 146 | 147 | Case 1 ; Json_OBJECT 148 | Local $Object = Json_ObjCreate() 149 | For $i = 0 To $Size - 1 Step 2 150 | Local $Key = _Json_Token($Json, $Ptr, $Next) 151 | Local $Value = _Json_Token($Json, $Ptr, $Next) 152 | If Not IsString($Key) Then $Key = Json_Encode($Key) 153 | 154 | If $Object.Exists($Key) Then $Object.Remove($Key) 155 | $Object.Add($Key, $Value) 156 | Next 157 | Return $Object 158 | 159 | Case 2 ; Json_ARRAY 160 | Local $Array[$Size] 161 | For $i = 0 To $Size - 1 162 | $Array[$i] = _Json_Token($Json, $Ptr, $Next) 163 | Next 164 | Return $Array 165 | 166 | Case 3 ; Json_STRING 167 | Return Json_StringDecode(StringMid($Json, $Start + 1, $End - $Start)) 168 | EndSwitch 169 | EndFunc ;==>_Json_Token 170 | 171 | Func Json_IsObject(ByRef $Object) 172 | Return (IsObj($Object) And ObjName($Object) = "Dictionary") 173 | EndFunc ;==>Json_IsObject 174 | 175 | Func Json_IsNull(ByRef $Null) 176 | Return IsKeyword($Null) Or (Not IsObj($Null) And VarGetType($Null) = "Object") 177 | EndFunc ;==>Json_IsNull 178 | 179 | Func Json_Encode_Compact($Data, $Option = 0) 180 | Local $Json = "" 181 | 182 | Select 183 | Case IsString($Data) 184 | Return '"' & Json_StringEncode($Data, $Option) & '"' 185 | 186 | Case IsNumber($Data) 187 | Return $Data 188 | 189 | Case IsArray($Data) And UBound($Data, 0) = 1 190 | $Json = "[" 191 | For $i = 0 To UBound($Data) - 1 192 | $Json &= Json_Encode_Compact($Data[$i], $Option) & "," 193 | Next 194 | If StringRight($Json, 1) = "," Then $Json = StringTrimRight($Json, 1) 195 | Return $Json & "]" 196 | 197 | Case Json_IsObject($Data) 198 | $Json = "{" 199 | Local $Keys = $Data.Keys() 200 | For $i = 0 To UBound($Keys) - 1 201 | $Json &= '"' & Json_StringEncode($Keys[$i], $Option) & '":' & Json_Encode_Compact($Data.Item($Keys[$i]), $Option) & "," 202 | Next 203 | If StringRight($Json, 1) = "," Then $Json = StringTrimRight($Json, 1) 204 | Return $Json & "}" 205 | 206 | Case IsBool($Data) 207 | Return StringLower($Data) 208 | 209 | Case IsPtr($Data) 210 | Return Number($Data) 211 | 212 | Case IsBinary($Data) 213 | Return '"' & Json_StringEncode(BinaryToString($Data, 4), $Option) & '"' 214 | 215 | Case Else ; Keyword, DllStruct, Object 216 | Return "null" 217 | EndSelect 218 | EndFunc ;==>Json_Encode_Compact 219 | 220 | Func Json_Encode_Pretty($Data, $Option, $Indent, $ArraySep, $ObjectSep, $ColonSep, $ArrayCRLF = Default, $ObjectCRLF = Default, $NextIdent = "") 221 | Local $ThisIdent = $NextIdent, $Json = "", $String = "", $Match = "", $Keys = "" 222 | Local $Length = 0 223 | 224 | Select 225 | Case IsString($Data) 226 | $String = Json_StringEncode($Data, $Option) 227 | If BitAND($Option, $JSON_UNQUOTED_STRING) And Not BitAND($Option, $JSON_STRICT_PRINT) And Not StringRegExp($String, "[\s,:]") And Not StringRegExp($String, "^[+\-0-9]") Then 228 | Return $String 229 | Else 230 | Return '"' & $String & '"' 231 | EndIf 232 | 233 | Case IsArray($Data) And UBound($Data, 0) = 1 234 | If UBound($Data) = 0 Then Return "[]" 235 | If IsKeyword($ArrayCRLF) Then 236 | $ArrayCRLF = "" 237 | $Match = StringRegExp($ArraySep, "[\r\n]+$", 3) 238 | If IsArray($Match) Then $ArrayCRLF = $Match[0] 239 | EndIf 240 | 241 | If $ArrayCRLF Then $NextIdent &= $Indent 242 | $Length = UBound($Data) - 1 243 | For $i = 0 To $Length 244 | If $ArrayCRLF Then $Json &= $NextIdent 245 | $Json &= Json_Encode_Pretty($Data[$i], $Option, $Indent, $ArraySep, $ObjectSep, $ColonSep, $ArrayCRLF, $ObjectCRLF, $NextIdent) 246 | If $i < $Length Then $Json &= $ArraySep 247 | Next 248 | 249 | If $ArrayCRLF Then Return "[" & $ArrayCRLF & $Json & $ArrayCRLF & $ThisIdent & "]" 250 | Return "[" & $Json & "]" 251 | 252 | Case Json_IsObject($Data) 253 | If $Data.Count = 0 Then Return "{}" 254 | If IsKeyword($ObjectCRLF) Then 255 | $ObjectCRLF = "" 256 | $Match = StringRegExp($ObjectSep, "[\r\n]+$", 3) 257 | If IsArray($Match) Then $ObjectCRLF = $Match[0] 258 | EndIf 259 | 260 | If $ObjectCRLF Then $NextIdent &= $Indent 261 | $Keys = $Data.Keys() 262 | $Length = UBound($Keys) - 1 263 | For $i = 0 To $Length 264 | If $ObjectCRLF Then $Json &= $NextIdent 265 | $Json &= Json_Encode_Pretty(String($Keys[$i]), $Option, $Indent, $ArraySep, $ObjectSep, $ColonSep) & $ColonSep _ 266 | & Json_Encode_Pretty($Data.Item($Keys[$i]), $Option, $Indent, $ArraySep, $ObjectSep, $ColonSep, $ArrayCRLF, $ObjectCRLF, $NextIdent) 267 | If $i < $Length Then $Json &= $ObjectSep 268 | Next 269 | 270 | If $ObjectCRLF Then Return "{" & $ObjectCRLF & $Json & $ObjectCRLF & $ThisIdent & "}" 271 | Return "{" & $Json & "}" 272 | 273 | Case Else 274 | Return Json_Encode_Compact($Data, $Option) 275 | 276 | EndSelect 277 | EndFunc ;==>Json_Encode_Pretty 278 | 279 | Func Json_Encode($Data, $Option = 0, $Indent = Default, $ArraySep = Default, $ObjectSep = Default, $ColonSep = Default) 280 | If BitAND($Option, $JSON_PRETTY_PRINT) Then 281 | Local $Strict = BitAND($Option, $JSON_STRICT_PRINT) 282 | 283 | If IsKeyword($Indent) Then 284 | $Indent = @TAB 285 | Else 286 | $Indent = Json_StringDecode($Indent) 287 | If StringRegExp($Indent, "[^\t ]") Then $Indent = @TAB 288 | EndIf 289 | 290 | If IsKeyword($ArraySep) Then 291 | $ArraySep = "," & @CRLF 292 | Else 293 | $ArraySep = Json_StringDecode($ArraySep) 294 | If $ArraySep = "" Or StringRegExp($ArraySep, "[^\s,]|,.*,") Or ($Strict And Not StringRegExp($ArraySep, ",")) Then $ArraySep = "," & @CRLF 295 | EndIf 296 | 297 | If IsKeyword($ObjectSep) Then 298 | $ObjectSep = "," & @CRLF 299 | Else 300 | $ObjectSep = Json_StringDecode($ObjectSep) 301 | If $ObjectSep = "" Or StringRegExp($ObjectSep, "[^\s,]|,.*,") Or ($Strict And Not StringRegExp($ObjectSep, ",")) Then $ObjectSep = "," & @CRLF 302 | EndIf 303 | 304 | If IsKeyword($ColonSep) Then 305 | $ColonSep = ": " 306 | Else 307 | $ColonSep = Json_StringDecode($ColonSep) 308 | If $ColonSep = "" Or StringRegExp($ColonSep, "[^\s,:]|[,:].*[,:]") Or ($Strict And (StringRegExp($ColonSep, ",") Or Not StringRegExp($ColonSep, ":"))) Then $ColonSep = ": " 309 | EndIf 310 | 311 | Return Json_Encode_Pretty($Data, $Option, $Indent, $ArraySep, $ObjectSep, $ColonSep) 312 | 313 | ElseIf BitAND($Option, $JSON_UNQUOTED_STRING) Then 314 | Return Json_Encode_Pretty($Data, $Option, "", ",", ",", ":") 315 | Else 316 | Return Json_Encode_Compact($Data, $Option) 317 | EndIf 318 | EndFunc ;==>Json_Encode 319 | 320 | Func Json_ObjCreate() 321 | Local $Object = ObjCreate('Scripting.Dictionary') 322 | $Object.CompareMode = 0 323 | Return $Object 324 | EndFunc ;==>Json_ObjCreate 325 | 326 | Func Json_ObjPut(ByRef $Object, $Key, $Value) 327 | $Key = String($Key) 328 | If $Object.Exists($Key) Then $Object.Remove($Key) 329 | $Object.Add($Key, $Value) 330 | EndFunc ;==>Json_ObjPut 331 | 332 | Func Json_ObjGet(ByRef $Object, $Key) 333 | Local $DynObject = $Object 334 | Local $Keys = StringSplit($Key, ".") 335 | For $x = 1 To $Keys[0] 336 | If $DynObject.Exists($Keys[$x]) Then 337 | If $x = $Keys[0] Then 338 | Return $DynObject.Item($Keys[$x]) 339 | Else 340 | $DynObject = Json_ObjGet($DynObject, $Keys[$x]) 341 | EndIf 342 | EndIf 343 | Next 344 | Return SetError(1, 0, '') 345 | EndFunc ;==>Json_ObjGet 346 | 347 | Func Json_ObjDelete(ByRef $Object, $Key) 348 | $Key = String($Key) 349 | If $Object.Exists($Key) Then $Object.Remove($Key) 350 | EndFunc ;==>Json_ObjDelete 351 | 352 | Func Json_ObjExists(ByRef $Object, $Key) 353 | Local $DynObject = $Object 354 | Local $Keys = StringSplit($Key, ".") 355 | For $x = 1 To $Keys[0] 356 | If $DynObject.Exists($Keys[$x]) Then 357 | If $x = $Keys[0] Then 358 | Return True 359 | Else 360 | $DynObject = Json_ObjGet($DynObject, $Keys[$x]) 361 | EndIf 362 | Else 363 | Return False 364 | EndIf 365 | Next 366 | Return False 367 | EndFunc ;==>Json_ObjExists 368 | 369 | Func Json_ObjGetCount(ByRef $Object) 370 | Return $Object.Count 371 | EndFunc ;==>Json_ObjGetCount 372 | 373 | Func Json_ObjGetKeys(ByRef $Object) 374 | Return $Object.Keys() 375 | EndFunc ;==>Json_ObjGetKeys 376 | 377 | Func Json_ObjGetItems(ByRef $Object) 378 | Return $Object.Items() 379 | EndFunc ;==>Json_ObjGetItems 380 | 381 | Func Json_ObjClear(ByRef $Object) 382 | Return $Object.RemoveAll() 383 | EndFunc ;==>Json_ObjClear 384 | 385 | ; Both dot notation and square bracket notation can be supported 386 | Func Json_Put(ByRef $Var, $Notation, $Data, $CheckExists = False) 387 | Local $Ret = 0, $Item = "", $Error = 0 388 | Local $Match = "" 389 | 390 | $Match = StringRegExp($Notation, "(^\[([^\]]+)\])|(^\.([^\.\[]+))", 3) 391 | If IsArray($Match) Then 392 | Local $Index 393 | If UBound($Match) = 4 Then 394 | $Index = String(Json_Decode($Match[3])) ; only string using dot notation 395 | $Notation = StringTrimLeft($Notation, StringLen($Match[2])) 396 | Else 397 | $Index = Json_Decode($Match[1]) 398 | $Notation = StringTrimLeft($Notation, StringLen($Match[0])) 399 | EndIf 400 | 401 | If IsString($Index) Then 402 | If $CheckExists And (Not Json_IsObject($Var) Or Not Json_ObjExists($Var, $Index)) Then 403 | Return SetError(1, 0, False) ; no specific object 404 | EndIf 405 | 406 | If Not Json_IsObject($Var) Then $Var = Json_ObjCreate() 407 | If $Notation Then 408 | $Item = Json_ObjGet($Var, $Index) 409 | $Ret = Json_Put($Item, $Notation, $Data, $CheckExists) 410 | $Error = @error 411 | If Not $Error Then Json_ObjPut($Var, $Index, $Item) 412 | Return SetError($Error, 0, $Ret) 413 | Else 414 | Json_ObjPut($Var, $Index, $Data) 415 | Return True 416 | EndIf 417 | 418 | ElseIf IsInt($Index) Then 419 | If $Index < 0 Or ($CheckExists And (Not IsArray($Var) Or UBound($Var, 0) <> 1 Or $Index >= UBound($Var))) Then 420 | Return SetError(1, 0, False) ; no specific object 421 | EndIf 422 | 423 | If Not IsArray($Var) Or UBound($Var, 0) <> 1 Then 424 | Dim $Var[$Index + 1] 425 | ElseIf $Index >= UBound($Var) Then 426 | ReDim $Var[$Index + 1] 427 | EndIf 428 | 429 | If $Notation Then 430 | $Ret = Json_Put($Var[$Index], $Notation, $Data, $CheckExists) 431 | Return SetError(@error, 0, $Ret) 432 | Else 433 | $Var[$Index] = $Data 434 | Return True 435 | EndIf 436 | 437 | EndIf 438 | EndIf 439 | Return SetError(2, 0, False) ; invalid notation 440 | EndFunc ;==>Json_Put 441 | 442 | ; Both dot notation and square bracket notation can be supported 443 | Func Json_Get(ByRef $Var, $Notation) 444 | Local $Match = StringRegExp($Notation, "(^\[([^\]]+)\])|(^\.([^\.\[]+))", 3) 445 | If IsArray($Match) Then 446 | Local $Index 447 | If UBound($Match) = 4 Then 448 | $Index = String(Json_Decode($Match[3])) ; only string using dot notation 449 | $Notation = StringTrimLeft($Notation, StringLen($Match[2])) 450 | Else 451 | $Index = Json_Decode($Match[1]) 452 | $Notation = StringTrimLeft($Notation, StringLen($Match[0])) 453 | EndIf 454 | 455 | Local $Item 456 | If IsString($Index) And Json_IsObject($Var) And Json_ObjExists($Var, $Index) Then 457 | $Item = Json_ObjGet($Var, $Index) 458 | ElseIf IsInt($Index) And IsArray($Var) And UBound($Var, 0) = 1 And $Index >= 0 And $Index < UBound($Var) Then 459 | $Item = $Var[$Index] 460 | Else 461 | Return SetError(1, 0, "") ; no specific object 462 | EndIf 463 | 464 | If Not $Notation Then Return $Item 465 | Local $Ret = Json_Get($Item, $Notation) 466 | Return SetError(@error, 0, $Ret) 467 | EndIf 468 | Return SetError(2, 0, "") ; invalid notation 469 | EndFunc ;==>Json_Get 470 | 471 | ; List all JSON keys and their value to the Console 472 | Func Json_Dump($Json, $InitTokenCount = 1000) 473 | Static $Jsmn_Init = __Jsmn_RuntimeLoader("jsmn_init"), $Jsmn_Parse = __Jsmn_RuntimeLoader("jsmn_parse") 474 | If $Json = "" Then $Json = '""' 475 | Local $TokenList, $Ret 476 | $Total_JSON_DUMP_Output = "" ; reset totaldump variable at the start of the dump process (Use for testing) 477 | Local $Parser = DllStructCreate("uint pos;int toknext;int toksuper") 478 | Do 479 | DllCallAddress("none:cdecl", $Jsmn_Init, "ptr", DllStructGetPtr($Parser)) 480 | $TokenList = DllStructCreate("byte[" & ($InitTokenCount * 20) & "]") 481 | $Ret = DllCallAddress("int:cdecl", $Jsmn_Parse, "ptr", DllStructGetPtr($Parser), "wstr", $Json, "ptr", DllStructGetPtr($TokenList), "uint", $InitTokenCount) 482 | $InitTokenCount *= 2 483 | Until $Ret[0] <> $JSMN_ERROR_NOMEM 484 | 485 | Local $Next = 0 486 | _Json_TokenDump($Json, DllStructGetPtr($TokenList), $Next) 487 | EndFunc ;==>Json_Dump 488 | 489 | Func _Json_TokenDump(ByRef $Json, $Ptr, ByRef $Next, $ObjPath = "") 490 | If $Next = -1 Then Return Null 491 | 492 | Local $Token = DllStructCreate("int;int;int;int", $Ptr + ($Next * 20)) 493 | Local $Type = DllStructGetData($Token, 1) 494 | Local $Start = DllStructGetData($Token, 2) 495 | Local $End = DllStructGetData($Token, 3) 496 | Local $Size = DllStructGetData($Token, 4) 497 | Local $Value 498 | $Next += 1 499 | 500 | If $Type = 0 And $Start = 0 And $End = 0 And $Size = 0 Then ; Null Item 501 | $Next = -1 502 | Return Null 503 | EndIf 504 | 505 | Switch $Type 506 | Case 0 ; Json_PRIMITIVE 507 | Local $Primitive = StringMid($Json, $Start + 1, $End - $Start) 508 | Switch $Primitive 509 | Case "true" 510 | Return "True" 511 | Case "false" 512 | Return "False" 513 | Case "null" 514 | Return "Null" 515 | Case Else 516 | If StringRegExp($Primitive, "^[+\-0-9]") Then 517 | Return Number($Primitive) 518 | Else 519 | Return Json_StringDecode($Primitive) 520 | EndIf 521 | EndSwitch 522 | 523 | Case 1 ; Json_OBJECT 524 | For $i = 0 To $Size - 1 Step 2 525 | Local $Key = _Json_TokenDump($Json, $Ptr, $Next) 526 | Local $cObjPath = $ObjPath & "." & $Key 527 | $Value = _Json_TokenDump($Json, $Ptr, $Next, $ObjPath & "." & $Key) 528 | If Not (IsBool($Value) And $Value = False) Then 529 | If Not IsString($Key) Then 530 | $Key = Json_Encode($Key) 531 | EndIf 532 | ; show the key and its value 533 | ConsoleWrite("+-> " & $cObjPath & ' =' & $Value & @CRLF) 534 | $Total_JSON_DUMP_Output &= "+-> " & $cObjPath & ' =' & $Value & @CRLF 535 | EndIf 536 | Next 537 | Return False 538 | Case 2 ; Json_ARRAY 539 | Local $sObjPath = $ObjPath 540 | For $i = 0 To $Size - 1 541 | $sObjPath = $ObjPath & "[" & $i & "]" 542 | $Value = _Json_TokenDump($Json, $Ptr, $Next, $sObjPath) 543 | If Not (IsBool($Value) And $Value = False) Then ;XC - Changed line 544 | ; show the key and its value 545 | ConsoleWrite("+=> " & $sObjPath & "=>" & $Value & @CRLF) 546 | $Total_JSON_DUMP_Output &= "+=> " & $sObjPath & "=>" & $Value & @CRLF 547 | EndIf 548 | Next 549 | $ObjPath = $sObjPath 550 | Return False 551 | 552 | Case 3 ; Json_STRING 553 | Local $LastKey = Json_StringDecode(StringMid($Json, $Start + 1, $End - $Start)) 554 | Return $LastKey 555 | EndSwitch 556 | EndFunc ;==>_Json_TokenDump 557 | --------------------------------------------------------------------------------