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>())
|
else if (evt->IsType<KeyCharEvent>())
|
||||||
{
|
{
|
||||||
// You can also use ToAscii()+GetKeyboardState() to retrieve characters.
|
|
||||||
char ch = dynamic_cast<KeyCharEvent*>(evt)->value;
|
char ch = dynamic_cast<KeyCharEvent*>(evt)->value;
|
||||||
io.AddInputCharacter(static_cast<ImWchar>(ch));
|
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;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
String WideToNarrow(const WideString& str)
|
String WideToNarrowWithCodePage(const WideString& str, UINT code_page)
|
||||||
{
|
{
|
||||||
if (str.empty())
|
if (str.empty())
|
||||||
return String();
|
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)
|
if (len > 0)
|
||||||
{
|
{
|
||||||
String result;
|
String result;
|
||||||
result.resize(len - 1);
|
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 result;
|
||||||
}
|
}
|
||||||
return String();
|
return String();
|
||||||
}
|
}
|
||||||
|
|
||||||
WideString NarrowToWide(const String& str)
|
WideString NarrowToWideWithCodePage(const String& str, UINT code_page)
|
||||||
{
|
{
|
||||||
if (str.empty())
|
if (str.empty())
|
||||||
return WideString();
|
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)
|
if (len > 0)
|
||||||
{
|
{
|
||||||
WideString result;
|
WideString result;
|
||||||
result.resize(len - 1);
|
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 result;
|
||||||
}
|
}
|
||||||
return WideString();
|
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
|
#endif // KGE_PLATFORM_WINDOWS
|
||||||
|
|
||||||
} // namespace string
|
} // namespace string
|
||||||
|
|
|
||||||
|
|
@ -66,6 +66,14 @@ String WideToNarrow(const WideString& str);
|
||||||
/// @brief Õ×Ö·û´®×ª¿í×Ö·û´®
|
/// @brief Õ×Ö·û´®×ª¿í×Ö·û´®
|
||||||
WideString NarrowToWide(const String& str);
|
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
|
} // namespace kiwano
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,7 @@ KGE_DECLARE_SMART_PTR(KeyEvent);
|
||||||
KGE_DECLARE_SMART_PTR(KeyDownEvent);
|
KGE_DECLARE_SMART_PTR(KeyDownEvent);
|
||||||
KGE_DECLARE_SMART_PTR(KeyUpEvent);
|
KGE_DECLARE_SMART_PTR(KeyUpEvent);
|
||||||
KGE_DECLARE_SMART_PTR(KeyCharEvent);
|
KGE_DECLARE_SMART_PTR(KeyCharEvent);
|
||||||
|
KGE_DECLARE_SMART_PTR(IMEInputEvent);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \addtogroup Event
|
* \addtogroup Event
|
||||||
|
|
@ -72,13 +73,23 @@ public:
|
||||||
KeyCharEvent();
|
KeyCharEvent();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// \~chinese
|
||||||
|
/// @brief 输入法输入事件
|
||||||
|
class KGE_API IMEInputEvent : public KeyEvent
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
String value; ///< 输入内容
|
||||||
|
|
||||||
|
IMEInputEvent();
|
||||||
|
};
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
struct IsSameEventType<KeyEvent>
|
struct IsSameEventType<KeyEvent>
|
||||||
{
|
{
|
||||||
inline bool operator()(const Event* evt) const
|
inline bool operator()(const Event* evt) const
|
||||||
{
|
{
|
||||||
return evt->GetType() == KGE_EVENT(KeyDownEvent) || evt->GetType() == KGE_EVENT(KeyUpEvent)
|
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);
|
::SetWindowPos(handle_, HWND_TOPMOST, x, y, cx, cy, SWP_NOACTIVATE);
|
||||||
::ShowWindow(handle_, SW_SHOWNORMAL);
|
::ShowWindow(handle_, SW_SHOWNORMAL);
|
||||||
|
|
||||||
resolution_.width = config.width;
|
resolution_.width = config.width;
|
||||||
resolution_.height = config.height;
|
resolution_.height = config.height;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
@ -552,6 +552,38 @@ LRESULT WindowWin32Impl::MessageProc(HWND hwnd, UINT32 msg, WPARAM wparam, LPARA
|
||||||
}
|
}
|
||||||
break;
|
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_LBUTTONDOWN:
|
||||||
case WM_LBUTTONDBLCLK:
|
case WM_LBUTTONDBLCLK:
|
||||||
case WM_RBUTTONDOWN:
|
case WM_RBUTTONDOWN:
|
||||||
|
|
@ -742,7 +774,7 @@ LRESULT WindowWin32Impl::MessageProc(HWND hwnd, UINT32 msg, WPARAM wparam, LPARA
|
||||||
if (max_width_ && max_height_)
|
if (max_width_ && max_height_)
|
||||||
{
|
{
|
||||||
((MINMAXINFO*)lparam)->ptMaxTrackSize = POINT{ LONG(max_width_), LONG(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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue