I am facing a problem in Windows 10 Creators update where, when I try to input something to my application using IME, the first character is ignored; i.e., If I use IME to enter the japanese hiragana character 'か' by typing K & A, i end up getting only 'あ' with the K being lost. This happens to the first character only. But the exact same application works properly in Windows 7~8.
The details are as below:
The application is an MFC MDI application of the Container/Server type. Its working is really simple & straightforward. If a document is open, then when a WM_KEYDOWN is fired, dynamically create a CEdit box and enter the pressed key into the edit box. If the edit box already exists, no need to create it again. Just append the input to the contents of the edit box.
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.
Next, I create a new document again. This time, I activate the windows IME to japanese and input 'k'. Again, an edit box will get created and it will display the 'k' with wavy underlines. I input 'a' and it correctly displays the japanese character 'か'. Again, expected and correct.
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.
I copy the whole code to MDI_Sample2. But there is one little change. This time, in the view, I override the PreTranslateMessage and do the exact same process which was previously being done inside WindowProc. And remove the WindowProc override. This MDI_Sample2 works perfectly well both on Windows 7 as well as Windows 10 1709 even when the Japanese IME is active.
What I have tried:
The code for the *View.cpp for both the projects are as given below:
MDI_Sample1View.cpp
*******************
BOOL MDI_Sample1View::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
if(message == WM_CHAR)
{
int wp = static_cast<int>(wParam);
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)
{
if(pMsg->message == WM_CHAR)
{
int wp = static_cast<int>(pMsg->wParam);
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);
}
All the other files are the same as created by visual studio when I created the new project.
The CwEdit.cpp class has 2 functions namely Create to create the edit box, and an OnKeyDown which is given below:
void CwSpEdit::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
if(nChar == VK_ESCAPE)
{
SetWindowText(_T(""));
return;
}
CEdit::OnKeyDown(nChar, nRepCnt, nFlags);
}
Rest of both the projects are identical. So, what is happening here? Why does WindowProc disregard the first character while PreTranslateMessage works fine?
How do I solve this issue? I need to make it work with WindowProc as it used to.