| 2565 | |
| 2566 | |
| 2567 | BIF_DECL(BIF_Hotstring) |
| 2568 | { |
| 2569 | aResultToken.symbol = SYM_STRING; |
| 2570 | aResultToken.marker = _T(""); |
| 2571 | |
| 2572 | _f_param_string(name, 0); |
| 2573 | _f_param_string_opt(action, 1); |
| 2574 | _f_param_string_opt(onoff, 2); |
| 2575 | |
| 2576 | if (!_tcsicmp(name, _T("EndChars"))) // Equivalent to #Hotstring EndChars <action> |
| 2577 | { |
| 2578 | TokenSetResult(aResultToken, g_EndChars); // Return the old value. |
| 2579 | if (!ParamIndexIsOmitted(1)) |
| 2580 | // There is some concern of a race condition with the hook thread, but since g_EndChars |
| 2581 | // has static storage duration and is therefore zero-initialized at startup (in particular, |
| 2582 | // the last char is always zero), the only consequence would be that some old end chars may |
| 2583 | // be used if a hotstring is evaluated during the tcslcpy() call. |
| 2584 | tcslcpy(g_EndChars, action, _countof(g_EndChars)); |
| 2585 | return; |
| 2586 | } |
| 2587 | else if (!_tcsicmp(name, _T("MouseReset"))) // "MouseReset, true" seems more intuitive than "NoMouse, false" |
| 2588 | { |
| 2589 | bool previous_value = g_HSResetUponMouseClick; |
| 2590 | if (!ParamIndexIsOmitted(1)) |
| 2591 | { |
| 2592 | g_HSResetUponMouseClick = ParamIndexToBOOL(1); |
| 2593 | if (g_HSResetUponMouseClick != previous_value && Hotstring::sEnabledCount) // No need if there aren't any hotstrings. |
| 2594 | Hotkey::ManifestAllHotkeysHotstringsHooks(); // Install the hook if needed, or uninstall if no longer needed. |
| 2595 | } |
| 2596 | aResultToken.symbol = SYM_INTEGER; |
| 2597 | aResultToken.value_int64 = previous_value; |
| 2598 | return; |
| 2599 | } |
| 2600 | else if (!_tcsicmp(name, _T("Reset"))) |
| 2601 | { |
| 2602 | *g_HSBuf = '\0'; |
| 2603 | g_HSBufLength = 0; |
| 2604 | return; |
| 2605 | } |
| 2606 | else if (aParamCount == 1 && *name != ':') // Equivalent to #Hotstring <name> |
| 2607 | { |
| 2608 | // TODO: Build string of current options and return it? |
| 2609 | bool unused_X_option; // 'X' option is required to be passed for each Hotstring() call, for clarity. |
| 2610 | Hotstring::ParseOptions(name, g_HSPriority, g_HSKeyDelay, g_HSSendMode, g_HSCaseSensitive |
| 2611 | , g_HSConformToCase, g_HSDoBackspace, g_HSOmitEndChar, g_HSSendRaw, g_HSEndCharRequired |
| 2612 | , g_HSDetectWhenInsideWord, g_HSDoReset, unused_X_option, g_SuspendExemptHS); |
| 2613 | return; |
| 2614 | } |
| 2615 | |
| 2616 | // Parse the hotstring name (this is similar to a section in LoadIncludedFile()): |
| 2617 | LPTSTR hotstring_start = NULL; |
| 2618 | LPTSTR hotstring_options = _T(""); // Set default as "no options were specified for this hotstring". |
| 2619 | if (name[0] == ':' && name[1]) |
| 2620 | { |
| 2621 | if (name[1] != ':') |
| 2622 | { |
| 2623 | hotstring_options = name + 1; // Point it to the hotstring's option letters. |
| 2624 | // The following relies on the fact that options should never contain a literal colon. |
nothing calls this directly
no test coverage detected