#include "LOGIC/Lgc_Func_Button_Private.h" #include #include #include namespace { constexpr DWORD LGC_FUNCTIONBUTTON_KEY_HOLD_DELAY_MS = 12; constexpr DWORD LGC_FUNCTIONBUTTON_SEQUENCE_STEP_DELAY_MS = 60; } // namespace Lgc_FunctionButton_Struct_WindowsKey Lgc_FunctionButton_GetWindowsKey(quint16 Usage) { switch (Usage) { case 0x0053: return { VK_NUMLOCK, 0 }; case 0x0054: return { VK_DIVIDE, KEYEVENTF_EXTENDEDKEY }; case 0x0055: return { VK_MULTIPLY, 0 }; case 0x0056: return { VK_SUBTRACT, 0 }; case 0x0057: return { VK_ADD, 0 }; case 0x0058: return { VK_RETURN, KEYEVENTF_EXTENDEDKEY }; case 0x0059: return { VK_NUMPAD1, 0 }; case 0x005A: return { VK_NUMPAD2, 0 }; case 0x005B: return { VK_NUMPAD3, 0 }; case 0x005C: return { VK_NUMPAD4, 0 }; case 0x005D: return { VK_NUMPAD5, 0 }; case 0x005E: return { VK_NUMPAD6, 0 }; case 0x005F: return { VK_NUMPAD7, 0 }; case 0x0060: return { VK_NUMPAD8, 0 }; case 0x0061: return { VK_NUMPAD9, 0 }; case 0x0062: return { VK_NUMPAD0, 0 }; case 0x0063: return { VK_DECIMAL, 0 }; case 0x00E0: return { VK_CONTROL, 0, true }; case 0x00E1: return { VK_SHIFT, 0, true }; case 0x00E2: return { VK_MENU, 0, true }; case 0x00E3: return { VK_LWIN, 0, true }; case 0x00E4: return { VK_CONTROL, KEYEVENTF_EXTENDEDKEY, true }; case 0x00E5: return { VK_SHIFT, 0, true }; case 0x00E6: return { VK_MENU, KEYEVENTF_EXTENDEDKEY, true }; case 0x00E7: return { VK_RWIN, 0, true }; default: return {}; } } bool Lgc_FunctionButton_SendWindowsKey( const Lgc_FunctionButton_Struct_WindowsKey& Key, bool IsPressed) { if (Key.VirtualKey == 0) { return false; } INPUT InputData = {}; InputData.type = INPUT_KEYBOARD; InputData.ki.wVk = Key.VirtualKey; InputData.ki.dwFlags = Key.ExtraFlags; if (!IsPressed) { InputData.ki.dwFlags |= KEYEVENTF_KEYUP; } return SendInput(1, &InputData, sizeof(INPUT)) == 1; } bool Lgc_FunctionButton_SendKeyCombination( const QVector& KeyList) { QVector ModifierList; QVector NormalKeyList; for (const auto& KeyItem : KeyList) { if (KeyItem.Key.VirtualKey == 0) { return false; } if (KeyItem.Key.IsModifier) { bool IsDuplicate = false; for (const auto& OldModifier : ModifierList) { if (Lgc_FunctionButton_IsSameWindowsKey(OldModifier, KeyItem.Key)) { IsDuplicate = true; break; } } if (!IsDuplicate) { ModifierList.append(KeyItem.Key); } continue; } NormalKeyList.append(KeyItem.Key); } for (int ModifierIndex = 0; ModifierIndex < ModifierList.size(); ++ModifierIndex) { const auto& ModifierKey = ModifierList.at(ModifierIndex); if (!Lgc_FunctionButton_SendWindowsKey(ModifierKey, true)) { for (int Index = ModifierIndex - 1; Index >= 0; --Index) { Lgc_FunctionButton_SendWindowsKey(ModifierList.at(Index), false); } return false; } Sleep(LGC_FUNCTIONBUTTON_KEY_HOLD_DELAY_MS); } if (NormalKeyList.isEmpty()) { for (int Index = ModifierList.size() - 1; Index >= 0; --Index) { if (!Lgc_FunctionButton_SendWindowsKey(ModifierList.at(Index), false)) { return false; } Sleep(LGC_FUNCTIONBUTTON_KEY_HOLD_DELAY_MS); } return !ModifierList.isEmpty(); } for (const auto& NormalKey : NormalKeyList) { if (!Lgc_FunctionButton_SendWindowsKey(NormalKey, true)) { for (int Index = ModifierList.size() - 1; Index >= 0; --Index) { Lgc_FunctionButton_SendWindowsKey(ModifierList.at(Index), false); } return false; } Sleep(LGC_FUNCTIONBUTTON_KEY_HOLD_DELAY_MS); if (!Lgc_FunctionButton_SendWindowsKey(NormalKey, false)) { for (int Index = ModifierList.size() - 1; Index >= 0; --Index) { Lgc_FunctionButton_SendWindowsKey(ModifierList.at(Index), false); } return false; } Sleep(LGC_FUNCTIONBUTTON_KEY_HOLD_DELAY_MS); } for (int Index = ModifierList.size() - 1; Index >= 0; --Index) { if (!Lgc_FunctionButton_SendWindowsKey(ModifierList.at(Index), false)) { return false; } Sleep(LGC_FUNCTIONBUTTON_KEY_HOLD_DELAY_MS); } return true; } bool Lgc_FunctionButton_SendShortcutSequence( const QVector>& CombinationList) { for (int Index = 0; Index < CombinationList.size(); ++Index) { const auto& Combination = CombinationList.at(Index); if (!Lgc_FunctionButton_SendKeyCombination(Combination)) { return false; } if (Index + 1 < CombinationList.size()) { Sleep(LGC_FUNCTIONBUTTON_SEQUENCE_STEP_DELAY_MS); } } return true; } void Lgc_FunctionButton_RunKeyCombination( const Lgc_FunctionFeature_Definition& Feature, quint16 SourceUsage, QString* p_TextStatus) { const QString CombinationText = Feature.SequenceText.trimmed(); if (CombinationText.isEmpty()) { *p_TextStatus = QStringLiteral("%1 的快捷键尚未配置。") .arg(Lgc_FunctionButton_GetFeatureName(Feature)); return; } QVector KeyList; QString ErrorText; if (!Lgc_FunctionButton_ParseKeyCombinationText( CombinationText, SourceUsage, &KeyList, &ErrorText)) { QVector UsageList; if (!Lgc_FunctionButton_ParseLegacySequenceText( CombinationText, SourceUsage, &UsageList, &ErrorText)) { *p_TextStatus = QStringLiteral("%1 的快捷键无效:%2") .arg(Lgc_FunctionButton_GetFeatureName(Feature), ErrorText); return; } KeyList = Lgc_FunctionButton_ConvertUsageListToSequenceKeys(UsageList); if (KeyList.isEmpty()) { *p_TextStatus = QStringLiteral("%1 的快捷键无效:存在无法执行的按键。") .arg(Lgc_FunctionButton_GetFeatureName(Feature)); return; } } *p_TextStatus = Lgc_FunctionButton_SendKeyCombination(KeyList) ? QStringLiteral("%1 已输出快捷键:%2") .arg(Lgc_FunctionButton_GetFeatureName(Feature), Lgc_FunctionButton_FormatKeyCombination(KeyList)) : QStringLiteral("%1 输出快捷键失败。") .arg(Lgc_FunctionButton_GetFeatureName(Feature)); } void Lgc_FunctionButton_RunKeySequence( const Lgc_FunctionFeature_Definition& Feature, quint16 SourceUsage, QString* p_TextStatus) { const QString SequenceText = Feature.SequenceText.trimmed(); if (SequenceText.isEmpty()) { *p_TextStatus = QStringLiteral("%1 的快捷键序列尚未配置。") .arg(Lgc_FunctionButton_GetFeatureName(Feature)); return; } QVector> CombinationList; QString ErrorText; if (!Lgc_FunctionButton_ParseShortcutSequenceText( SequenceText, SourceUsage, &CombinationList, &ErrorText)) { QVector UsageList; if (!Lgc_FunctionButton_ParseLegacySequenceText( SequenceText, SourceUsage, &UsageList, &ErrorText)) { *p_TextStatus = QStringLiteral("%1 的快捷键序列无效:%2") .arg(Lgc_FunctionButton_GetFeatureName(Feature), ErrorText); return; } const QVector KeyList = Lgc_FunctionButton_ConvertUsageListToSequenceKeys(UsageList); CombinationList = Lgc_FunctionButton_GroupSequenceKeysIntoCombinations(KeyList); if (CombinationList.isEmpty()) { *p_TextStatus = QStringLiteral("%1 的快捷键序列无效:存在无法执行的按键。") .arg(Lgc_FunctionButton_GetFeatureName(Feature)); return; } } *p_TextStatus = Lgc_FunctionButton_SendShortcutSequence(CombinationList) ? QStringLiteral("%1 已输出快捷键序列:%2") .arg(Lgc_FunctionButton_GetFeatureName(Feature), Lgc_FunctionButton_FormatShortcutSequence(CombinationList)) : QStringLiteral("%1 输出快捷键序列失败。") .arg(Lgc_FunctionButton_GetFeatureName(Feature)); } void Lgc_FunctionButton_RunOpenWebsite( const Lgc_FunctionFeature_Definition& Feature, QString* p_TextStatus) { const QString UrlText = Feature.WebsiteUrl.trimmed(); const QUrl Url = QUrl::fromUserInput(UrlText); if (UrlText.isEmpty() || !Url.isValid() || Url.isEmpty()) { *p_TextStatus = QStringLiteral("%1 的网址配置无效。") .arg(Lgc_FunctionButton_GetFeatureName(Feature)); return; } *p_TextStatus = QDesktopServices::openUrl(Url) ? QStringLiteral("%1 已打开网址:%2") .arg(Lgc_FunctionButton_GetFeatureName(Feature), Url.toString()) : QStringLiteral("%1 打开网址失败。") .arg(Lgc_FunctionButton_GetFeatureName(Feature)); }