| 413 | |
| 414 | |
| 415 | ResultType input_type::SetKeyFlags(LPTSTR aKeys, bool aEndKeyMode, UCHAR aFlagsRemove, UCHAR aFlagsAdd) |
| 416 | { |
| 417 | bool vk_by_number, sc_by_number; |
| 418 | vk_type vk; |
| 419 | sc_type sc = 0; |
| 420 | modLR_type modifiersLR; |
| 421 | size_t key_text_length; |
| 422 | UINT single_char_count = 0; |
| 423 | TCHAR *end_pos, single_char_string[2]; |
| 424 | single_char_string[1] = '\0'; // Init its second character once, since the loop only changes the first char. |
| 425 | |
| 426 | const bool endchar_mode = aEndKeyMode && EndCharMode; |
| 427 | UCHAR * const end_vk = KeyVK; |
| 428 | UCHAR * const end_sc = KeySC; |
| 429 | |
| 430 | for (TCHAR *end_key = aKeys; *end_key; ++end_key) // This a modified version of the processing loop used in SendKeys(). |
| 431 | { |
| 432 | vk = 0; // Set default. Not strictly necessary but more maintainable. |
| 433 | *single_char_string = '\0'; // Set default as "this key name is not a single-char string". |
| 434 | |
| 435 | switch (*end_key) |
| 436 | { |
| 437 | case '}': continue; // Important that these be ignored. |
| 438 | case '{': |
| 439 | { |
| 440 | if ( !(end_pos = _tcschr(end_key + 1, '}')) ) |
| 441 | continue; // Do nothing, just ignore the unclosed '{' and continue. |
| 442 | if ( !(key_text_length = end_pos - end_key - 1) ) |
| 443 | { |
| 444 | if (end_pos[1] == '}') // The string "{}}" has been encountered, which is interpreted as a single "}". |
| 445 | { |
| 446 | ++end_pos; |
| 447 | key_text_length = 1; |
| 448 | } |
| 449 | else // Empty braces {} were encountered. |
| 450 | continue; // do nothing: let it proceed to the }, which will then be ignored. |
| 451 | } |
| 452 | if (key_text_length == 1) // A single-char key name, such as {.} or {{}. |
| 453 | { |
| 454 | if (endchar_mode) // Handle this single-char key name by char code, not by VK. |
| 455 | { |
| 456 | // Although it might be sometimes useful to treat "x" as a character and "{x}" as a key, |
| 457 | // "{{}" and "{}}" can't be included without the extra braces. {vkNN} can still be used |
| 458 | // to handle the key by VK instead of by character. |
| 459 | single_char_count++; |
| 460 | continue; // It will be processed by another section. |
| 461 | } |
| 462 | *single_char_string = end_key[1]; // Only used when vk != 0. |
| 463 | } |
| 464 | |
| 465 | *end_pos = '\0'; // temporarily terminate the string here. |
| 466 | |
| 467 | sc_by_number = false; // Set default. |
| 468 | modifiersLR = 0; // Init prior to below. |
| 469 | // Handle the key by VK if it was given by number, such as {vk26}. |
| 470 | // Otherwise, for any key name which has a VK shared by two possible SCs |
| 471 | // (such as Up and NumpadUp), handle it by SC so it's identified correctly. |
| 472 | if (vk = TextToVK(end_key + 1, &modifiersLR, true)) |