feat(window): add ime input event
This commit is contained in:
parent
612a4cd21d
commit
6731b7dd3d
|
|
@ -162,10 +162,15 @@ void ImGuiModule::HandleEvent(EventModuleContext& ctx)
|
|||
}
|
||||
else if (evt->IsType<KeyCharEvent>())
|
||||
{
|
||||
// You can also use ToAscii()+GetKeyboardState() to retrieve characters.
|
||||
char ch = dynamic_cast<KeyCharEvent*>(evt)->value;
|
||||
io.AddInputCharacter(static_cast<ImWchar>(ch));
|
||||
}
|
||||
else if (evt->IsType<IMEInputEvent>())
|
||||
{
|
||||
const auto& str = dynamic_cast<IMEInputEvent*>(evt)->value;
|
||||
const auto utf8_str = strings::WideToUTF8(strings::NarrowToWide(str));
|
||||
io.AddInputCharactersUTF8(utf8_str.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -81,40 +81,60 @@ WideString FormatArgs(const wchar_t* format, va_list args)
|
|||
return result;
|
||||
}
|
||||
|
||||
String WideToNarrow(const WideString& str)
|
||||
String WideToNarrowWithCodePage(const WideString& str, UINT code_page)
|
||||
{
|
||||
if (str.empty())
|
||||
return String();
|
||||
|
||||
int len = ::WideCharToMultiByte(CP_ACP, 0, str.c_str(), -1, NULL, 0, NULL, NULL);
|
||||
int len = ::WideCharToMultiByte(code_page, 0, str.c_str(), -1, NULL, 0, NULL, NULL);
|
||||
if (len > 0)
|
||||
{
|
||||
String result;
|
||||
result.resize(len - 1);
|
||||
|
||||
::WideCharToMultiByte(CP_ACP, 0, str.c_str(), -1, &result[0], len, NULL, NULL);
|
||||
::WideCharToMultiByte(code_page, 0, str.c_str(), -1, &result[0], len, NULL, NULL);
|
||||
return result;
|
||||
}
|
||||
return String();
|
||||
}
|
||||
|
||||
WideString NarrowToWide(const String& str)
|
||||
WideString NarrowToWideWithCodePage(const String& str, UINT code_page)
|
||||
{
|
||||
if (str.empty())
|
||||
return WideString();
|
||||
|
||||
int len = ::MultiByteToWideChar(CP_ACP, 0, str.c_str(), -1, NULL, 0);
|
||||
int len = ::MultiByteToWideChar(code_page, 0, str.c_str(), -1, NULL, 0);
|
||||
if (len > 0)
|
||||
{
|
||||
WideString result;
|
||||
result.resize(len - 1);
|
||||
|
||||
::MultiByteToWideChar(CP_ACP, 0, str.c_str(), -1, &result[0], len);
|
||||
::MultiByteToWideChar(code_page, 0, str.c_str(), -1, &result[0], len);
|
||||
return result;
|
||||
}
|
||||
return WideString();
|
||||
}
|
||||
|
||||
String WideToNarrow(const WideString& str)
|
||||
{
|
||||
return WideToNarrowWithCodePage(str, CP_ACP);
|
||||
}
|
||||
|
||||
WideString NarrowToWide(const String& str)
|
||||
{
|
||||
return NarrowToWideWithCodePage(str, CP_ACP);
|
||||
}
|
||||
|
||||
String WideToUTF8(const WideString& str)
|
||||
{
|
||||
return WideToNarrowWithCodePage(str, CP_UTF8);
|
||||
}
|
||||
|
||||
WideString UTF8ToWide(const String& str)
|
||||
{
|
||||
return NarrowToWideWithCodePage(str, CP_UTF8);
|
||||
}
|
||||
|
||||
#endif // KGE_PLATFORM_WINDOWS
|
||||
|
||||
} // namespace string
|
||||
|
|
|
|||
|
|
@ -66,6 +66,14 @@ String WideToNarrow(const WideString& str);
|
|||
/// @brief Õ×Ö·û´®×ª¿í×Ö·û´®
|
||||
WideString NarrowToWide(const String& str);
|
||||
|
||||
/// \~chinese
|
||||
/// @brief ¿í×Ö·û´®×ª utf8 ×Ö·û´®
|
||||
String WideToUTF8(const WideString& str);
|
||||
|
||||
/// \~chinese
|
||||
/// @brief utf8 ×Ö·û´®×ª¿í×Ö·û´®
|
||||
WideString UTF8ToWide(const String& str);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -26,4 +26,10 @@ KeyCharEvent::KeyCharEvent()
|
|||
{
|
||||
}
|
||||
|
||||
IMEInputEvent::IMEInputEvent()
|
||||
: KeyEvent(KGE_EVENT(IMEInputEvent))
|
||||
, value()
|
||||
{
|
||||
}
|
||||
|
||||
} // namespace kiwano
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ KGE_DECLARE_SMART_PTR(KeyEvent);
|
|||
KGE_DECLARE_SMART_PTR(KeyDownEvent);
|
||||
KGE_DECLARE_SMART_PTR(KeyUpEvent);
|
||||
KGE_DECLARE_SMART_PTR(KeyCharEvent);
|
||||
KGE_DECLARE_SMART_PTR(IMEInputEvent);
|
||||
|
||||
/**
|
||||
* \addtogroup Event
|
||||
|
|
@ -72,13 +73,23 @@ public:
|
|||
KeyCharEvent();
|
||||
};
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 输入法输入事件
|
||||
class KGE_API IMEInputEvent : public KeyEvent
|
||||
{
|
||||
public:
|
||||
String value; ///< 输入内容
|
||||
|
||||
IMEInputEvent();
|
||||
};
|
||||
|
||||
template <>
|
||||
struct IsSameEventType<KeyEvent>
|
||||
{
|
||||
inline bool operator()(const Event* evt) const
|
||||
{
|
||||
return evt->GetType() == KGE_EVENT(KeyDownEvent) || evt->GetType() == KGE_EVENT(KeyUpEvent)
|
||||
|| evt->GetType() == KGE_EVENT(KeyCharEvent);
|
||||
|| evt->GetType() == KGE_EVENT(KeyCharEvent) || evt->GetType() == KGE_EVENT(IMEInputEvent);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -305,7 +305,7 @@ void WindowWin32Impl::Init(const WindowConfig& config)
|
|||
::SetWindowPos(handle_, HWND_TOPMOST, x, y, cx, cy, SWP_NOACTIVATE);
|
||||
::ShowWindow(handle_, SW_SHOWNORMAL);
|
||||
|
||||
resolution_.width = config.width;
|
||||
resolution_.width = config.width;
|
||||
resolution_.height = config.height;
|
||||
}
|
||||
else
|
||||
|
|
@ -552,6 +552,38 @@ LRESULT WindowWin32Impl::MessageProc(HWND hwnd, UINT32 msg, WPARAM wparam, LPARA
|
|||
}
|
||||
break;
|
||||
|
||||
case WM_IME_CHAR:
|
||||
{
|
||||
// no need to handle
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
case WM_IME_COMPOSITION:
|
||||
{
|
||||
if (lparam & GCS_RESULTSTR)
|
||||
{
|
||||
const auto hIMC = ::ImmGetContext(hwnd);
|
||||
if (hIMC)
|
||||
{
|
||||
// Get the size of the result string.
|
||||
auto dwSize = ::ImmGetCompositionStringA(hIMC, GCS_RESULTSTR, NULL, 0);
|
||||
|
||||
// increase buffer size for terminating null character
|
||||
dwSize += sizeof(char);
|
||||
|
||||
// Get the result strings that is generated by IME.
|
||||
String buf(size_t(dwSize), 0);
|
||||
::ImmGetCompositionStringA(hIMC, GCS_RESULTSTR, const_cast<char*>(buf.data()), dwSize);
|
||||
::ImmReleaseContext(hwnd, hIMC);
|
||||
|
||||
IMEInputEventPtr evt = new IMEInputEvent;
|
||||
evt->value = std::move(buf);
|
||||
this->PushEvent(evt);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
case WM_LBUTTONDOWN:
|
||||
case WM_LBUTTONDBLCLK:
|
||||
case WM_RBUTTONDOWN:
|
||||
|
|
@ -742,7 +774,7 @@ LRESULT WindowWin32Impl::MessageProc(HWND hwnd, UINT32 msg, WPARAM wparam, LPARA
|
|||
if (max_width_ && max_height_)
|
||||
{
|
||||
((MINMAXINFO*)lparam)->ptMaxTrackSize = POINT{ LONG(max_width_), LONG(max_height_) };
|
||||
((MINMAXINFO*)lparam)->ptMaxSize = POINT{ LONG(max_width_), LONG(max_height_) };
|
||||
((MINMAXINFO*)lparam)->ptMaxSize = POINT{ LONG(max_width_), LONG(max_height_) };
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue