![]() |
![]() |
Input Method Editors
An input method editor, or IME, is a program that allows users to enter complex characters with a standard keyboard. Using IMEs, a user can type in complex character in a word processor. A massive-multiplayer-online-game player can chat with her friends directly in languages with complex characters, such as Chinese, Japanese, and Korean. This document explains how a full-screen application can extends a basic edit control to implement IME functionalities. This will provide detailed guidance for the IME messages that needed to be implemented by your application.
Complex characters, such as those found in East Asian languages, are not composed of alphabets similar to English. Therefore, characters cannot be entered by simply typing the alphabets. There needs to be alternative ways for users to enter these characters using a standard keyboard with letter keys on it. IMEs solve this problem by intercepting keyboard input and mapping the input to elements, such as phonetic components, that make sense with the language. The user can use the keys to enter a valid pronunciation. If the IME recognizes the pronunciation as valid, it can present the user with a list of potential word or phrase candidates from which the user can select his or her final choice. The chosen word then gets sent to the application via a series of WM_CHAR messages. Because the IME works at a level below the application by intercepting the keyboard input, the presence of an IME is transparent to the application. Therefore, an application does not require special coding to utilize IMEs. Almost all Windows applications can readily take advantage of IMEs without being aware of their existence. Typically, an IME displays several windows to provide the user with information on the character entry. Figure 1 shows the most common visual elements an IME may show. The reading window contains the current reading string of the IME. This reading string echoes what the user types and typically changes after each keystroke by the user. The composition string is the collection of characters that the user has composed with the IME. This string is drawn by the IME on top of the application. When the user is satisfied with the composition string, she can notify the IME and the IME then sends the composition string to the application via a series of WM_CHAR messages. The candidate window can be brought up when the user has entered a valid pronunciation. Because there may be more than one character with the same pronunciation, the IME cannot tell which character the user intends to enter. Therefore, the IME presents a list of candidate characters all with the pronunciation entered, and the user can choose the character she wants from the list. The input locale indicator, often embedded in the taskbar, shows the language that the user enters in when she types the keys.
In the latest DirectX Sample Framework, the IME functionalities are implemented in the CDXUTIMEEditBox class. This class is derived from CDXUTEditBox, the basic edit control provided by the framework. CDXUTIMEEditBox extends that edit control to support IME by overriding its class methods. The classes are designed this way to help users learn what they need to take from the framework to implement IME support in their own edit controls. The rest of this document explains how the framework, CDXUTIMEEditBox in particular, overrides a basic edit control to implement IME functionalities. Most of the IME-specific variables in CDXUTIMEEditBox are declared as static. This is done because many IME buffers and states are specific to the process. For instance, a process has one and only one buffer for composition string. Even if the process has 10 edit controls, they will all be sharing the same composition string buffer. Therefore, it is logical for CDXUTIMEEditBox's own composition string buffer to be static so that the application does not take up unnecessary memory space by giving each instance of CDXUTIMEEditBox its own buffer for composition string.
By default, when an IME needs to have an IME window drawn, it asks Windows to do it. Windows draws the IME window as a standard USER32 window with a HWND. Under normal circumstances, this produces satisfactory result. However, when the application goes to full-screen mode, standard windows no longer work and may not display on top of the application. To overcome this issue, the application must draw the IME windows itself instead of relying on Windows to perform this task. IMEs are designed to be customizable by applications. When the default behavior does not provide what an application requires, it can override the IME handling with precisely what it needs. An application can achieve this by processing IME-related messages and calling the Input Method Manager (IMM) API. When a user interacts with an IME to input complex characters, the IME sends messages to the application to notify it of important events, such as starting a composition or showing the candidate window. An application typically ignores these messages and passes them to the default message handler, which causes the IME to handle them. When the application, instead of the default handler, handles the messages, it controls exactly what happens at each of the IME events. Often, the message handler retrieves the content of the various IME windows by calling the Input Method Manager API. Once the application has this information, it can properly draw the IME windows itself when it needs to render its screen.
The IME-related messages that must be properly handled for using IMEs with full-screen applications are listed below:
The following sections explain the message handling in detail.
There are several important tasks that CDXUTIMEEditBox must perform when such a message is sent. The first of them is calling GetKeyboardLayout(). This returns the input locale ID for the application thread. The CDXUTIMEEditBox class saves this ID in its static member variable s_hklCurrent for use later. When supporting IME, knowing the current input language is important because each language IME has its own distinct behavior. Therefore, it is sometimes necessary to have multiple code paths based on the input language. Once the input language is known, CDXUTIMEEditBox initializes the string to display for the editbox's own language indicator. This indicator allows users to know the active input language when running the application in full-screen mode, as the taskbar or language bar is not visible in such mode. Next, the state of the IME is determined by inspecting the IME conversion status, available by calling ImmGetConversionStatus(). This information is necessary because each input language can be in native or non-native conversion mode. Native conversion mode lets the user enter text in the particular language chosen. Non-native conversion mode makes the keyboard act as a standard English keyboard. It is important to give users visual cue as to what type of conversion mode the IME is in, so they can easily know what characters to expect when hitting a key. CDXUTIMEEditBox provides this visual cue by the language indicator color. When the input language uses an IME and the IME is in native conversion mode, the class uses the m_IndicatorImeColor member color to draw the indicator text. When the language uses an IME and the IME is in non-native conversion mode, or the language does not use an IME at all, the class uses the m_IndicatorEngColor member color to draw the indicator text. The next thing that CDXUTIMEEditBox does when handling WM_INPUTLANGCHANGE is checking the input language and setting the static member variable s_bInsertOnType to true for Korean and false for all other languages. The reason that this flag is required is due to the different behaviors of Korean IME and all other IMEs. When inputting in non-Korean, the text that the user enters is displayed in the composition window. The user can freely change the content of the composition string. When the user is satisfied with the composition string, she hits Enter and the composition string is sent to the application as a series of WM_CHAR. In Korean, however, when a user hits a key to enter text, a character is immediately sent to the application. When the user subsequently hits more keys to modify that initial character, the character in the editbox changes to reflect additional input from the user. Essentially, the user is composing characters in the editbox. These two behaviors are different enough that CDXUTIMEEditBox must code for each of them specifically. After all of the above are complete, the handler calls the static member method SetupImeApi(). The purpose of this method is to retrieve addresses of two functions from the IME module: GetReadingString() and ShowReadingWindow(). These functions are useful for supporting IME, so CDXUTIMEEditBox utilizes them if they exist. Immediately after, ShowReadingWindow() is called to hide the reading window for this particular IME. Because the application is rendering the reading window itself, it notifies the IME to disable drawing the window so that it will not interfere with the full-screen rendering.
WM_IME_SETCONTEXT
WM_IME_STARTCOMPOSITION
WM_IME_COMPOSITION
WM_IME_ENDCOMPOSITION
WM_IME_NOTIFY
The rendering of the IME elements/windows is straightforward. CDXUTIMEEditBox lets the base class render first because IME windows should appear on top of the edit control. After the base editbox is rendered, CDXUTIMEEditBox checks the visible flag of each of the IME window (indicator, composition, candidate, reading) and draws it if it should be visible. The sections below go over the operation in more details.
Language Indicator
Composition Window
Reading Window/Candidate Window
IMEs sometimes contain advanced features to aid with better text input experience. Figure 4, 5, and 6 show some of the features found in newer IMEs. These advanced features are not present in the DirectX Sample Framework in the Summer 2004 SDK Update. Implementing support for these advanced features is a difficult task because there is no interface defined to get the necessary information from IMEs.
Input Method Editors allow easy text entry in East Asian languages and other languages with complex characters, making applications user-friendly in regions where those particular languages are used. Applications that take advantage of the new DirectX Sample Framework already get IME functionalities. For applications that do not make use of the framework, this document helps the developers add IME support by detailing how a non-IME-enabled editbox can be extended to receive the benefit of IME. Developers can choose one of the two approaches by considering the needs of their applications.
|