"Fossies" - the Fresh Open Source Software Archive

Member "AutoHotkey_L-1.1.33.09/source/input_object.cpp" (8 May 2021, 6886 Bytes) of package /windows/misc/AutoHotkey_L-1.1.33.09.zip:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "input_object.cpp" see the Fossies "Dox" file reference documentation.

    1 #include "stdafx.h" // pre-compiled headers
    2 #include "defines.h"
    3 #include "globaldata.h"
    4 #include "script.h"
    5 #include "application.h"
    6 
    7 #include "script_object.h"
    8 #include "script_func_impl.h"
    9 #include "input_object.h"
   10 
   11 
   12 BIF_DECL(BIF_InputHook)
   13 {
   14     auto *input_handle = new InputObject();
   15 
   16     _f_param_string_opt(aOptions, 0);
   17     _f_param_string_opt(aEndKeys, 1);
   18     _f_param_string_opt(aMatchList, 2);
   19     
   20     if (!input_handle->Setup(aOptions, aEndKeys, aMatchList, _tcslen(aMatchList)))
   21     {
   22         input_handle->Release();
   23         _f_return_FAIL;
   24     }
   25 
   26     aResultToken.symbol = SYM_OBJECT;
   27     aResultToken.object = input_handle;
   28 }
   29 
   30 
   31 ResultType InputObject::Setup(LPTSTR aOptions, LPTSTR aEndKeys, LPTSTR aMatchList, size_t aMatchList_length)
   32 {
   33     return input.Setup(aOptions, aEndKeys, aMatchList, aMatchList_length);
   34 }
   35 
   36 
   37 ResultType InputObject::Invoke(ExprTokenType &aResultToken, ExprTokenType &aThisToken, int aFlags, ExprTokenType *aParam[], int aParamCount)
   38 {
   39     if (!aParamCount)
   40         _o_throw(ERR_INVALID_USAGE);
   41 
   42     LPTSTR name = TokenToString(*aParam[0]);
   43     
   44     if (IS_INVOKE_CALL)
   45     {
   46         if (!_tcsicmp(name, _T("Start")))
   47         {
   48             if (input.InProgress())
   49                 return OK;
   50             input.Buffer[input.BufferLength = 0] = '\0';
   51             return InputStart(input);
   52         }
   53         else if (!_tcsicmp(name, _T("Wait")))
   54         {
   55             UINT wait_ms = ParamIndexIsOmitted(1) ? UINT_MAX : (UINT)(ParamIndexToDouble(1) * 1000);
   56             DWORD tick_start = GetTickCount();
   57             while (input.InProgress() && (GetTickCount() - tick_start) < wait_ms)
   58                 MsgSleep();
   59             aResultToken.symbol = SYM_STRING;
   60             aResultToken.marker = input.GetEndReason(NULL, 0, false);
   61             return OK;
   62         }
   63         else if (!_tcsicmp(name, _T("Stop")))
   64         {
   65             if (input.InProgress())
   66                 input.Stop();
   67             return OK;
   68         }
   69         else if (!_tcsicmp(name, _T("KeyOpt")))
   70         {
   71             return KeyOpt(aResultToken, aParam + 1, aParamCount - 1);
   72         }
   73         return INVOKE_NOT_HANDLED;
   74     }
   75 
   76     if (aParamCount != (IS_INVOKE_SET ? 2 : 1))
   77         _o_throw(ERR_INVALID_USAGE);
   78 
   79     if (IS_INVOKE_GET)
   80     {
   81         if (!_tcsicmp(name, _T("Input")))
   82         {
   83             aResultToken.symbol = SYM_STRING;
   84             return TokenSetResult(aResultToken, input.Buffer, input.BufferLength);
   85         }
   86         else if (!_tcsicmp(name, _T("InProgress")))
   87         {
   88             aResultToken.symbol = SYM_INTEGER;
   89             aResultToken.value_int64 = input.InProgress();
   90             return OK;
   91         }
   92         else if (!_tcsicmp(name, _T("EndReason")))
   93         {
   94             aResultToken.symbol = SYM_STRING;
   95             aResultToken.marker = input.GetEndReason(NULL, 0, false);
   96             return OK;
   97         }
   98         else if (!_tcsicmp(name, _T("EndKey")))
   99         {
  100             aResultToken.symbol = SYM_STRING;
  101             if (input.Status == INPUT_TERMINATED_BY_ENDKEY)
  102                 input.GetEndReason(aResultToken.marker = _f_retval_buf, _f_retval_buf_size, false);
  103             else
  104                 aResultToken.marker = _T("");
  105             return OK;
  106         }
  107         else if (!_tcsicmp(name, _T("EndMods")))
  108         {
  109             aResultToken.symbol = SYM_STRING;
  110             TCHAR *cp = aResultToken.marker = aResultToken.buf;
  111             const auto mod_string = MODLR_STRING;
  112             for (int i = 0; i < 8; ++i)
  113                 if (input.EndingMods & (1 << i))
  114                 {
  115                     *cp++ = mod_string[i*2];
  116                     *cp++ = mod_string[i*2+1];
  117                 }
  118             *cp = '\0';
  119             return OK;
  120         }
  121         else if (!_tcsicmp(name, _T("Match")))
  122         {
  123             aResultToken.symbol = SYM_STRING;
  124             if (input.Status == INPUT_TERMINATED_BY_MATCH && input.EndingMatchIndex < input.MatchCount)
  125                 aResultToken.marker = input.match[input.EndingMatchIndex];
  126             else
  127                 aResultToken.marker = _T("");
  128             return OK;
  129         }
  130     }
  131     if (!_tcsnicmp(name, _T("On"), 2))
  132     {
  133         IObject **pon;
  134         if (!_tcsicmp(name + 2, _T("End")))
  135             pon = &onEnd;
  136         else if (!_tcsicmp(name + 2, _T("KeyDown")))
  137             pon = &onKeyDown;
  138         else if (!_tcsicmp(name + 2, _T("KeyUp")))
  139             pon = &onKeyUp;
  140         else if (!_tcsicmp(name + 2, _T("Char")))
  141             pon = &onChar;
  142         else
  143             return INVOKE_NOT_HANDLED;
  144 
  145         if (IS_INVOKE_SET)
  146         {
  147             IObject *obj = ParamIndexToObject(1);
  148             if (obj)
  149                 obj->AddRef();
  150             else if (!TokenIsEmptyString(*aParam[1]))
  151                 _o_throw(ERR_INVALID_VALUE);
  152             if (*pon)
  153                 (*pon)->Release();
  154             *pon = obj;
  155         }
  156         if (*pon)
  157         {
  158             (*pon)->AddRef();
  159             aResultToken.SetValue(*pon);
  160         }
  161         return OK;
  162     }
  163     // OPTIONS
  164     bool *bool_option = NULL;
  165     if (!_tcsicmp(name, _T("MinSendLevel")))
  166     {
  167         if (IS_INVOKE_SET)
  168             input.MinSendLevel = (SendLevelType)ParamIndexToInt64(1);
  169         aResultToken.SetValue(input.MinSendLevel);
  170         return OK;
  171     }
  172     else if (!_tcsicmp(name, _T("Timeout")))
  173     {
  174         if (IS_INVOKE_SET)
  175         {
  176             input.Timeout = (int)(ParamIndexToDouble(1) * 1000);
  177             if (input.InProgress() && input.Timeout > 0)
  178                 input.SetTimeoutTimer();
  179         }
  180         aResultToken.SetValue(input.Timeout / 1000.0);
  181         return OK;
  182     }
  183     else if (!_tcsicmp(name, _T("BackspaceIsUndo"))) bool_option = &input.BackspaceIsUndo;
  184     else if (!_tcsicmp(name, _T("CaseSensitive"))) bool_option = &input.CaseSensitive;
  185     else if (!_tcsicmp(name, _T("FindAnywhere"))) bool_option = &input.FindAnywhere;
  186     else if (!_tcsicmp(name, _T("VisibleText"))) bool_option = &input.VisibleText;
  187     else if (!_tcsicmp(name, _T("VisibleNonText"))) bool_option = &input.VisibleNonText;
  188     else if (!_tcsicmp(name, _T("NotifyNonText"))) bool_option = &input.NotifyNonText;
  189     if (bool_option)
  190     {
  191         if (IS_INVOKE_SET)
  192             *bool_option = ParamIndexToBOOL(1);
  193         aResultToken.SetValue(*bool_option);
  194         return OK;
  195     }
  196     return INVOKE_NOT_HANDLED;
  197 }
  198 
  199 
  200 ResultType InputObject::KeyOpt(ExprTokenType &aResultToken, ExprTokenType *aParam[], int aParamCount)
  201 {
  202     if (aParamCount < 2)
  203         _o_throw(ERR_TOO_FEW_PARAMS);
  204 
  205     _f_param_string(keys, 0);
  206     _f_param_string(options, 1);
  207 
  208     bool adding = true;
  209     UCHAR flag, add_flags = 0, remove_flags = 0;
  210     for (LPTSTR cp = options; *cp; ++cp)
  211     {
  212         switch (ctoupper(*cp))
  213         {
  214         case '+': adding = true; continue;
  215         case '-': adding = false; continue;
  216         case ' ': case '\t': continue;
  217         case 'E': flag = END_KEY_ENABLED; break;
  218         case 'I': flag = INPUT_KEY_IGNORE_TEXT; break;
  219         case 'N': flag = INPUT_KEY_NOTIFY; break;
  220         case 'S':
  221             flag = INPUT_KEY_SUPPRESS;
  222             if (adding)
  223                 remove_flags |= INPUT_KEY_VISIBLE;
  224             break;
  225         case 'V':
  226             flag = INPUT_KEY_VISIBLE;
  227             if (adding)
  228                 remove_flags |= INPUT_KEY_SUPPRESS;
  229             break;
  230         case 'Z': // Zero (reset)
  231             add_flags = 0;
  232             remove_flags = INPUT_KEY_OPTION_MASK;
  233             continue;
  234         default: _o_throw(ERR_INVALID_OPTION, cp);
  235         }
  236         if (adding)
  237             add_flags |= flag; // Add takes precedence over remove, so remove_flags isn't changed.
  238         else
  239         {
  240             remove_flags |= flag;
  241             add_flags &= ~flag; // Override any previous add.
  242         }
  243     }
  244     
  245     if (!_tcsicmp(keys, _T("{All}")))
  246     {
  247         // Could optimize by using memset() when remove_flags == 0xFF, but that doesn't seem
  248         // worthwhile since this mode is already faster than SetKeyFlags() with a single key.
  249         for (int i = 0; i < _countof(input.KeyVK); ++i)
  250             input.KeyVK[i] = (input.KeyVK[i] & ~remove_flags) | add_flags;
  251         for (int i = 0; i < _countof(input.KeySC); ++i)
  252             input.KeySC[i] = (input.KeySC[i] & ~remove_flags) | add_flags;
  253         return OK;
  254     }
  255 
  256     return input.SetKeyFlags(keys, false, remove_flags, add_flags);
  257 }