I want to be able to support text input in a custom Windows control, just like the EDIT and rich edit controls already do, but not subclassing either of those. The control currently uses Direct2D and DirectWrite to draw text, and runs on Windows Vista SP1 with Platform Update or newer (I might change it to Windows 7 SP1 with Platform Update or newer if I decide I need newer Direct2D and DirectWrite features, assuming those are available there or on Windows 8 only, but that's a different question...)
For what it's worth, on OS X I would use NSTextInputClient and on GTK+ I would use GtkIMContext. It's things like these that I'm talking about.
The obvious choice is to use WM_CHAR
, which if I gather correctly, is natively UTF-16 if the window class is registered with RegisterClassW()
, and therefore should "just work" regardless of location. However, WM_CHAR
is generated by TranslateMessage()
, and its documentation says there is no way to determine whether a WM_CHAR
has been generated or not, since TranslateMessage()
always returns nonzero. I need to be able to determine whether the current keyboard message will be handled by the text system (and thus should be ignored); this is especially true since all non-text keys need to be handled in a layout-independent way (which I already have).
I've also seen in the Windows 7 samples code for both the IMM API and the Text Services Framework. I'm not sure whether one is better than the other, and they both seem to do the same thing. Do they?
In the case of IMM, there are a number of WM_IMM_xxx
messages that I'm not sure if I should be ignoring or not, and every reference I've found seems to disagree as to whether I should handle them in a Unicode window or not... Also, the above problem of knowing if a given key event will be handled by IMM or not is still open; is there a way?
TSF has a concept called ACP, which seems to allow me to use whatever text storage format I want for storing the text I'm actually going to use (that is, not an in-progress composition). Is this true? I'd like to be able to store my text as UTF-8 with attributes, converting to UTF-16 when drawing (for DirectWrite). Do the other API choices also let me do this?
Or am I completely on the wrong path?
And how would I opt into the on-screen keyboard once I do all of that?
Other references I used:
Thanks.
UPDATE 7 Nov 2016
After looking at the TsfPad sample again, I notice it also seems to just use WM_CHAR
; now I'm not sure how it even uses TSF, other than that it does...
The TSF API is a superset of the IMM API. It's also newer than IMM, and is the current, modern way to handle international text input (as well as other input mechanisms like handwriting and speech).
If you use the TSF API, text appears via the API instead of windows messages (so the issue of which message is irrelevant).
The On-Screen keyboard is handled automatically, and you shouldn't have to worry about it. (The entire purpose of TSF is to make your app independent of input source.)
TSF can support UTF-8, but it's a bit of a pain; you need to mark the extension characters as hidden. You would be much better off with UTF-16, which is TSF's default API.
The best example I know of on how to add TSF support to an existing edit control is still the article I wrote back in July 2007.
Input can still arrive via WM_CHAR (if the current input profile is a keyboard layout, for example), so you need to implement this as well; typically, though, you can handle WM_CHAR messages by calling into your ITextStoreACP::InsertTextAtSelection implementation.