From 4e8d5c9c393db76787f18f9e05529eb6e1e6c903 Mon Sep 17 00:00:00 2001 From: Dmitry Chapyshev Date: Tue, 9 Aug 2016 21:03:55 +0000 Subject: [PATCH] [INPUT] - Implement 'Key Settings' and 'Change Key Settings' dialogs * Now you can add, delete and change the input method, change the hotkey switching input methods. The system correctly responds to changes. It works fine in Windows 10, but has not yet been tested on ReactOS svn path=/trunk/; revision=72171 --- reactos/dll/cpl/input_new/CMakeLists.txt | 3 +- reactos/dll/cpl/input_new/add_dialog.c | 2 +- reactos/dll/cpl/input_new/input.h | 12 + reactos/dll/cpl/input_new/input_list.c | 10 - .../dll/cpl/input_new/key_sequence_dialog.c | 205 +++++++++++++++ .../dll/cpl/input_new/key_settings_dialog.c | 245 +++++++++++++++--- reactos/dll/cpl/input_new/settings_page.c | 33 ++- 7 files changed, 458 insertions(+), 52 deletions(-) create mode 100644 reactos/dll/cpl/input_new/key_sequence_dialog.c diff --git a/reactos/dll/cpl/input_new/CMakeLists.txt b/reactos/dll/cpl/input_new/CMakeLists.txt index 3a1529cdb20..999192f26ad 100644 --- a/reactos/dll/cpl/input_new/CMakeLists.txt +++ b/reactos/dll/cpl/input_new/CMakeLists.txt @@ -15,7 +15,8 @@ list(APPEND SOURCE advanced_settings_page.c add_dialog.c edit_dialog.c - key_settings_dialog.c) + key_settings_dialog.c + key_sequence_dialog.c) add_rc_deps(input.rc ${CMAKE_CURRENT_SOURCE_DIR}/resources/keyboard-shortcuts.ico) diff --git a/reactos/dll/cpl/input_new/add_dialog.c b/reactos/dll/cpl/input_new/add_dialog.c index 5156b190834..927285cab4f 100644 --- a/reactos/dll/cpl/input_new/add_dialog.c +++ b/reactos/dll/cpl/input_new/add_dialog.c @@ -17,7 +17,7 @@ GetDefaultLayoutForLocale(DWORD dwLocaleId) DWORD dwResult = 0; HINF hIntlInf; - hIntlInf = SetupOpenInfFileW(L"intl.inf", NULL, INF_STYLE_WIN4, NULL); + hIntlInf = SetupOpenInfFileW(L"G:\\Projects\\_ReactOS\\reactos\\output-MinGW-i386\\dll\\cpl\\input_new\\intl.inf", NULL, INF_STYLE_WIN4, NULL); if (hIntlInf != INVALID_HANDLE_VALUE) { WCHAR szLangID[MAX_STR_LEN]; diff --git a/reactos/dll/cpl/input_new/input.h b/reactos/dll/cpl/input_new/input.h index 3ca37475ffb..46293efb318 100644 --- a/reactos/dll/cpl/input_new/input.h +++ b/reactos/dll/cpl/input_new/input.h @@ -56,9 +56,21 @@ INT_PTR CALLBACK EditDialogProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); /* key_settings_dialog.c */ + +typedef struct +{ + DWORD dwAttributes; + DWORD dwLanguage; + DWORD dwLayout; +} KEY_SETTINGS; + INT_PTR CALLBACK KeySettingsDialogProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); +/* key_sequence_dialog.c */ +INT_PTR CALLBACK +ChangeKeySeqDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); + static inline WCHAR* DublicateString(const WCHAR *pszString) diff --git a/reactos/dll/cpl/input_new/input_list.c b/reactos/dll/cpl/input_new/input_list.c index 2fea50b609a..f442edec4b1 100644 --- a/reactos/dll/cpl/input_new/input_list.c +++ b/reactos/dll/cpl/input_new/input_list.c @@ -110,11 +110,8 @@ InputList_PrepareUserRegistry(VOID) { RegDeleteKeyW(hKey, L"Preload"); RegDeleteKeyW(hKey, L"Substitutes"); - //RegDeleteKeyW(hKey, L"Toggle"); RegCloseKey(hKey); - - RegDeleteKeyW(HKEY_CURRENT_USER, L"Keyboard Layout"); } if (RegCreateKeyW(HKEY_CURRENT_USER, L"Keyboard Layout", &hKey) != ERROR_SUCCESS) @@ -136,13 +133,6 @@ InputList_PrepareUserRegistry(VOID) RegCloseKey(hTempKey); - if (RegCreateKeyW(hKey, L"Toggle", &hTempKey) != ERROR_SUCCESS) - { - goto Cleanup; - } - - RegCloseKey(hTempKey); - bResult = TRUE; Cleanup: diff --git a/reactos/dll/cpl/input_new/key_sequence_dialog.c b/reactos/dll/cpl/input_new/key_sequence_dialog.c new file mode 100644 index 00000000000..81bc82edbae --- /dev/null +++ b/reactos/dll/cpl/input_new/key_sequence_dialog.c @@ -0,0 +1,205 @@ +/* +* PROJECT: input.dll +* FILE: dll/cpl/input/key_sequence_dialog.c +* PURPOSE: input.dll +* PROGRAMMER: Dmitry Chapyshev (dmitry@reactos.org) +*/ + +#include "input.h" + + +INT_PTR CALLBACK +ChangeKeySeqDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + UNREFERENCED_PARAMETER(lParam); + + switch (uMsg) + { + case WM_INITDIALOG: + { + KEY_SETTINGS *keySettings = (KEY_SETTINGS*) lParam; + + if (keySettings != NULL) + { + SetWindowLongPtrW(hwndDlg, GWLP_USERDATA, (LONG_PTR) keySettings); + + if (keySettings->dwLanguage == 3) + { + CheckDlgButton(hwndDlg, IDC_CTRL_LANG, BST_CHECKED); + EnableWindow(GetDlgItem(hwndDlg, IDC_CTRL_LANG), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_LEFT_ALT_LANG), FALSE); + } + else + { + CheckDlgButton(hwndDlg, IDC_SWITCH_INPUT_LANG_CB, BST_CHECKED); + + if (keySettings->dwLanguage == 1) + { + CheckDlgButton(hwndDlg, IDC_LEFT_ALT_LANG, BST_CHECKED); + } + else + { + CheckDlgButton(hwndDlg, IDC_CTRL_LANG, BST_CHECKED); + } + } + + if (keySettings->dwLayout == 3) + { + CheckDlgButton(hwndDlg, IDC_LEFT_ALT_LAYOUT, BST_CHECKED); + EnableWindow(GetDlgItem(hwndDlg, IDC_CTRL_LAYOUT), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_LEFT_ALT_LAYOUT), FALSE); + } + else + { + CheckDlgButton(hwndDlg, IDC_SWITCH_KBLAYOUTS_CB, BST_CHECKED); + + if (keySettings->dwLayout == 1) + { + CheckDlgButton(hwndDlg, IDC_LEFT_ALT_LAYOUT, BST_CHECKED); + } + else + { + CheckDlgButton(hwndDlg, IDC_CTRL_LAYOUT, BST_CHECKED); + } + } + } + } + break; + + case WM_COMMAND: + { + switch (LOWORD(wParam)) + { + case IDC_SWITCH_INPUT_LANG_CB: + { + if (HIWORD(wParam) == BN_CLICKED) + { + if (IsDlgButtonChecked(hwndDlg, IDC_SWITCH_INPUT_LANG_CB) == BST_CHECKED) + { + EnableWindow(GetDlgItem(hwndDlg, IDC_CTRL_LANG), TRUE); + EnableWindow(GetDlgItem(hwndDlg, IDC_LEFT_ALT_LANG), TRUE); + } + else + { + EnableWindow(GetDlgItem(hwndDlg, IDC_CTRL_LANG), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_LEFT_ALT_LANG), FALSE); + } + } + } + break; + + case IDC_SWITCH_KBLAYOUTS_CB: + { + if (HIWORD(wParam) == BN_CLICKED) + { + if (IsDlgButtonChecked(hwndDlg, IDC_SWITCH_KBLAYOUTS_CB) == BST_CHECKED) + { + EnableWindow(GetDlgItem(hwndDlg, IDC_CTRL_LAYOUT), TRUE); + EnableWindow(GetDlgItem(hwndDlg, IDC_LEFT_ALT_LAYOUT), TRUE); + } + else + { + EnableWindow(GetDlgItem(hwndDlg, IDC_CTRL_LAYOUT), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_LEFT_ALT_LAYOUT), FALSE); + } + } + } + break; + + case IDC_CTRL_LANG: + { + if (HIWORD(wParam) == BN_CLICKED) + { + CheckDlgButton(hwndDlg, IDC_LEFT_ALT_LAYOUT, BST_CHECKED); + CheckDlgButton(hwndDlg, IDC_CTRL_LAYOUT, BST_UNCHECKED); + } + } + break; + + case IDC_LEFT_ALT_LANG: + { + if (HIWORD(wParam) == BN_CLICKED) + { + CheckDlgButton(hwndDlg, IDC_CTRL_LAYOUT, BST_CHECKED); + CheckDlgButton(hwndDlg, IDC_LEFT_ALT_LAYOUT, BST_UNCHECKED); + } + } + break; + + case IDC_CTRL_LAYOUT: + { + if (HIWORD(wParam) == BN_CLICKED) + { + CheckDlgButton(hwndDlg, IDC_LEFT_ALT_LANG, BST_CHECKED); + CheckDlgButton(hwndDlg, IDC_CTRL_LANG, BST_UNCHECKED); + } + } + break; + + case IDC_LEFT_ALT_LAYOUT: + { + if (HIWORD(wParam) == BN_CLICKED) + { + CheckDlgButton(hwndDlg, IDC_CTRL_LANG, BST_CHECKED); + CheckDlgButton(hwndDlg, IDC_LEFT_ALT_LANG, BST_UNCHECKED); + } + } + break; + + case IDOK: + { + KEY_SETTINGS *keySettings; + + keySettings = (KEY_SETTINGS*)GetWindowLongPtrW(hwndDlg, GWLP_USERDATA); + + if (keySettings != NULL) + { + if (IsDlgButtonChecked(hwndDlg, IDC_SWITCH_INPUT_LANG_CB) == BST_CHECKED) + { + if (IsDlgButtonChecked(hwndDlg, IDC_CTRL_LANG) == BST_CHECKED) + { + keySettings->dwLanguage = 2; + } + else + { + keySettings->dwLanguage = 1; + } + } + else + { + keySettings->dwLanguage = 3; + } + + if (IsDlgButtonChecked(hwndDlg, IDC_SWITCH_KBLAYOUTS_CB) == BST_CHECKED) + { + if (IsDlgButtonChecked(hwndDlg, IDC_CTRL_LAYOUT) == BST_CHECKED) + { + keySettings->dwLayout = 2; + } + else + { + keySettings->dwLayout = 1; + } + } + else + { + keySettings->dwLayout = 3; + } + } + + EndDialog(hwndDlg, LOWORD(wParam)); + } + break; + + case IDCANCEL: + { + EndDialog(hwndDlg, LOWORD(wParam)); + } + break; + } + } + break; + } + + return FALSE; +} diff --git a/reactos/dll/cpl/input_new/key_settings_dialog.c b/reactos/dll/cpl/input_new/key_settings_dialog.c index 0e1a80f9a23..b3f39778f9c 100644 --- a/reactos/dll/cpl/input_new/key_settings_dialog.c +++ b/reactos/dll/cpl/input_new/key_settings_dialog.c @@ -7,43 +7,210 @@ #include "input.h" +static KEY_SETTINGS _KeySettings = { 0 }; -INT_PTR CALLBACK -ChangeKeySeqDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) + +static VOID +ReadKeysSettings(VOID) { - UNREFERENCED_PARAMETER(lParam); + HKEY hKey; - switch (uMsg) + if (RegOpenKeyExW(HKEY_CURRENT_USER, + L"Keyboard Layout", + 0, + KEY_QUERY_VALUE, + &hKey) == ERROR_SUCCESS) { - case WM_INITDIALOG: + DWORD dwSize; + + dwSize = sizeof(DWORD); + + if (RegQueryValueExW(hKey, + L"Attributes", + NULL, NULL, + (LPBYTE)&_KeySettings.dwAttributes, + &dwSize) != ERROR_SUCCESS) { - + _KeySettings.dwAttributes = (DWORD) -1; } - break; - case WM_COMMAND: - { - switch (LOWORD(wParam)) - { - case IDOK: - { - EndDialog(hwndDlg, LOWORD(wParam)); - } - break; - - case IDCANCEL: - { - EndDialog(hwndDlg, LOWORD(wParam)); - } - break; - } - } - break; + RegCloseKey(hKey); } - return FALSE; + if (RegOpenKeyExW(HKEY_CURRENT_USER, + L"Keyboard Layout\\Toggle", + 0, + KEY_QUERY_VALUE, + &hKey) == ERROR_SUCCESS) + { + WCHAR szBuffer[MAX_PATH]; + DWORD dwSize; + + dwSize = sizeof(szBuffer); + + if (RegQueryValueExW(hKey, + L"Language Hotkey", + NULL, NULL, + (LPBYTE)szBuffer, &dwSize) == ERROR_SUCCESS) + { + _KeySettings.dwLanguage = _wtoi(szBuffer); + } + + dwSize = sizeof(szBuffer); + + if (RegQueryValueExW(hKey, + L"Layout Hotkey", + NULL, NULL, + (LPBYTE)szBuffer, &dwSize) == ERROR_SUCCESS) + { + _KeySettings.dwLayout = _wtoi(szBuffer); + } + + RegCloseKey(hKey); + } } + +static VOID +WriteKeysSettings(VOID) +{ + HKEY hKey; + + if (RegOpenKeyExW(HKEY_CURRENT_USER, + L"Keyboard Layout", + 0, + KEY_SET_VALUE, + &hKey) == ERROR_SUCCESS) + { + RegSetValueExW(hKey, + L"Attributes", + 0, + REG_DWORD, + (LPBYTE)&_KeySettings.dwAttributes, + sizeof(DWORD)); + + RegCloseKey(hKey); + } + + if (RegOpenKeyExW(HKEY_CURRENT_USER, + L"Keyboard Layout\\Toggle", + 0, + KEY_SET_VALUE, + &hKey) == ERROR_SUCCESS) + { + WCHAR szBuffer[MAX_PATH]; + + StringCchPrintfW(szBuffer, ARRAYSIZE(szBuffer), L"%lu", _KeySettings.dwLanguage); + + RegSetValueExW(hKey, + L"Hotkey", + 0, + REG_SZ, + (LPBYTE)szBuffer, + (wcslen(szBuffer) + 1) * sizeof(WCHAR)); + + RegSetValueExW(hKey, + L"Language Hotkey", + 0, + REG_SZ, + (LPBYTE)szBuffer, + (wcslen(szBuffer) + 1) * sizeof(WCHAR)); + + StringCchPrintfW(szBuffer, ARRAYSIZE(szBuffer), L"%lu", _KeySettings.dwLayout); + + RegSetValueExW(hKey, + L"Layout Hotkey", + 0, + REG_SZ, + (LPBYTE)szBuffer, + (wcslen(szBuffer) + 1) * sizeof(WCHAR)); + + RegCloseKey(hKey); + + /* Notice system of change of parameters */ + SystemParametersInfoW(SPI_SETLANGTOGGLE, 0, NULL, 0); + } +} + + +static VOID +UpdateKeySettingsListView(HWND hwndList) +{ + WCHAR szBuffer[MAX_STR_LEN]; + LV_ITEM item; + INT iItemIndex; + + ListView_DeleteAllItems(hwndList); + + memset(&item, 0, sizeof(LV_ITEM)); + + LoadStringW(hApplet, IDS_SWITCH_BET_INLANG, szBuffer, ARRAYSIZE(szBuffer)); + item.mask = LVIF_TEXT | LVIF_PARAM | LVIF_STATE; + item.pszText = szBuffer; + item.iItem = 0; + + iItemIndex = ListView_InsertItem(hwndList, &item); + + if (_KeySettings.dwLanguage == 1) + { + LoadStringW(hApplet, IDS_LEFT_ALT_SHIFT, szBuffer, ARRAYSIZE(szBuffer)); + } + else if (_KeySettings.dwLanguage == 2) + { + LoadStringW(hApplet, IDS_CTRL_SHIFT, szBuffer, ARRAYSIZE(szBuffer)); + } + else + { + LoadStringW(hApplet, IDS_NONE, szBuffer, ARRAYSIZE(szBuffer)); + } + + ListView_SetItemText(hwndList, iItemIndex, 1, szBuffer); +} + + +static VOID +OnInitKeySettingsDialog(HWND hwndDlg) +{ + LV_COLUMN column; + HWND hwndList; + + ReadKeysSettings(); + + if (_KeySettings.dwAttributes & KLF_SHIFTLOCK) + { + CheckDlgButton(hwndDlg, IDC_PRESS_SHIFT_KEY_RB, BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_PRESS_CL_KEY_RB, BST_CHECKED); + } + else + { + CheckDlgButton(hwndDlg, IDC_PRESS_SHIFT_KEY_RB, BST_CHECKED); + CheckDlgButton(hwndDlg, IDC_PRESS_CL_KEY_RB, BST_UNCHECKED); + } + + hwndList = GetDlgItem(hwndDlg, IDC_KEY_LISTVIEW); + + ListView_SetExtendedListViewStyle(hwndList, LVS_EX_FULLROWSELECT); + + memset(&column, 0, sizeof(LV_COLUMN)); + + column.mask = LVCF_FMT | LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM; + + column.fmt = LVCFMT_LEFT; + column.iSubItem = 0; + column.pszText = L""; + column.cx = 210; + ListView_InsertColumn(hwndList, 0, &column); + + column.fmt = LVCFMT_RIGHT; + column.cx = 145; + column.iSubItem = 1; + column.pszText = L""; + ListView_InsertColumn(hwndList, 1, &column); + + UpdateKeySettingsListView(hwndList); +} + + INT_PTR CALLBACK KeySettingsDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { @@ -52,7 +219,10 @@ KeySettingsDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) switch (uMsg) { case WM_INITDIALOG: - break; + { + OnInitKeySettingsDialog(hwndDlg); + } + break; case WM_COMMAND: { @@ -60,18 +230,29 @@ KeySettingsDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { case IDC_CHANGE_KEY_SEQ_BTN: { - if (DialogBoxW(hApplet, - MAKEINTRESOURCEW(IDD_CHANGE_KEY_SEQ), - hwndDlg, - ChangeKeySeqDialogProc) == IDOK) + if (DialogBoxParamW(hApplet, + MAKEINTRESOURCEW(IDD_CHANGE_KEY_SEQ), + hwndDlg, + ChangeKeySeqDialogProc, + (LPARAM)&_KeySettings) == IDOK) { - + UpdateKeySettingsListView(GetDlgItem(hwndDlg, IDC_KEY_LISTVIEW)); } } break; case IDOK: { + if (IsDlgButtonChecked(hwndDlg, IDC_PRESS_CL_KEY_RB) == BST_UNCHECKED) + { + _KeySettings.dwAttributes &= ~KLF_SHIFTLOCK; + } + else + { + _KeySettings.dwAttributes |= KLF_SHIFTLOCK; + } + + WriteKeysSettings(); EndDialog(hwndDlg, LOWORD(wParam)); } break; diff --git a/reactos/dll/cpl/input_new/settings_page.c b/reactos/dll/cpl/input_new/settings_page.c index 1d12d6c4018..b630cb7fe3f 100644 --- a/reactos/dll/cpl/input_new/settings_page.c +++ b/reactos/dll/cpl/input_new/settings_page.c @@ -348,13 +348,10 @@ OnCommandSettingsPage(HWND hwndDlg, WPARAM wParam) case IDC_KEY_SET_BTN: { - if (DialogBoxW(hApplet, - MAKEINTRESOURCEW(IDD_KEYSETTINGS), - hwndDlg, - KeySettingsDialogProc) == IDOK) - { - PropSheet_Changed(GetParent(hwndDlg), hwndDlg); - } + DialogBoxW(hApplet, + MAKEINTRESOURCEW(IDD_KEYSETTINGS), + hwndDlg, + KeySettingsDialogProc); } break; } @@ -374,9 +371,28 @@ OnNotifySettingsPage(HWND hwndDlg, LPARAM lParam) { if (header->idFrom == IDC_KEYLAYOUT_LIST) { - if (ListView_GetNextItem(header->hwndFrom, -1, LVNI_SELECTED) != -1) + INT iSelected = ListView_GetNextItem(header->hwndFrom, -1, LVNI_SELECTED); + + if (iSelected != -1) { + LVITEM item = { 0 }; + SetControlsState(hwndDlg, TRUE); + + item.mask = LVIF_PARAM; + item.iItem = iSelected; + + if (ListView_GetItem(header->hwndFrom, &item) != FALSE) + { + INPUT_LIST_NODE *pInput; + + pInput = (INPUT_LIST_NODE*) item.lParam; + + if (pInput != NULL && pInput->wFlags & INPUT_LIST_NODE_FLAG_DEFAULT) + { + EnableWindow(GetDlgItem(hwndDlg, IDC_SET_DEFAULT), FALSE); + } + } } else { @@ -388,6 +404,7 @@ OnNotifySettingsPage(HWND hwndDlg, LPARAM lParam) case PSN_APPLY: { + /* Write Input Methods list to registry */ InputList_Process(); } break;