diff --git a/.gitignore b/.gitignore index 7fd14bb2..e0b73c90 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,4 @@ /Sources/OpenKey/win32/OpenKey/OpenKey/x64/Debug /Sources/OpenKey/win32/OpenKey/OpenKey/x64/Release /Sources/OpenKey/win32/OpenKey/OpenKeyUpdate/x64/Release +*/Release/ \ No newline at end of file diff --git a/Sources/OpenKey/engine/Engine.cpp b/Sources/OpenKey/engine/Engine.cpp index de90833b..d9214320 100644 --- a/Sources/OpenKey/engine/Engine.cpp +++ b/Sources/OpenKey/engine/Engine.cpp @@ -119,6 +119,25 @@ static bool _useSpellCheckingBefore; static bool _hasHandleQuickConsonant; static bool _willTempOffEngine = false; +/** + * German umlaut mode + * a + 1 -> ä; o + 1 -> ö; u + 1 -> ü; s + 1 -> ß + * Keeps the last typed letter (with caps state) of the current word. + * CAPS_MASK bit is used to remember whether the base letter was capitalized. + */ +static Uint32 _germanLastKey = 0; + +static Uint32 germanUmlautChar(const Uint32& lastKey) { + bool isCaps = (lastKey & CAPS_MASK) != 0; + switch (lastKey & CHAR_MASK) { + case KEY_A: return isCaps ? 0xC4 : 0xE4; //Ä : ä + case KEY_O: return isCaps ? 0xD6 : 0xF6; //Ö : ö + case KEY_U: return isCaps ? 0xDC : 0xFC; //Ü : ü + case KEY_S: return isCaps ? 0x1E9E : 0xDF; //ẞ : ß + } + return 0; +} + //function prototype void findAndCalculateVowel(const bool& forGrammar=false); void insertMark(const Uint32& markMask, const bool& canModifyFlag=true); @@ -463,6 +482,7 @@ void startNewSession() { _hasHandledMacro = false; _hasHandleQuickConsonant = false; _longWordHelper.clear(); + _germanLastKey = 0; } void checkCorrectVowel(vector>& charset, int& i, int& k, const Uint16& markKey) { @@ -1311,6 +1331,47 @@ void vEnglishMode(const vKeyEventState& state, const Uint16& data, const bool& i } } +void vGermanMode(const vKeyEventState& state, const Uint16& data, const bool& isCaps, const bool& otherControlKey) { + hCode = vDoNothing; + hBPC = 0; + hNCC = 0; + hExt = 3; //normal key + + if (state == vKeyEventState::MouseDown || state == vKeyEventState::MouseUp || otherControlKey) { + _germanLastKey = 0; + hExt = 1; //word break + return; + } + + if (data == KEY_DELETE) { //backspace + _germanLastKey = 0; + hExt = 2; //delete key + return; + } + + if (data == KEY_1) { //umlaut trigger key + if (_germanLastKey != 0) { + Uint32 ch = germanUmlautChar(_germanLastKey); + if (ch != 0) { + hCode = vWillProcess; + hBPC = 1; //remove the base letter + hNCC = 1; + hData[0] = CHAR_CODE_MASK | ch; + _germanLastKey = 0; + return; + } + } + _germanLastKey = 0; //'1' can not be combined + return; + } + + if (data >= KEY_A && data <= KEY_Z) { //letter key + _germanLastKey = data | (isCaps ? CAPS_MASK : 0); + } else { + _germanLastKey = 0; //any other key breaks the combination + } +} + void vKeyHandleEvent(const vKeyEvent& event, const vKeyEventState& state, const Uint16& data, diff --git a/Sources/OpenKey/engine/Engine.h b/Sources/OpenKey/engine/Engine.h index f288f8c5..a9471e0e 100644 --- a/Sources/OpenKey/engine/Engine.h +++ b/Sources/OpenKey/engine/Engine.h @@ -44,6 +44,7 @@ /* * 0: English * 1: Vietnamese + * 2: German (umlaut: a+1=ä, o+1=ö, u+1=ü, s+1=ß) */ extern int vLanguage; @@ -221,6 +222,12 @@ void startNewSession(); */ void vEnglishMode(const vKeyEventState& state, const Uint16& data, const bool& isCaps, const bool& otherControlKey); +/** + * German umlaut typing mode (a+1=ä, o+1=ö, u+1=ü, s+1=ß) + * Call this for every key/mouse event while vLanguage == 2 + */ +void vGermanMode(const vKeyEventState& state, const Uint16& data, const bool& isCaps, const bool& otherControlKey); + /** * temporarily turn off spell checking */ diff --git a/Sources/OpenKey/win32/OpenKey/OpenKey.sln b/Sources/OpenKey/win32/OpenKey/OpenKey.sln index 5002e5a0..7692a697 100644 --- a/Sources/OpenKey/win32/OpenKey/OpenKey.sln +++ b/Sources/OpenKey/win32/OpenKey/OpenKey.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.0.29324.140 +# Visual Studio Version 18 +VisualStudioVersion = 18.10.3 MinimumVisualStudioVersion = 10.0.40219.1 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "OpenKey", "OpenKey\OpenKey.vcxproj", "{21E71F9D-859A-4B8B-84F4-F5003E933BB3}" EndProject diff --git a/Sources/OpenKey/win32/OpenKey/OpenKey/AppDelegate.cpp b/Sources/OpenKey/win32/OpenKey/OpenKey/AppDelegate.cpp index 140d6e4a..86719887 100644 --- a/Sources/OpenKey/win32/OpenKey/OpenKey/AppDelegate.cpp +++ b/Sources/OpenKey/win32/OpenKey/OpenKey/AppDelegate.cpp @@ -205,14 +205,27 @@ void AppDelegate::onDefaultConfig() { } void AppDelegate::onToggleVietnamese() { - APP_SET_DATA(vLanguage, vLanguage ? 0 : 1); + APP_SET_DATA(vLanguage, vLanguage == 0 ? 1 : (vLanguage == 1 ? 2 : 0)); if (mainDialog) { mainDialog->fillData(); } - + + if (vUseSmartSwitchKey) { + string& exe = OpenKeyHelper::getLastAppExecuteName(); + setAppInputMethodStatus(exe, vLanguage | (vCodeTable << 2)); + saveSmartSwitchKeyData(); + } +} + +void AppDelegate::onSetLanguage(const int& language) { + APP_SET_DATA(vLanguage, language == 1 ? 1 : (language == 2 ? 2 : 0)); + if (mainDialog) { + mainDialog->fillData(); + } + if (vUseSmartSwitchKey) { string& exe = OpenKeyHelper::getLastAppExecuteName(); - setAppInputMethodStatus(exe, vLanguage | (vCodeTable << 1)); + setAppInputMethodStatus(exe, vLanguage | (vCodeTable << 2)); saveSmartSwitchKeyData(); } } @@ -281,7 +294,7 @@ void AppDelegate::onTableCode(const int & code) { mainDialog->fillData(); } if (vRememberCode) { - setAppInputMethodStatus(OpenKeyHelper::getFrontMostAppExecuteName(), vLanguage | (vCodeTable << 1)); + setAppInputMethodStatus(OpenKeyHelper::getFrontMostAppExecuteName(), vLanguage | (vCodeTable << 2)); saveSmartSwitchKeyData(); } } diff --git a/Sources/OpenKey/win32/OpenKey/OpenKey/AppDelegate.h b/Sources/OpenKey/win32/OpenKey/OpenKey/AppDelegate.h index dd5ffdaa..1852f133 100644 --- a/Sources/OpenKey/win32/OpenKey/OpenKey/AppDelegate.h +++ b/Sources/OpenKey/win32/OpenKey/OpenKey/AppDelegate.h @@ -47,6 +47,7 @@ class AppDelegate { void onInputType(const int& type); void onTableCode(const int& code); + void onSetLanguage(const int& language); //0: English; 1: Vietnamese; 2: German void onControlPanel(); void onOpenKeyAbout(); diff --git a/Sources/OpenKey/win32/OpenKey/OpenKey/MainControlDialog.cpp b/Sources/OpenKey/win32/OpenKey/OpenKey/MainControlDialog.cpp index eab2e7c2..74b2cfc4 100644 --- a/Sources/OpenKey/win32/OpenKey/OpenKey/MainControlDialog.cpp +++ b/Sources/OpenKey/win32/OpenKey/OpenKey/MainControlDialog.cpp @@ -112,6 +112,9 @@ void MainControlDialog::initDialog() { checkEnglish = GetDlgItem(hDlg, IDC_RADIO_METHOD_ENGLISH); createToolTip(checkEnglish, IDS_STRING_ENG); + checkGerman = GetDlgItem(hDlg, IDC_RADIO_METHOD_GERMAN); + createToolTip(checkGerman, IDS_STRING_GER); + /*--------end common---------*/ checkModernOrthorgraphy = GetDlgItem(hTabPage1, IDC_CHECK_MODERN_ORTHORGRAPHY); @@ -334,8 +337,9 @@ void MainControlDialog::fillData() { setSwitchKeyText(textSwitchKey, (vSwitchKeyStatus >> 24) & 0xFF); SendMessage(checkBeep, BM_SETCHECK, HAS_BEEP(vSwitchKeyStatus) ? 1 : 0, 0); - SendMessage(checkVietnamese, BM_SETCHECK, vLanguage, 0); - SendMessage(checkEnglish, BM_SETCHECK, !vLanguage, 0); + SendMessage(checkVietnamese, BM_SETCHECK, vLanguage == 1, 0); + SendMessage(checkEnglish, BM_SETCHECK, vLanguage == 0, 0); + SendMessage(checkGerman, BM_SETCHECK, vLanguage == 2, 0); SendMessage(checkModernOrthorgraphy, BM_SETCHECK, vUseModernOrthography ? 1 : 0, 0); SendMessage(checkFixRecommendBrowser, BM_SETCHECK, vFixRecommendBrowser ? 1 : 0, 0); @@ -392,7 +396,7 @@ void MainControlDialog::onComboBoxSelected(const HWND& hCombobox, const int& com else if (hCombobox == comboBoxTableCode) { APP_SET_DATA(vCodeTable, (int)SendMessage(hCombobox, CB_GETCURSEL, 0, 0)); if (vRememberCode) { - setAppInputMethodStatus(OpenKeyHelper::getFrontMostAppExecuteName(), vLanguage | (vCodeTable << 1)); + setAppInputMethodStatus(OpenKeyHelper::getFrontMostAppExecuteName(), vLanguage | (vCodeTable << 2)); saveSmartSwitchKeyData(); } } @@ -433,18 +437,32 @@ void MainControlDialog::onCheckboxClicked(const HWND& hWnd) { } else if (hWnd == checkVietnamese) { val = (int)SendMessage(checkVietnamese, BM_GETCHECK, 0, 0); - APP_SET_DATA(vLanguage, val ? 1 : 0); - if (vUseSmartSwitchKey) { - setAppInputMethodStatus(OpenKeyHelper::getFrontMostAppExecuteName(), vLanguage | (vCodeTable << 1)); - saveSmartSwitchKeyData(); + if (val) { + APP_SET_DATA(vLanguage, 1); + if (vUseSmartSwitchKey) { + setAppInputMethodStatus(OpenKeyHelper::getFrontMostAppExecuteName(), vLanguage | (vCodeTable << 2)); + saveSmartSwitchKeyData(); + } } } else if (hWnd == checkEnglish) { - val = (int)SendMessage(checkVietnamese, BM_GETCHECK, 0, 0); - APP_SET_DATA(vLanguage, val ? 1 : 0); - if (vUseSmartSwitchKey) { - setAppInputMethodStatus(OpenKeyHelper::getFrontMostAppExecuteName(), vLanguage | (vCodeTable << 1)); - saveSmartSwitchKeyData(); + val = (int)SendMessage(checkEnglish, BM_GETCHECK, 0, 0); + if (val) { + APP_SET_DATA(vLanguage, 0); + if (vUseSmartSwitchKey) { + setAppInputMethodStatus(OpenKeyHelper::getFrontMostAppExecuteName(), vLanguage | (vCodeTable << 2)); + saveSmartSwitchKeyData(); + } + } + } + else if (hWnd == checkGerman) { + val = (int)SendMessage(checkGerman, BM_GETCHECK, 0, 0); + if (val) { + APP_SET_DATA(vLanguage, 2); + if (vUseSmartSwitchKey) { + setAppInputMethodStatus(OpenKeyHelper::getFrontMostAppExecuteName(), vLanguage | (vCodeTable << 2)); + saveSmartSwitchKeyData(); + } } } else if (hWnd == checkModernOrthorgraphy) { diff --git a/Sources/OpenKey/win32/OpenKey/OpenKey/MainControlDialog.h b/Sources/OpenKey/win32/OpenKey/OpenKey/MainControlDialog.h index 435d638f..4726051e 100644 --- a/Sources/OpenKey/win32/OpenKey/OpenKey/MainControlDialog.h +++ b/Sources/OpenKey/win32/OpenKey/OpenKey/MainControlDialog.h @@ -20,7 +20,7 @@ class MainControlDialog : public BaseDialog { HWND comboBoxInputType; HWND comboBoxTableCode; HWND checkCtrl, checkAlt, checkWin, checkShift, textSwitchKey, checkBeep; - HWND checkVietnamese, checkEnglish; + HWND checkVietnamese, checkEnglish, checkGerman; HWND checkModernOrthorgraphy, checkFixRecommendBrowser, checkShowOnStartup, checkRunWithWindows, checkSpelling, checkRestoreIfWrongSpelling, checkUseClipboard, checkModernIcon, checkAllowZWJF, checkTempOffSpelling, checkQuickStartConsonant, checkQuickEndConsonant; diff --git a/Sources/OpenKey/win32/OpenKey/OpenKey/OpenKey.cpp b/Sources/OpenKey/win32/OpenKey/OpenKey/OpenKey.cpp index faa179cc..ff7ff710 100644 --- a/Sources/OpenKey/win32/OpenKey/OpenKey/OpenKey.cpp +++ b/Sources/OpenKey/win32/OpenKey/OpenKey/OpenKey.cpp @@ -401,13 +401,15 @@ bool checkHotKey(int hotKeyData, bool checkKeyCode = true) { void switchLanguage() { if (vLanguage == 0) vLanguage = 1; + else if (vLanguage == 1) + vLanguage = 2; //German else vLanguage = 0; if (HAS_BEEP(vSwitchKeyStatus)) MessageBeep(MB_OK); AppDelegate::getInstance()->onInputMethodChangedFromHotKey(); if (vUseSmartSwitchKey) { - setAppInputMethodStatus(OpenKeyHelper::getFrontMostAppExecuteName(), vLanguage | (vCodeTable << 1)); + setAppInputMethodStatus(OpenKeyHelper::getFrontMostAppExecuteName(), vLanguage | (vCodeTable << 2)); saveSmartSwitchKeyData(); } startNewSession(); @@ -454,6 +456,32 @@ static void handleMacro() { SendKeyCode(_keycode | (_flag & MASK_SHIFT ? CAPS_MASK : 0)); } +static void handleGermanKey() { + //fix autocomplete + if (vFixRecommendBrowser) { + SendEmptyCharacter(); + pData->backspaceCount++; + } + + //send backspace to remove the base letter + if (pData->backspaceCount > 0 && pData->backspaceCount < MAX_BUFF) { + for (_i = 0; _i < pData->backspaceCount; _i++) { + SendBackspace(); + } + } + + //send the umlaut character + if (!vSendKeyStepByStep) { + SendNewCharString(); + } else { + if (pData->newCharCount > 0 && pData->newCharCount <= MAX_BUFF) { + for (int i = pData->newCharCount - 1; i >= 0; i--) { + SendKeyCode(pData->charData[i]); + } + } + } +} + static bool SetModifierMask(const Uint16& vkCode) { // For caps lock case, toggling the flag isn't enough. We need to check the actual state, which should be done before each key press. // Example: the caps lock state can be changed without the key being pressed, or the key toggle is made with admin privilege, making the app not able to detect the change. @@ -577,6 +605,22 @@ LRESULT CALLBACK keyboardHookProcess(int nCode, WPARAM wParam, LPARAM lParam) { return CallNextHookEx(hKeyboardHook, nCode, wParam, lParam); } + //if is in german mode + if (vLanguage == 2) { + if (wParam == WM_KEYDOWN || wParam == WM_SYSKEYDOWN) { + vGermanMode(vKeyEventState::KeyDown, + _keycode, + (_flag & MASK_SHIFT) || (_flag & MASK_CAPITAL), + OTHER_CONTROL_KEY); + + if (pData->code == vWillProcess) { //umlaut character + handleGermanKey(); + return -1; //consume event + } + } + return CallNextHookEx(hKeyboardHook, nCode, wParam, lParam); + } + //handle keyboard if (wParam == WM_KEYDOWN || wParam == WM_SYSKEYDOWN) { //send event signal to Engine @@ -662,7 +706,11 @@ LRESULT CALLBACK mouseHookProcess(int nCode, WPARAM wParam, LPARAM lParam) { case WM_XBUTTONUP: case WM_NCXBUTTONUP: //send event signal to Engine - vKeyHandleEvent(vKeyEvent::Mouse, vKeyEventState::MouseDown, 0); + if (vLanguage == 2) { + vGermanMode(vKeyEventState::MouseDown, 0, false, false); + } else { + vKeyHandleEvent(vKeyEvent::Mouse, vKeyEventState::MouseDown, 0); + } if (IS_DOUBLE_CODE(vCodeTable)) { //VNI _syncKey.clear(); } @@ -677,18 +725,22 @@ VOID CALLBACK winEventProcCallback(HWINEVENTHOOK hWinEventHook, DWORD dwEvent, H string& exe = OpenKeyHelper::getFrontMostAppExecuteName(); if (exe.compare("explorer.exe") == 0) //dont apply with windows explorer return; - _languageTemp = getAppInputMethodStatus(exe, vLanguage | (vCodeTable << 1)); + _languageTemp = getAppInputMethodStatus(exe, vLanguage | (vCodeTable << 2)); vTempOffEngine(false); - if (vUseSmartSwitchKey && (_languageTemp & 0x01) != vLanguage) { + if (_languageTemp != -1 && (_languageTemp & 0x03) == 3 && _languageTemp <= 9) { + //legacy data (old bit layout: 1-bit language + code table shifted 1) + _languageTemp = (_languageTemp & 0x01) | ((_languageTemp >> 1) << 2); + } + if (vUseSmartSwitchKey && (_languageTemp & 0x03) != vLanguage) { if (_languageTemp != -1) { - vLanguage = _languageTemp; + vLanguage = _languageTemp & 0x03; AppDelegate::getInstance()->onInputMethodChangedFromHotKey(); } else { saveSmartSwitchKeyData(); } } startNewSession(); - if (vRememberCode && (_languageTemp >> 1) != vCodeTable) { //for remember table code feature + if (vRememberCode && (_languageTemp >> 2) != vCodeTable) { //for remember table code feature if (_languageTemp != -1) { AppDelegate::getInstance()->onTableCode(_languageTemp >> 1); } else { diff --git a/Sources/OpenKey/win32/OpenKey/OpenKey/OpenKey.rc b/Sources/OpenKey/win32/OpenKey/OpenKey/OpenKey.rc index 25cab5ac..d24639c2 100644 --- a/Sources/OpenKey/win32/OpenKey/OpenKey/OpenKey.rc +++ b/Sources/OpenKey/win32/OpenKey/OpenKey/OpenKey.rc @@ -42,6 +42,10 @@ IDI_ICON_STATUS_VIET_10 ICON "StatusViet10.ico" IDI_ICON_STATUS_ENG_10 ICON "StatusEng10.ico" +IDI_ICON_STATUS_GER ICON "StatusGer.ico" + +IDI_ICON_STATUS_GER_10 ICON "StatusGer10.ico" + IDI_ICON_OK_BUTTON ICON "OKButton.ico" IDI_ICON_EXIT_BUTTON ICON "ExitButton.ico" @@ -129,6 +133,7 @@ BEGIN LTEXT "Chế độ gõ:",IDC_STATIC,14,60,36,8 CONTROL "Tiếng Việt",IDC_RADIO_METHOD_VIETNAMESE,"Button",BS_AUTORADIOBUTTON,64,59,47,10 CONTROL "Tiếng Anh",IDC_RADIO_METHOD_ENGLISH,"Button",BS_AUTORADIOBUTTON,158,59,48,10 + CONTROL "Tiếng Đức",IDC_RADIO_METHOD_GERMAN,"Button",BS_AUTORADIOBUTTON,226,59,48,10 DEFPUSHBUTTON "Đóng",IDBUTTON_OK,200,234,71,20 PUSHBUTTON "Tắt OpenKey",IDBUTTON_EXIT,26,234,71,20 CONTROL "",IDC_TAB_CONTROL,"SysTabControl32",TCS_FIXEDWIDTH,7,89,283,140 @@ -448,6 +453,7 @@ BEGIN IDS_APP_TITLE "OpenKey" IDS_TRAY_TITLE "Bấm vào đây để bật gõ Tiếng Việt" IDS_TRAY_TITLE_2 "Bấm vào đây để tắt gõ Tiếng Việt" + IDS_TRAY_TITLE_3 "Đang gõ Tiếng Đức (ä ö ü ß)" IDS_STRING_CONVERT_COMPLETED "Chuyển mã thành công!\nKết quả đã được lưu trong Clipboard!" IDS_MAIN_DIALOG_TITLE "OpenKey %s - Bộ gõ Tiếng Việt" @@ -508,6 +514,7 @@ BEGIN IDS_STRING_BEEP "Kêu tiếng bíp mỗi khi chuyển chế độ gõ, không áp dụng với Loại trừ ứng dụng thông minh" IDS_STRING_VIET "Bật chế độ gõ Tiếng Việt" IDS_STRING_ENG "Bật chế độ gõ Tiếng Anh" + IDS_STRING_GER "Bật chế độ gõ Tiếng Đức: a+1=ä, o+1=ö, u+1=ü, s+1=ß" IDS_STRING_CODE "Chọn bảng mã cần gõ" IDS_STRING_INPUT "Chọn kiểu gõ quen thuộc của bạn" IDS_STRING_MACRO "Bật tính năng gõ tắt" diff --git a/Sources/OpenKey/win32/OpenKey/OpenKey/OpenKey.vcxproj b/Sources/OpenKey/win32/OpenKey/OpenKey/OpenKey.vcxproj index 69b1e312..d5d637ce 100644 --- a/Sources/OpenKey/win32/OpenKey/OpenKey/OpenKey.vcxproj +++ b/Sources/OpenKey/win32/OpenKey/OpenKey/OpenKey.vcxproj @@ -1,5 +1,5 @@ - + Debug @@ -19,7 +19,7 @@ - 15.0 + 18.0 {21E71F9D-859A-4B8B-84F4-F5003E933BB3} Win32Proj OpenKey @@ -29,26 +29,26 @@ Application true - v143 + v145 Unicode Application false - v143 + v145 true Unicode Application true - v143 + v145 Unicode Application false - v143 + v145 true Unicode @@ -210,6 +210,8 @@ + + diff --git a/Sources/OpenKey/win32/OpenKey/OpenKey/OpenKey.vcxproj.filters b/Sources/OpenKey/win32/OpenKey/OpenKey/OpenKey.vcxproj.filters index d23a8126..4dcbf909 100644 --- a/Sources/OpenKey/win32/OpenKey/OpenKey/OpenKey.vcxproj.filters +++ b/Sources/OpenKey/win32/OpenKey/OpenKey/OpenKey.vcxproj.filters @@ -153,6 +153,12 @@ Resource Files + + Resource Files + + + Resource Files + Resource Files diff --git a/Sources/OpenKey/win32/OpenKey/OpenKey/StatusGer.ico b/Sources/OpenKey/win32/OpenKey/OpenKey/StatusGer.ico new file mode 100644 index 00000000..97f0fec9 Binary files /dev/null and b/Sources/OpenKey/win32/OpenKey/OpenKey/StatusGer.ico differ diff --git a/Sources/OpenKey/win32/OpenKey/OpenKey/StatusGer10.ico b/Sources/OpenKey/win32/OpenKey/OpenKey/StatusGer10.ico new file mode 100644 index 00000000..f36cdfb6 Binary files /dev/null and b/Sources/OpenKey/win32/OpenKey/OpenKey/StatusGer10.ico differ diff --git a/Sources/OpenKey/win32/OpenKey/OpenKey/SystemTrayHelper.cpp b/Sources/OpenKey/win32/OpenKey/OpenKey/SystemTrayHelper.cpp index 55d786e9..e818d7fb 100644 --- a/Sources/OpenKey/win32/OpenKey/OpenKey/SystemTrayHelper.cpp +++ b/Sources/OpenKey/win32/OpenKey/OpenKey/SystemTrayHelper.cpp @@ -22,6 +22,10 @@ redistribute your new version, it MUST be open source. #define POPUP_SMART_SWITCH 902 #define POPUP_USE_MACRO 903 +#define POPUP_LANG_VIET 904 +#define POPUP_LANG_ENG 905 +#define POPUP_LANG_GER 906 + #define POPUP_TELEX 910 #define POPUP_VNI 911 #define POPUP_SIMPLE_TELEX 912 @@ -49,11 +53,15 @@ redistribute your new version, it MUST be open source. static HMENU popupMenu; //static HMENU menuInputType; static HMENU otherCode; +static HMENU languageMenu; static NOTIFYICONDATA nid; map menuData = { {POPUP_VIET_ON_OFF, _T("Bật Tiếng Việt")}, + {POPUP_LANG_VIET, _T("Tiếng Việt")}, + {POPUP_LANG_ENG, _T("Tiếng Anh")}, + {POPUP_LANG_GER, _T("Tiếng Đức (ä ö ü ß)")}, {POPUP_SPELLING, _T("Bật kiểm tra chính tả")}, {POPUP_SMART_SWITCH, _T("Bật loại trừ ứng dụng thông minh")}, {POPUP_USE_MACRO, _T("Bật gõ tắt")}, @@ -80,7 +88,7 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) case WM_CREATE: taskbarCreated = RegisterWindowMessage(_T("TaskbarCreated")); break; - case WM_USER+2019: + case WM_USER+2019: AppDelegate::getInstance()->onControlPanel(); break; case WM_TRAYMESSAGE: { @@ -107,6 +115,15 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) case POPUP_VIET_ON_OFF: AppDelegate::getInstance()->onToggleVietnamese(); break; + case POPUP_LANG_VIET: + AppDelegate::getInstance()->onSetLanguage(1); + break; + case POPUP_LANG_ENG: + AppDelegate::getInstance()->onSetLanguage(0); + break; + case POPUP_LANG_GER: + AppDelegate::getInstance()->onSetLanguage(2); + break; case POPUP_SPELLING: AppDelegate::getInstance()->onToggleCheckSpelling(); break; @@ -202,6 +219,13 @@ HWND SystemTrayHelper::createFakeWindow(const HINSTANCE & hIns) { void SystemTrayHelper::createPopupMenu() { popupMenu = CreatePopupMenu(); AppendMenu(popupMenu, MF_CHECKED, POPUP_VIET_ON_OFF, menuData[POPUP_VIET_ON_OFF]); + + languageMenu = CreatePopupMenu(); + AppendMenu(languageMenu, MF_CHECKED, POPUP_LANG_VIET, menuData[POPUP_LANG_VIET]); + AppendMenu(languageMenu, MF_CHECKED, POPUP_LANG_ENG, menuData[POPUP_LANG_ENG]); + AppendMenu(languageMenu, MF_CHECKED, POPUP_LANG_GER, menuData[POPUP_LANG_GER]); + AppendMenu(popupMenu, MF_POPUP, (UINT_PTR)languageMenu, _T("Ngôn ngữ")); + AppendMenu(popupMenu, MF_SEPARATOR, 0, 0); AppendMenu(popupMenu, MF_CHECKED, POPUP_SPELLING, menuData[POPUP_SPELLING]); AppendMenu(popupMenu, MF_CHECKED, POPUP_SMART_SWITCH, menuData[POPUP_SMART_SWITCH]); @@ -241,10 +265,14 @@ void SystemTrayHelper::createPopupMenu() { static void loadTrayIcon() { int icon = 0; - if (vLanguage) { + if (vLanguage == 1) { icon = vUseGrayIcon ? IDI_ICON_STATUS_VIET_10 : IDI_ICON_STATUS_VIET; LoadString(GetModuleHandle(0), IDS_TRAY_TITLE_2, nid.szTip, 128); } + else if (vLanguage == 2) { + icon = vUseGrayIcon ? IDI_ICON_STATUS_GER_10 : IDI_ICON_STATUS_GER; + LoadString(GetModuleHandle(0), IDS_TRAY_TITLE_3, nid.szTip, 128); + } else { icon = vUseGrayIcon ? IDI_ICON_STATUS_ENG_10 : IDI_ICON_STATUS_ENG; LoadString(GetModuleHandle(0), IDS_TRAY_TITLE, nid.szTip, 128); @@ -256,7 +284,10 @@ void SystemTrayHelper::updateData() { loadTrayIcon(); Shell_NotifyIcon(NIM_MODIFY, &nid); - MODIFY_MENU(popupMenu, POPUP_VIET_ON_OFF, vLanguage); + MODIFY_MENU(popupMenu, POPUP_VIET_ON_OFF, vLanguage == 1); + MODIFY_MENU(languageMenu, POPUP_LANG_VIET, vLanguage == 1); + MODIFY_MENU(languageMenu, POPUP_LANG_ENG, vLanguage == 0); + MODIFY_MENU(languageMenu, POPUP_LANG_GER, vLanguage == 2); MODIFY_MENU(popupMenu, POPUP_SPELLING, vCheckSpelling); MODIFY_MENU(popupMenu, POPUP_SMART_SWITCH, vUseSmartSwitchKey); MODIFY_MENU(popupMenu, POPUP_USE_MACRO, vUseMacro); diff --git a/Sources/OpenKey/win32/OpenKey/OpenKey/resource.h b/Sources/OpenKey/win32/OpenKey/OpenKey/resource.h index dc1f5b3e..b890be70 100644 --- a/Sources/OpenKey/win32/OpenKey/OpenKey/resource.h +++ b/Sources/OpenKey/win32/OpenKey/OpenKey/resource.h @@ -182,16 +182,21 @@ #define IDS_STRING_START_CONSONANT 1066 #define IDS_STRING_END_CONSONANT 1067 #define IDC_CHECK_OTHER_LANGUAGES 1068 +#define IDC_RADIO_METHOD_GERMAN 1069 +#define IDS_STRING_GER 1070 +#define IDS_TRAY_TITLE_3 1071 +#define IDI_ICON_STATUS_GER 153 +#define IDI_ICON_STATUS_GER_10 154 #define IDC_STATIC -1 // Next default values for new objects -// +// #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_NO_MFC 1 -#define _APS_NEXT_RESOURCE_VALUE 149 +#define _APS_NEXT_RESOURCE_VALUE 157 #define _APS_NEXT_COMMAND_VALUE 32771 -#define _APS_NEXT_CONTROL_VALUE 1052 +#define _APS_NEXT_CONTROL_VALUE 1072 #define _APS_NEXT_SYMED_VALUE 110 #endif #endif diff --git a/Sources/OpenKey/win32/OpenKey/OpenKeyUpdate/OpenKeyUpdate.vcxproj b/Sources/OpenKey/win32/OpenKey/OpenKeyUpdate/OpenKeyUpdate.vcxproj index 4b97af97..4c9fd942 100644 --- a/Sources/OpenKey/win32/OpenKey/OpenKeyUpdate/OpenKeyUpdate.vcxproj +++ b/Sources/OpenKey/win32/OpenKey/OpenKeyUpdate/OpenKeyUpdate.vcxproj @@ -19,7 +19,7 @@ - 16.0 + 18.0 {A63EF692-7EAE-4EDA-8D2B-3686E1A15A19} Win32Proj OpenKeyUpdate @@ -29,26 +29,26 @@ Application true - v143 + v145 Unicode Application false - v143 + v145 true Unicode Application true - v143 + v145 Unicode Application false - v143 + v145 true Unicode