need help to improve CJK support

stoneworks

16-05-2012 09:56:38

First of all, thank you for great piece of work you've done so far.

I'm trying to use MyGUI(v3.2) for my private project, and found :
- *current* IME Candidates or compositions are not showing (JK)
- wierd output (J)

Spent a few days searching and testing IME-related part of the codes,
I'm sharing what I've done so far. (Tested on Korean, Japanese IME only)

Still, IME Candidates window is not showing, but it's enough for me now.
And more test needed with Chinese/Japanese IME.

I hope my little patch could be part of MyGUI trunk someday.

Enjoy!

1. in MyGUIEngine/include/MyGUI_KeyCode.h:180

MediaSelect = 0xED,
IMEComposition = 0xEF, /* IME Composition */
};


2. in MyGUIEngine/include/MyGUI_EditBox.h:370

size_t mTextLength;
// IME composition string
UString mIMEComposition;

// выделение


3. in MyGUIEngine/src/MyGUI_EditBox.cpp:645

}
else if (_key == KeyCode::IMEComposition && !mModeReadOnly)
{
switch (_char)
{
case KeyCode::Backspace : // clear
if (mIMEComposition.size() > 0)
{
mCursorPosition -= mIMEComposition.size();
eraseText(mCursorPosition, mIMEComposition.size(), false);
mIMEComposition.clear();
}
break;
case KeyCode::End : // end of IME Composition string
// change composition str
insertText(mIMEComposition, mCursorPosition, false);
break;
case KeyCode::Return : // Composition complete
insertText(mIMEComposition, mCursorPosition, true);
mIMEComposition.clear();
break;
default :
mIMEComposition.append(1, _char);
break;
}
}
else if (_char != 0)
{


4. in Common/Input/Win32/InputManager.cpp:162

}
// else if (WM_IME_CHAR == uMsg)
// {
// int text = 0;
//#ifdef _UNICODE
// text = wParam;
//#else
// char mbstr[3];
// BYTE hiByte = wParam >> 8;
// BYTE loByte = wParam & 0x000000FF;
// if (hiByte == 0)
// {
// mbstr[0] = loByte;
// mbstr[1] = '\0';
// }
// else
// {
// mbstr[0] = hiByte;
// mbstr[1] = loByte;
// mbstr[2] = '\0';
// }
//
// wchar_t wstr[2];
// /*int num = */MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, mbstr, -1, wstr, _countof(wstr));
// text = wstr[0];
//#endif // _UNICODE
// msInputManager->injectKeyPress(MyGUI::KeyCode::None, (MyGUI::Char)text);
// return 0;
// }
else if (WM_IME_COMPOSITION == uMsg)
{
if (lParam & GCS_COMPSTR)
{
HIMC hIMC = ImmGetContext(hWnd);
DWORD dwSize = ImmGetCompositionString(hIMC, GCS_COMPSTR, NULL, 0);
size_t bufSize = dwSize / sizeof(TCHAR);

msInputManager->injectKeyPress(MyGUI::KeyCode::IMEComposition, MyGUI::KeyCode::Backspace);

if (dwSize > 0)
{
std::vector<TCHAR> buf(bufSize + 1, 0);

ImmGetCompositionString(hIMC, GCS_COMPSTR, &buf.front(), dwSize);
ImmReleaseContext(hWnd, hIMC);

for (int i = 0; i < bufSize; ++i)
{
msInputManager->injectKeyPress(MyGUI::KeyCode::IMEComposition, (MyGUI::Char)buf);
}

msInputManager->injectKeyPress(MyGUI::KeyCode::IMEComposition, MyGUI::KeyCode::End);
}
}
else if (lParam & GCS_RESULTSTR)
{
HIMC hIMC = ImmGetContext(hWnd);
DWORD dwSize = ImmGetCompositionString(hIMC, GCS_RESULTSTR, NULL, 0);
size_t bufSize = dwSize / sizeof(TCHAR);

msInputManager->injectKeyPress(MyGUI::KeyCode::IMEComposition, MyGUI::KeyCode::Backspace);

if (dwSize > 0)
{
std::vector<TCHAR> buf(bufSize + 1, 0);

ImmGetCompositionString(hIMC, GCS_RESULTSTR, &buf.front(), dwSize);
ImmReleaseContext(hWnd, hIMC);

for (int i = 0; i < bufSize; ++i)
{
msInputManager->injectKeyPress(MyGUI::KeyCode::IMEComposition, (MyGUI::Char)buf);
}

msInputManager->injectKeyPress(MyGUI::KeyCode::IMEComposition, MyGUI::KeyCode::Return);
}

return 0; // message handled
}
}
else if (WM_KEYUP == uMsg)