1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #ifndef UI_BASE_IME_WIN_IMM32_MANAGER_H
6 #define UI_BASE_IME_WIN_IMM32_MANAGER_H
13 #include "base/basictypes.h"
14 #include "base/i18n/rtl.h"
15 #include "base/strings/string16.h"
16 #include "ui/base/ime/text_input_mode.h"
17 #include "ui/base/ime/ui_base_ime_export.h"
18 #include "ui/gfx/geometry/rect.h"
22 struct CompositionText
;
24 // This header file defines a struct and a class used for encapsulating IMM32
25 // APIs, controls IMEs attached to a window, and enables the 'on-the-spot'
26 // input without deep knowledge about the APIs, i.e. knowledge about the
27 // language-specific and IME-specific behaviors.
28 // The following items enumerates the simplest steps for an (window)
29 // application to control its IMEs with the struct and the class defined
31 // 1. Add an instance of the IMM32Manager class to its window class.
32 // (The IMM32Manager class needs a window handle.)
33 // 2. Add messages handlers listed in the following subsections, follow the
34 // instructions written in each subsection, and use the IMM32Manager class.
35 // 2.1. WM_IME_SETCONTEXT (0x0281)
36 // Call the functions listed below:
37 // - IMM32Manager::CreateImeWindow();
38 // - IMM32Manager::CleanupComposition(), and;
39 // - IMM32Manager::SetImeWindowStyle().
40 // An application MUST prevent from calling ::DefWindowProc().
41 // 2.2. WM_IME_STARTCOMPOSITION (0x010D)
42 // Call the functions listed below:
43 // - IMM32Manager::CreateImeWindow(), and;
44 // - IMM32Manager::ResetComposition().
45 // An application MUST prevent from calling ::DefWindowProc().
46 // 2.3. WM_IME_COMPOSITION (0x010F)
47 // Call the functions listed below:
48 // - IMM32Manager::UpdateImeWindow();
49 // - IMM32Manager::GetResult();
50 // - IMM32Manager::GetComposition(), and;
51 // - IMM32Manager::ResetComposition() (optional).
52 // An application MUST prevent from calling ::DefWindowProc().
53 // 2.4. WM_IME_ENDCOMPOSITION (0x010E)
54 // Call the functions listed below:
55 // - IMM32Manager::ResetComposition(), and;
56 // - IMM32Manager::DestroyImeWindow().
57 // An application CAN call ::DefWindowProc().
58 // 2.5. WM_INPUTLANGCHANGE (0x0051)
59 // Call the functions listed below:
60 // - IMM32Manager::SetInputLanguage().
61 // An application CAN call ::DefWindowProc().
63 // This class controls the IMM (Input Method Manager) through IMM32 APIs and
64 // enables it to retrieve the string being controled by the IMM. (I wrote
65 // a note to describe the reason why I do not use 'IME' but 'IMM' below.)
67 // Fortunately or unfortunately, TSF (Text Service Framework) and
68 // CUAS (Cicero Unaware Application Support) allows IMM32 APIs for
69 // retrieving not only the inputs from IMEs (Input Method Editors), used
70 // only for inputting East-Asian language texts, but also the ones from
71 // tablets (on Windows XP Tablet PC Edition and Windows Vista), voice
72 // recognizers (e.g. ViaVoice and Microsoft Office), etc.
73 // We can disable TSF and CUAS in Windows XP Tablet PC Edition. On the other
74 // hand, we can NEVER disable either TSF or CUAS in Windows Vista, i.e.
75 // THIS CLASS IS NOT ONLY USED ON THE INPUT CONTEXTS OF EAST-ASIAN
76 // LANGUAGES BUT ALSO USED ON THE INPUT CONTEXTS OF ALL LANGUAGES.
77 class UI_BASE_IME_EXPORT IMM32Manager
{
80 virtual ~IMM32Manager();
82 // Retrieves whether or not there is an ongoing composition.
83 bool is_composing() const { return is_composing_
; }
85 // Retrieves the input language from Windows and update it.
86 void SetInputLanguage();
88 // Creates the IME windows, and allocate required resources for them.
90 // * window_handle [in] (HWND)
91 // Represents the window handle of the caller.
92 void CreateImeWindow(HWND window_handle
);
94 // Updates the style of the IME windows.
96 // * window_handle [in] (HWND)
97 // Represents the window handle of the caller.
98 // * message [in] (UINT)
99 // * wparam [in] (WPARAM)
100 // * lparam [in] (LPARAM)
101 // Represent the windows message of the caller.
102 // These parameters are used for verifying if this function is called
103 // in a handler function for WM_IME_SETCONTEXT messages because this
104 // function uses ::DefWindowProc() to update the style.
105 // A caller just has to pass the input parameters for the handler
106 // function without modifications.
107 // * handled [out] (BOOL*)
108 // Returns ::DefWindowProc() is really called in this function.
109 // PLEASE DO NOT CALL ::DefWindowProc() IF THIS VALUE IS TRUE!
110 // All the window styles set in this function are over-written when
111 // calling ::DefWindowProc() after returning this function.
112 // Returns the value returned by DefWindowProc.
113 LRESULT
SetImeWindowStyle(HWND window_handle
, UINT message
,
114 WPARAM wparam
, LPARAM lparam
, BOOL
* handled
);
116 // Destroys the IME windows and all the resources attached to them.
118 // * window_handle [in] (HWND)
119 // Represents the window handle of the caller.
120 void DestroyImeWindow(HWND window_handle
);
122 // Updates the position of the IME windows.
124 // * window_handle [in] (HWND)
125 // Represents the window handle of the caller.
126 void UpdateImeWindow(HWND window_handle
);
128 // Cleans up the all resources attached to the given IMM32Manager object, and
129 // reset its composition status.
131 // * window_handle [in] (HWND)
132 // Represents the window handle of the caller.
133 void CleanupComposition(HWND window_handle
);
135 // Resets the composition status.
136 // Cancel the ongoing composition if it exists.
137 // NOTE(hbono): This method does not release the allocated resources.
139 // * window_handle [in] (HWND)
140 // Represents the window handle of the caller.
141 void ResetComposition(HWND window_handle
);
143 // Retrieves a composition result of the ongoing composition if it exists.
145 // * window_handle [in] (HWND)
146 // Represents the window handle of the caller.
147 // * lparam [in] (LPARAM)
148 // Specifies the updated members of the ongoing composition, and must be
149 // the same parameter of a WM_IME_COMPOSITION message handler.
150 // This parameter is used for checking if the ongoing composition has
151 // its result string,
152 // * result [out] (base::string16)
153 // Represents the object contains the composition result.
156 // The ongoing composition has a composition result.
158 // The ongoing composition does not have composition results.
160 // This function is designed for being called from WM_IME_COMPOSITION
162 bool GetResult(HWND window_handle
, LPARAM lparam
, base::string16
* result
);
164 // Retrieves the current composition status of the ongoing composition.
166 // * window_handle [in] (HWND)
167 // Represents the window handle of the caller.
168 // * lparam [in] (LPARAM)
169 // Specifies the updated members of the ongoing composition, and must be
170 // the same parameter of a WM_IME_COMPOSITION message handler.
171 // This parameter is used for checking if the ongoing composition has
172 // its result string,
173 // * composition [out] (Composition)
174 // Represents the struct contains the composition status.
177 // The status of the ongoing composition is updated.
179 // The status of the ongoing composition is not updated.
181 // This function is designed for being called from WM_IME_COMPOSITION
183 bool GetComposition(HWND window_handle
, LPARAM lparam
,
184 CompositionText
* composition
);
186 // Enables the IME attached to the given window, i.e. allows user-input
187 // events to be dispatched to the IME.
189 // * window_handle [in] (HWND)
190 // Represents the window handle of the caller.
191 // * complete [in] (bool)
192 // Represents whether or not to complete the ongoing composition.
194 // After finishing the ongoing composition and close its IME windows,
195 // start another composition and display its IME windows to the given
198 // Just move the IME windows of the ongoing composition to the given
199 // position without finishing it.
200 void EnableIME(HWND window_handle
);
202 // Disables the IME attached to the given window, i.e. prohibits any
203 // user-input events from being dispatched to the IME.
204 // In Chrome, this function is used when:
205 // * a renreder process sets its input focus to a password input.
207 // * window_handle [in] (HWND)
208 // Represents the window handle of the caller.
209 void DisableIME(HWND window_handle
);
211 // Cancels an ongoing composition of the IME attached to the given window.
213 // * window_handle [in] (HWND)
214 // Represents the window handle of the caller.
215 void CancelIME(HWND window_handle
);
217 // Updates the caret position of the given window.
219 // * window_handle [in] (HWND)
220 // Represents the window handle of the caller.
221 // * caret_rect [in] (const gfx::Rect&)
222 // Represent the rectangle of the input caret.
223 // This rectangle is used for controlling the positions of IME windows.
224 void UpdateCaretRect(HWND window_handle
, const gfx::Rect
& caret_rect
);
226 // Updates the setting whether we want IME to render composition text.
227 void SetUseCompositionWindow(bool use_composition_window
);
229 // Returns the current input language id.
230 LANGID
input_language_id() const { return input_language_id_
; }
232 // Returns BCP-47 tag name of the current input language.
233 std::string
GetInputLanguageName() const;
235 // Sets conversion status corresponding to |input_mode|.
236 virtual void SetTextInputMode(HWND window_handle
, TextInputMode input_mode
);
238 // Helper functions ----------------------------------------------------------
240 // Checks if there is any RTL keyboard layout installed in the system.
241 static bool IsRTLKeyboardLayoutInstalled();
243 // Checks if the user pressed both Ctrl and right or left Shift keys to
244 // requrest to change the text direction and layout alignment explicitly.
245 // Returns true if only a Ctrl key and a Shift key are down. The desired text
246 // direction will be stored in |*direction|.
247 static bool IsCtrlShiftPressed(base::i18n::TextDirection
* direction
);
249 // Gets parameters for ::ImmSetOpenStatus and ::ImmSetConversionStatus from
251 static void ConvertInputModeToImmFlags(TextInputMode input_mode
,
252 DWORD initial_conversion_mode
,
254 DWORD
* new_conversion_mode
);
258 // Retrieves the composition information.
259 void GetCompositionInfo(HIMC imm_context
, LPARAM lparam
,
260 CompositionText
* composition
);
262 // Updates the position of the IME windows.
263 void MoveImeWindow(HWND window_handle
, HIMC imm_context
);
265 // Completes the ongoing composition if it exists.
266 void CompleteComposition(HWND window_handle
, HIMC imm_context
);
268 // Retrieves a string from the IMM.
269 bool GetString(HIMC imm_context
,
272 base::string16
* result
);
275 // Represents whether or not there is an ongoing composition in a browser
276 // process, i.e. whether or not a browser process is composing a text.
279 // The current input Language ID retrieved from Windows, which consists of:
280 // * Primary Language ID (bit 0 to bit 9), which shows a natunal language
281 // (English, Korean, Chinese, Japanese, etc.) and;
282 // * Sub-Language ID (bit 10 to bit 15), which shows a geometrical region
283 // the language is spoken (For English, United States, United Kingdom,
284 // Australia, Canada, etc.)
285 // The following list enumerates some examples for the Language ID:
286 // * "en-US" (0x0409)
287 // MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US);
288 // * "ko-KR" (0x0412)
289 // MAKELANGID(LANG_KOREAN, SUBLANG_KOREAN);
290 // * "zh-TW" (0x0404)
291 // MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_TRADITIONAL);
292 // * "zh-CN" (0x0804)
293 // MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED);
294 // * "ja-JP" (0x0411)
295 // MAKELANGID(LANG_JAPANESE, SUBLANG_JAPANESE_JAPAN), etc.
296 // (See <winnt.h> for other available values.)
297 // This Language ID is used for processing language-specific operations in
299 LANGID input_language_id_
;
301 // Represents whether or not the current input context has created a system
302 // caret to set the position of its IME candidate window.
303 // * true: it creates a system caret.
304 // * false: it does not create a system caret.
307 // The rectangle of the input caret retrieved from a renderer process.
308 gfx::Rect caret_rect_
;
310 // Indicates whether or not we want IME to render composition text.
311 bool use_composition_window_
;
313 DISALLOW_COPY_AND_ASSIGN(IMM32Manager
);
318 #endif // UI_BASE_IME_WIN_IMM32_MANAGER_H