Странное поведение при вводе с помощью IME в windows 10 1709
Я столкнулся с проблемой в Windows 10 Creators update, где, когда я пытаюсь ввести что-то в свое приложение с помощью IME, первый символ игнорируется; то есть, если я использую IME для ввода японского символа хираганы "DK", набрав K & A, я в конечном итоге получаю только "あ" с потерянным K. Это происходит только с первым персонажем. Но точно такое же приложение работает правильно в Windows 7~8.
Подробности приведены ниже:
Приложение представляет собой приложение MFC MDI типа контейнер/сервер. Его работа действительно проста и понятна. Если документ открыт, то при запуске WM_KEYDOWN динамически создайте поле CEdit и введите нажатую клавишу в поле редактирования. Если поле редактирования уже существует, нет необходимости создавать его снова. Просто добавьте входные данные к содержимому поля редактирования.
I created 2 sample MFC MDI projects (e.g. MDI_sample1 & MDI_Sample2). Keeping the default cpp & h files as is, just added a new class (e.g. CwEdit) that subclasses the CEdit class to both MDI_Sample1 & MDI_Sample2 projects. Now, in MDI_Sample1, I open the *View.cpp, and add a WindowProc override. In this function, I check for the WM_KEYDOWN message, and on WM_KEYDOWN excepting VK_BACK, VK_ENTER, VK_TAB, I dynamically create an edit box using the CwEdit class, and then SendMessage a WM_KEYDOWN with the current wParam and lParam that I got as arguments of the WindowProc function. Running the program, I create a document and then press the key 'k'. An edit box will get created in the document. If IME is not being used, the character 'k' will also get entered into this newly created edit box. Next,I press 'a'and the character 'a' is appended to 'k' in the edit box. So far so good.
Затем я снова создаю новый документ. На этот раз я активирую windows IME на японский язык и ввожу "k". Опять же, будет создано окно редактирования, и оно будет отображать букву "К" с волнистыми подчеркиваниями. Я ввожу "а", и он правильно отображает японский иероглиф "я". Опять же, ожидаемо и правильно.
I copy this exe file to a windows 10 1709 machine and run it. Again, I repeat the same steps above to input the character 'k'. Without IME being active, the box is created and the 'k' is entered into it. Next I press 'a' and the edit box will correctly read 'ka'. Next, I create a new document. This time, I activate the windows IME to japanese and input 'k'. Again, an edit box will get created but it will be empty. I input 'a' and it now displays the japanese character 'あ'. This behaviour happens to all characters. The first keydown which was used to create the edit box will not be shown when IME is active. But once the edit box is created, everything works fine.
Я копирую весь код в MDI_Sample2. Но есть одно маленькое изменение. На этот раз в представлении я переопределяю PreTranslateMessage и выполняю точно такой же процесс, который ранее выполнялся внутри WindowProc. И удалите переопределение WindowProc. Этот MDI_Sample2 отлично работает как на Windows 7, так и на Windows 10 1709, даже когда японский IME активен.
Что я уже пробовал:
Код для *View.cpp для обоих проектов они приведены ниже:
MDI_Sample1View.cpp
*******************
BOOL MDI_Sample1View::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) { // TODO: Add your specialized code here and/or call the base class if(message == WM_CHAR) { int wp = static_cast<int>(wParam); // All printable ascii characters if (wp >= 0x32 && wp <= 0x255) { EnableEdit(); M_pEdit->SendMessage(message, wParam, lParam); return TRUE; } } else if(message == WM_KEYDOWN) { if (wParam == VK_ESCAPE) { if(M_pEdit && GetFocus() == M_pEdit) { DisableEdit(); return TRUE; } } EnableEdit(); } return CView::WindowProc(message, wParam, lParam); }MDI_Sample2View.cpp
*******************
BOOL MDI_Sample2View::PreTranslateMessage(MSG* pMsg) { // TODO: Add your specialized code here and/or call the base class if(pMsg->message == WM_CHAR) { int wp = static_cast<int>(pMsg->wParam); // All printable ascii characters if (wp >= 0x32 && wp <= 0x255) { EnableEdit(); M_pEdit->SendMessage(pMsg->message, pMsg->wParam, pMsg->lParam); return TRUE; } } else if(pMsg->message == WM_KEYDOWN) { if (pMsg->wParam == VK_ESCAPE) { if(M_pEdit && GetFocus() == M_pEdit) { DisableEdit(); return TRUE; } } EnableEdit(); } return CView::PreTranslateMessage(pMsg); }Все остальные файлы такие же, как и созданные visual studio при создании нового проекта.
Тот самый CwEdit.cpp класс имеет 2 функции, а именно Create для создания поля редактирования и OnKeyDown, который приведен ниже:
void CwSpEdit::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) { if(nChar == VK_ESCAPE) { SetWindowText(_T("")); return; } CEdit::OnKeyDown(nChar, nRepCnt, nFlags); }В остальном оба проекта идентичны. Итак, что же здесь происходит? Почему WindowProc игнорирует первый символ, в то время как PreTranslateMessage работает нормально?
Как мне решить эту проблему? Мне нужно заставить его работать с WindowProc, как это было раньше.