| 1000 | } |
| 1001 | |
| 1002 | ResultType Hotkey::Dynamic(LPTSTR aHotkeyName, LPTSTR aOptions, IObject *aCallback, HookActionType aHookAction, ResultToken &aResultToken) |
| 1003 | // Creates, updates, enables, or disables a hotkey dynamically (while the script is running). |
| 1004 | // Returns OK or FAIL. |
| 1005 | { |
| 1006 | // Caller has ensured that aCallback and aHookAction can't both be non-zero. Furthermore, |
| 1007 | // both can be zero/NULL only when the caller is updating an existing hotkey to have new options |
| 1008 | // (i.e. it's retaining its current callback). |
| 1009 | if (aCallback) |
| 1010 | { |
| 1011 | if (!ValidateFunctor(aCallback, 1, aResultToken)) |
| 1012 | return FAIL; |
| 1013 | } |
| 1014 | |
| 1015 | bool suffix_has_tilde, hook_is_mandatory; |
| 1016 | Hotkey *hk = FindHotkeyByTrueNature(aHotkeyName, suffix_has_tilde, hook_is_mandatory); // NULL if not found. |
| 1017 | HotkeyVariant *variant = hk ? hk->FindVariant() : NULL; |
| 1018 | bool update_all_hotkeys = false; // This method avoids multiple calls to ManifestAllHotkeysHotstringsHooks() (which is high-overhead). |
| 1019 | bool variant_was_just_created = false; |
| 1020 | |
| 1021 | switch (aHookAction) |
| 1022 | { |
| 1023 | case HOTKEY_ID_ON: |
| 1024 | case HOTKEY_ID_OFF: |
| 1025 | case HOTKEY_ID_TOGGLE: |
| 1026 | if (!hk) |
| 1027 | return aResultToken.Error(ERR_NONEXISTENT_HOTKEY, aHotkeyName, ErrorPrototype::Target); |
| 1028 | if (!(variant || hk->mHookAction)) // mHookAction (alt-tab) hotkeys don't need a variant that matches the current criteria. |
| 1029 | // To avoid ambiguity and also allow the script to use error handling to detect whether a variant |
| 1030 | // already exists, it seems best to strictly require a matching variant rather than falling back |
| 1031 | // onto some "default variant" such as the global variant (if any). |
| 1032 | return aResultToken.Error(ERR_NONEXISTENT_VARIANT, aHotkeyName, ErrorPrototype::Target); |
| 1033 | if (aHookAction == HOTKEY_ID_TOGGLE) |
| 1034 | aHookAction = hk->mHookAction |
| 1035 | ? (hk->mParentEnabled ? HOTKEY_ID_OFF : HOTKEY_ID_ON) // Enable/disable parent hotkey (due to alt-tab being a global hotkey). |
| 1036 | : (variant->mEnabled ? HOTKEY_ID_OFF : HOTKEY_ID_ON); // Enable/disable individual variant. |
| 1037 | if (aHookAction == HOTKEY_ID_ON) |
| 1038 | { |
| 1039 | if (hk->mHookAction ? hk->EnableParent() : hk->Enable(*variant)) |
| 1040 | update_all_hotkeys = true; // Do it this way so that any previous "true" value isn't lost. |
| 1041 | } |
| 1042 | else |
| 1043 | if (hk->mHookAction ? hk->DisableParent() : hk->Disable(*variant)) |
| 1044 | update_all_hotkeys = true; // Do it this way so that any previous "true" value isn't lost. |
| 1045 | break; |
| 1046 | |
| 1047 | default: // aHookAction is 0 or an AltTab action. COMMAND: Hotkey, Name, Callback|AltTabAction |
| 1048 | if (!hk) // No existing hotkey of this name, so create a new hotkey. |
| 1049 | { |
| 1050 | if (aHookAction) // Create hotkey: Hotkey Name, AltTabAction |
| 1051 | hk = AddHotkey(NULL, aHookAction, aHotkeyName, suffix_has_tilde); |
| 1052 | else // Create hotkey: Hotkey Name, Callback [, Options] |
| 1053 | { |
| 1054 | if (!aCallback) // Caller is trying to set new aOptions for a nonexistent hotkey. |
| 1055 | return aResultToken.Error(ERR_NONEXISTENT_HOTKEY, aHotkeyName, ErrorPrototype::Target); |
| 1056 | hk = AddHotkey(aCallback, 0, aHotkeyName, suffix_has_tilde); |
| 1057 | } |
| 1058 | if (!hk) |
| 1059 | return FAIL; // AddHotkey() already displayed the error. |
nothing calls this directly
no test coverage detected