11 #include "flutter/fml/logging.h"
12 #include "flutter/fml/macros.h"
20 : context_(::ImmGetContext(window_handle)),
21 window_handle_(window_handle) {
22 FML_DCHECK(window_handle);
26 if (context_ !=
nullptr) {
27 ::ImmReleaseContext(window_handle_, context_);
32 bool IsValid()
const {
return context_ !=
nullptr; }
48 window_handle_ = window_handle;
52 if (window_handle_ ==
nullptr) {
60 ::CreateCaret(window_handle_,
nullptr, 1, 1);
69 if (window_handle_ ==
nullptr) {
81 if (window_handle_ ==
nullptr) {
87 MoveImeWindow(imm_context.
get());
94 if (window_handle_ ==
nullptr) {
100 MoveImeWindow(imm_context.
get());
105 if (window_handle_ ==
nullptr) {
112 return ImmGetCompositionString(imm_context.
get(), GCS_CURSORPOS,
nullptr,
119 return GetString(GCS_COMPSTR);
123 return GetString(GCS_RESULTSTR);
127 if (window_handle_ ==
nullptr || !ime_active_) {
134 ::ImmNotifyIME(imm_context.
get(), NI_COMPOSITIONSTR, CPS_CANCEL, 0);
135 ::ImmNotifyIME(imm_context.
get(), NI_CLOSECANDIDATE, 0, 0);
138 wchar_t composition_str[] = L
"";
139 wchar_t reading_str[] = L
"";
140 ::ImmSetCompositionStringW(imm_context.
get(), SCS_SETSTR, composition_str,
141 sizeof(
wchar_t), reading_str,
sizeof(
wchar_t));
145 std::optional<std::u16string> TextInputManager::GetString(
int type)
const {
146 if (window_handle_ ==
nullptr || !ime_active_) {
149 ImmContext imm_context(window_handle_);
150 if (imm_context.IsValid()) {
152 const long compose_bytes =
153 ::ImmGetCompositionString(imm_context.get(),
type,
nullptr, 0);
154 const long compose_length = compose_bytes /
sizeof(wchar_t);
155 if (compose_length < 0) {
159 std::u16string
text(compose_length,
'\0');
160 ::ImmGetCompositionString(imm_context.get(),
type, &
text[0], compose_bytes);
166 void TextInputManager::MoveImeWindow(HIMC imm_context) {
167 if (GetFocus() != window_handle_ || !ime_active_) {
170 LONG left = caret_rect_.
left();
171 LONG top = caret_rect_.
top();
172 LONG right = caret_rect_.
right();
173 LONG bottom = caret_rect_.
bottom();
174 ::SetCaretPos(left, bottom);
177 COMPOSITIONFORM composition_form = {CFS_POINT, {left, top}};
178 ::ImmSetCompositionWindow(imm_context, &composition_form);
181 CANDIDATEFORM candidate_form = {
182 0, CFS_EXCLUDE, {left, bottom}, {left, top, right, bottom}};
183 ::ImmSetCandidateWindow(imm_context, &candidate_form);