| 10898 | } |
| 10899 | |
| 10900 | bool GuiType::ConvertAccelerator(LPTSTR aString, ACCEL &aAccel) |
| 10901 | { |
| 10902 | aString = omit_leading_whitespace(aString); |
| 10903 | if (!*aString) // Multiple points below rely on this check. |
| 10904 | return false; |
| 10905 | |
| 10906 | // Omitting FVIRTKEY and storing a character code instead of a vk code allows the |
| 10907 | // accelerator to be triggered by Alt+Numpad and perhaps IME or other means. However, |
| 10908 | // testing shows that it also causes the modifier key flags to be ignored, so this |
| 10909 | // approach can only be used if aString is a lone character: |
| 10910 | if (!aString[1]) |
| 10911 | { |
| 10912 | aAccel.key = (WORD)(TBYTE)*aString; |
| 10913 | aAccel.fVirt = 0; |
| 10914 | return true; |
| 10915 | } |
| 10916 | |
| 10917 | aAccel.fVirt = FVIRTKEY; // Init. |
| 10918 | |
| 10919 | modLR_type modLR = 0; |
| 10920 | |
| 10921 | LPTSTR cp; |
| 10922 | while (cp = _tcschr(aString + 1, '+')) // For each modifier. +1 is used in case "+" is the key. |
| 10923 | { |
| 10924 | LPTSTR cp_end = omit_trailing_whitespace(aString, cp - 1); |
| 10925 | size_t len = cp_end - aString + 1; |
| 10926 | if (!_tcsnicmp(aString, _T("Ctrl"), len)) |
| 10927 | modLR |= MOD_LCONTROL; |
| 10928 | else if (!_tcsnicmp(aString, _T("Alt"), len)) |
| 10929 | modLR |= MOD_LALT; |
| 10930 | else if (!_tcsnicmp(aString, _T("Shift"), len)) |
| 10931 | modLR |= MOD_LSHIFT; |
| 10932 | else |
| 10933 | return false; |
| 10934 | aString = omit_leading_whitespace(cp + 1); |
| 10935 | if (!*aString) // Below relies on this check. |
| 10936 | return false; // "Modifier+", but no key name. |
| 10937 | } |
| 10938 | |
| 10939 | // Now that any modifiers have been parsed and removed, convert the key name. |
| 10940 | // If only a single character remains, this may set additional modifiers. |
| 10941 | if (!aString[1]) |
| 10942 | { |
| 10943 | // It seems preferable to treat "Ctrl+O" as ^o and not ^+o, so convert the character |
| 10944 | // to lower-case so that MOD_LSHIFT is added only for keys like "@". Seems best to use |
| 10945 | // the locale-dependent method, though somewhat debatable. |
| 10946 | aAccel.key = CharToVKAndModifiers(ltolower(*aString), &modLR, GetKeyboardLayout(0)); |
| 10947 | } |
| 10948 | else |
| 10949 | aAccel.key = TextToVK(aString); |
| 10950 | |
| 10951 | if (modLR & MOD_LCONTROL) |
| 10952 | aAccel.fVirt |= FCONTROL; |
| 10953 | if (modLR & MOD_LALT) // Not MOD_RALT, which would mean AltGr (unsupported). |
| 10954 | aAccel.fVirt |= FALT; |
| 10955 | if (modLR & MOD_LSHIFT) |
| 10956 | aAccel.fVirt |= FSHIFT; |
| 10957 |
nothing calls this directly
no test coverage detected