Mercurial > sdl-ios-xcode
comparison EXCLUDE/GLIMM/src/IMM.cpp @ 4741:bb189d44af16
Added GLIMM (using IMM instead of TSF)
Uses small bit of TSF to fully disable cicero (TSF for non-TSF enabled apps)
author | dewyatt |
---|---|
date | Wed, 30 Jun 2010 17:29:20 -0400 |
parents | |
children | 0aaa54fbd2bc |
comparison
equal
deleted
inserted
replaced
4740:abf528de6d2e | 4741:bb189d44af16 |
---|---|
1 #include "IMM.hpp" | |
2 #include <stdexcept> | |
3 | |
4 IMM::IMM() : my_COM_Initialized(false), | |
5 my_Thread_Manager(0), | |
6 my_Window(0), | |
7 my_Context(0), | |
8 my_HKL(0), | |
9 my_Vertical_Candidates(false) | |
10 { | |
11 | |
12 } | |
13 | |
14 IMM::~IMM() | |
15 { | |
16 Finalize(); | |
17 } | |
18 | |
19 void IMM::Initialize(HWND Window) | |
20 { | |
21 Finalize(); | |
22 | |
23 my_Window = Window; | |
24 | |
25 if (SUCCEEDED(CoInitializeEx(NULL, COINIT_APARTMENTTHREADED))) | |
26 { | |
27 my_COM_Initialized = true; | |
28 if (SUCCEEDED(CoCreateInstance(CLSID_TF_ThreadMgr, NULL, CLSCTX_INPROC_SERVER, IID_ITfThreadMgr, reinterpret_cast<LPVOID *>(&my_Thread_Manager)))) | |
29 { | |
30 ITfDocumentMgr *Document_Manager = 0; | |
31 if (FAILED(my_Thread_Manager->AssociateFocus(Window, NULL, &Document_Manager))) | |
32 printf("Warning: ITfThreadMgr->AssociateFocus failed\n"); | |
33 | |
34 if (Document_Manager) | |
35 Document_Manager->Release(); | |
36 } | |
37 else | |
38 printf("Warning: Failed to create ITfThreadMgr instance\n"); | |
39 } | |
40 else | |
41 printf("Warning: Failed to initialize COM\n"); | |
42 | |
43 ImmDisableTextFrameService(-1); | |
44 | |
45 my_Context = ImmGetContext(my_Window); | |
46 if (!ImmReleaseContext(my_Window, my_Context)) | |
47 throw std::runtime_error("Error releasing context"); | |
48 | |
49 if (!my_Context) | |
50 throw std::runtime_error("No context"); | |
51 | |
52 Update_Input_Locale(); | |
53 } | |
54 | |
55 void IMM::Finalize() | |
56 { | |
57 if (my_Thread_Manager) | |
58 { | |
59 my_Thread_Manager->Release(); | |
60 my_Thread_Manager = 0; | |
61 } | |
62 if (my_COM_Initialized) | |
63 { | |
64 CoUninitialize(); | |
65 my_COM_Initialized = false; | |
66 } | |
67 } | |
68 | |
69 #define GET_LANG(hkl) LOWORD((hkl)) | |
70 #define GET_PRIMLANG(hkl) ((WORD)PRIMARYLANGID(GET_LANG((hkl)))) | |
71 #define GET_SUBLANG(hkl) SUBLANGID(GET_LANG((hkl))) | |
72 | |
73 void IMM::Update_Input_Locale() | |
74 { | |
75 static HKL Previous_HKL = 0; | |
76 my_HKL = GetKeyboardLayout(0); | |
77 if (Previous_HKL == my_HKL) | |
78 return; | |
79 | |
80 Previous_HKL = my_HKL; | |
81 my_Vertical_Candidates = false; | |
82 switch (GET_PRIMLANG(my_HKL)) | |
83 { | |
84 case LANG_CHINESE: | |
85 my_Vertical_Candidates = true; | |
86 switch (GET_SUBLANG(my_HKL)) | |
87 { | |
88 case SUBLANG_CHINESE_SIMPLIFIED: | |
89 my_Vertical_Candidates = false; | |
90 break; | |
91 } | |
92 break; | |
93 case LANG_JAPANESE: | |
94 my_Vertical_Candidates = true; | |
95 break; | |
96 } | |
97 } | |
98 | |
99 LRESULT IMM::Handle_Message(HWND Window, UINT Message, WPARAM wParam, LPARAM lParam, bool &Ate) | |
100 { | |
101 Ate = false; | |
102 switch (Message) | |
103 { | |
104 case WM_INPUTLANGCHANGE: | |
105 Update_Input_Locale(); | |
106 break; | |
107 case WM_IME_SETCONTEXT: | |
108 lParam = 0; | |
109 return DefWindowProcW(my_Window, Message, wParam, lParam); | |
110 break; | |
111 case WM_IME_STARTCOMPOSITION: | |
112 Ate = true; | |
113 break; | |
114 case WM_IME_COMPOSITION: | |
115 { | |
116 Ate = true; | |
117 HIMC Context = ImmGetContext(Window); | |
118 if (!Context) | |
119 break; | |
120 | |
121 if (lParam & GCS_RESULTSTR) | |
122 { | |
123 LONG Length = ImmGetCompositionStringW(Context, GCS_RESULTSTR, 0, 0); | |
124 std::wstring Composition(Length / sizeof(wchar_t), 0); | |
125 Length = ImmGetCompositionStringW(Context, GCS_RESULTSTR, &Composition[0], Composition.size() * sizeof(Composition[0])); | |
126 printf("GCS_RESULTSTR: "); | |
127 for (LONG i = 0; i < Length / sizeof(wchar_t); ++i) | |
128 printf("U+%04X ", Composition[i]); | |
129 | |
130 printf("\n"); | |
131 } | |
132 if (lParam & GCS_COMPSTR) | |
133 { | |
134 LONG Length = ImmGetCompositionStringW(Context, GCS_COMPSTR, 0, 0); | |
135 std::wstring Composition(Length / sizeof(wchar_t), 0); | |
136 Length = ImmGetCompositionStringW(Context, GCS_COMPSTR, &Composition[0], Composition.size() * sizeof(Composition[0])); | |
137 printf("GCS_COMPSTR: "); | |
138 for (LONG i = 0; i < Length / sizeof(wchar_t); ++i) | |
139 printf("U+%04X ", Composition[i]); | |
140 | |
141 printf("\n"); | |
142 } | |
143 ImmReleaseContext(Window, Context); | |
144 } | |
145 break; | |
146 case WM_IME_ENDCOMPOSITION: | |
147 break; | |
148 case WM_IME_NOTIFY: | |
149 switch (wParam) | |
150 { | |
151 case IMN_SETCONVERSIONMODE: | |
152 | |
153 break; | |
154 case IMN_SETOPENSTATUS: | |
155 Update_Input_Locale(); | |
156 break; | |
157 case IMN_OPENCANDIDATE: | |
158 case IMN_CHANGECANDIDATE: | |
159 Ate = true; | |
160 break; | |
161 } | |
162 break; | |
163 } | |
164 return 0; | |
165 } |