Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -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/
61 changes: 61 additions & 0 deletions Sources/OpenKey/engine/Engine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -463,6 +482,7 @@ void startNewSession() {
_hasHandledMacro = false;
_hasHandleQuickConsonant = false;
_longWordHelper.clear();
_germanLastKey = 0;
}

void checkCorrectVowel(vector<vector<Uint16>>& charset, int& i, int& k, const Uint16& markKey) {
Expand Down Expand Up @@ -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,
Expand Down
7 changes: 7 additions & 0 deletions Sources/OpenKey/engine/Engine.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
/*
* 0: English
* 1: Vietnamese
* 2: German (umlaut: a+1=ä, o+1=ö, u+1=ü, s+1=ß)
*/
extern int vLanguage;

Expand Down Expand Up @@ -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
*/
Expand Down
4 changes: 2 additions & 2 deletions Sources/OpenKey/win32/OpenKey/OpenKey.sln
Original file line number Diff line number Diff line change
@@ -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
Expand Down
21 changes: 17 additions & 4 deletions Sources/OpenKey/win32/OpenKey/OpenKey/AppDelegate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}
}
Expand Down Expand Up @@ -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();
}
}
Expand Down
1 change: 1 addition & 0 deletions Sources/OpenKey/win32/OpenKey/OpenKey/AppDelegate.h
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
42 changes: 30 additions & 12 deletions Sources/OpenKey/win32/OpenKey/OpenKey/MainControlDialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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();
}
}
Expand Down Expand Up @@ -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) {
Expand Down
2 changes: 1 addition & 1 deletion Sources/OpenKey/win32/OpenKey/OpenKey/MainControlDialog.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
64 changes: 58 additions & 6 deletions Sources/OpenKey/win32/OpenKey/OpenKey/OpenKey.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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();
}
Expand All @@ -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 {
Expand Down
7 changes: 7 additions & 0 deletions Sources/OpenKey/win32/OpenKey/OpenKey/OpenKey.rc
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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"
Expand Down Expand Up @@ -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"
Expand Down
Loading