7
|
1 /* vi:set ts=8 sts=4 sw=4:
|
|
2 *
|
|
3 * VIM - Vi IMproved by Bram Moolenaar
|
|
4 *
|
|
5 * Do ":help uganda" in Vim to read copying and usage conditions.
|
|
6 * Do ":help credits" in Vim to see a list of people who contributed.
|
|
7 */
|
|
8
|
|
9 /*
|
|
10 * DESCRIPTION:
|
|
11 * This module produces Global IME for Vim, on Windows with Internet
|
|
12 * Explorer 5.01 or higher. You need three files "dimm.idl", "dimm.h", and
|
|
13 * "dimm_i.c" when compile this module at your self. "dimm.h", and
|
|
14 * "dimm_i.c" are generated from "dimm.idl" by using MIDL.EXE as like
|
|
15 * "if_ole.h". You can get "dimm.idl" in MSDN web site. I got it below
|
|
16 * URL.
|
|
17 *
|
|
18 * WHAT IS THE GLOBAL IME?:
|
|
19 * Global IME makes capability input Chinese, Japanese, and Korean text into
|
|
20 * Vim buffer on any language version of Windows 98, Windows 95, and Windows
|
|
21 * NT 4.0. See below URL for detail of Global IME. You can also find
|
|
22 * various laguage version of Global IME at same place.
|
|
23 *
|
|
24 * RUNTIME REQUIREMENTS:
|
|
25 * - Internet Exproler 5.01 or higher.
|
|
26 * - Global IME (with language pack?).
|
|
27 * - Of course Vim for Windows.
|
|
28 *
|
|
29 * URLS:
|
|
30 * - Where you can probably get "dimm.idl".
|
|
31 * http://msdn.microsoft.com/downloads/samples/internet/libraries/ie5_lib/sample.asp
|
|
32 * - Global IME detailed information.
|
|
33 * http://www.microsoft.com/windows/ie/features/ime.asp
|
|
34 */
|
|
35
|
|
36 #ifdef GLOBAL_IME
|
|
37
|
|
38 #define WIN32_LEAN_AND_MEAN
|
|
39 #include <windows.h>
|
|
40 #include <objbase.h>
|
|
41 extern "C" {
|
|
42 #include "vim.h"
|
|
43 }
|
|
44 #include "dimm.h"
|
|
45 #include "glbl_ime.h"
|
|
46
|
|
47 static IActiveIMMApp *pIApp = NULL;
|
|
48 static IActiveIMMMessagePumpOwner *pIMsg = NULL;
|
|
49 static HWND s_hWnd = NULL;
|
|
50 static BOOL s_bStatus = FALSE; /* for evacuate */
|
|
51
|
|
52 /*
|
|
53 * Initialize Global IME.
|
|
54 * "atom" must be return value of RegisterClass(Ex).
|
|
55 */
|
|
56 void
|
|
57 global_ime_init(ATOM atom, HWND hWnd)
|
|
58 {
|
|
59 IUnknown *pI;
|
|
60 HRESULT hr;
|
|
61
|
|
62 if (pIApp != NULL || pIMsg != NULL)
|
|
63 return;
|
|
64 OleInitialize(NULL);
|
|
65
|
|
66 /*
|
|
67 * Get interface IUnknown
|
|
68 */
|
|
69 hr = CoCreateInstance(CLSID_CActiveIMM, NULL, CLSCTX_SERVER,
|
|
70 IID_IUnknown, (void**)&pI);
|
|
71 if (FAILED(hr) || !pI)
|
|
72 return;
|
|
73
|
|
74 /*
|
|
75 * Get interface IActiveIMMApp
|
|
76 */
|
|
77 hr = pI->QueryInterface(IID_IActiveIMMApp, (void**)&pIApp);
|
|
78 if (FAILED(hr))
|
|
79 pIApp = NULL;
|
|
80
|
|
81 /*
|
|
82 * Get interface IActiveIMMMessagePumpOwner
|
|
83 */
|
|
84 hr = pI->QueryInterface(IID_IActiveIMMMessagePumpOwner, (void**)&pIMsg);
|
|
85 if (FAILED(hr))
|
|
86 pIMsg = NULL;
|
|
87
|
|
88 if (pIApp != NULL)
|
|
89 {
|
|
90 pIApp->Activate(TRUE);
|
|
91 pIApp->FilterClientWindows(&atom, 1);
|
|
92 }
|
|
93 if (pIMsg != NULL)
|
|
94 pIMsg->Start();
|
|
95
|
|
96 pI->Release();
|
|
97 s_hWnd = hWnd;
|
|
98 }
|
|
99
|
|
100 /*
|
|
101 * Reset and clear Global IME.
|
|
102 */
|
|
103 void
|
|
104 global_ime_end()
|
|
105 {
|
|
106 if (pIApp != NULL)
|
|
107 {
|
|
108 IActiveIMMApp *p = pIApp;
|
|
109
|
|
110 pIApp = NULL;
|
|
111 p->FilterClientWindows(NULL, 0);
|
|
112 p->Deactivate();
|
|
113 p->Release();
|
|
114 }
|
|
115 if (pIMsg != NULL)
|
|
116 {
|
|
117 IActiveIMMMessagePumpOwner *p = pIMsg;
|
|
118
|
|
119 pIMsg = NULL;
|
|
120 p->End();
|
|
121 p->Release();
|
|
122 }
|
|
123 OleUninitialize();
|
|
124 }
|
|
125
|
|
126 /*
|
|
127 * Replacement for DefWindowProc().
|
|
128 */
|
|
129 LRESULT WINAPI
|
|
130 global_ime_DefWindowProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
|
|
131 {
|
|
132 LRESULT lResult;
|
|
133
|
|
134 if (pIApp == NULL || pIApp->OnDefWindowProc(hWnd, Msg,
|
|
135 wParam, lParam, &lResult) != S_OK)
|
|
136 {
|
|
137 #if defined(WIN3264) && defined(FEAT_MBYTE)
|
|
138 if (wide_WindowProc)
|
285
|
139 lResult = DefWindowProcW(hWnd, Msg, wParam, lParam);
|
7
|
140 else
|
|
141 #endif
|
|
142 lResult = DefWindowProc(hWnd, Msg, wParam, lParam);
|
|
143 }
|
|
144 return lResult;
|
|
145 }
|
|
146
|
|
147 /*
|
|
148 * Replace with TranslateMessage()
|
|
149 */
|
|
150 BOOL WINAPI
|
|
151 global_ime_TranslateMessage(CONST MSG *lpMsg)
|
|
152 {
|
|
153 if (pIMsg == NULL || pIMsg->OnTranslateMessage(lpMsg) == S_FALSE)
|
|
154 return TranslateMessage(lpMsg);
|
|
155 return TRUE;
|
|
156 }
|
|
157
|
|
158 /*
|
|
159 * Set position of IME compotision window.
|
|
160 *
|
|
161 * You have to call this before starting composition. If once composition
|
|
162 * started, this can take no effect until that composition have finised. So
|
|
163 * you should handle WM_IME_STARTCOMPOSITION and call this function.
|
|
164 */
|
|
165 void WINAPI
|
|
166 global_ime_set_position(POINT *pPoint)
|
|
167 {
|
|
168 HIMC hImc = NULL;
|
|
169
|
|
170 if (pIApp == NULL || pPoint == NULL)
|
|
171 return;
|
|
172
|
|
173 if (SUCCEEDED(pIApp->GetContext(s_hWnd, &hImc)))
|
|
174 {
|
|
175 COMPOSITIONFORM CompForm;
|
|
176
|
|
177 CompForm.dwStyle = CFS_POINT;
|
|
178 CompForm.ptCurrentPos = *pPoint;
|
|
179 pIApp->SetCompositionWindow(hImc, &CompForm);
|
|
180 pIApp->ReleaseContext(s_hWnd, hImc);
|
|
181 }
|
|
182 }
|
|
183
|
|
184 /*
|
|
185 * Set font to Global IME
|
|
186 */
|
|
187 /* GIME_TEST */
|
|
188 void WINAPI
|
|
189 global_ime_set_font(LOGFONT *pFont)
|
|
190 {
|
|
191 HIMC hImc = NULL;
|
|
192
|
|
193 if (pIApp == NULL || pFont == NULL)
|
|
194 return;
|
|
195
|
|
196 if (SUCCEEDED(pIApp->GetContext(s_hWnd, &hImc)))
|
|
197 {
|
|
198 pIApp->SetCompositionFontA(hImc, pFont);
|
|
199 pIApp->ReleaseContext(s_hWnd, hImc);
|
|
200 }
|
|
201 }
|
|
202
|
376
|
203 #if 0
|
7
|
204 /*
|
|
205 * for IME control. Save current status of IME, and set force new-status to
|
376
|
206 * English (turn off).
|
7
|
207 */
|
|
208 void WINAPI
|
|
209 global_ime_status_evacuate()
|
|
210 {
|
|
211 HIMC hImc;
|
|
212
|
|
213 if (pIApp != NULL && SUCCEEDED(pIApp->GetContext(s_hWnd, &hImc)))
|
|
214 {
|
|
215 s_bStatus = (pIApp->GetOpenStatus(hImc) == 0) ? TRUE : FALSE;
|
|
216 pIApp->SetOpenStatus(hImc, FALSE);
|
|
217 pIApp->ReleaseContext(s_hWnd, hImc);
|
|
218 }
|
|
219 }
|
|
220
|
|
221 /*
|
|
222 * for IME control. Change IME status to last saved one.
|
|
223 */
|
|
224 void WINAPI
|
|
225 global_ime_status_restore()
|
|
226 {
|
|
227 HIMC hImc;
|
|
228
|
|
229 if (pIApp != NULL && SUCCEEDED(pIApp->GetContext(s_hWnd, &hImc)))
|
|
230 {
|
|
231 pIApp->SetOpenStatus(hImc, s_bStatus);
|
|
232 pIApp->ReleaseContext(s_hWnd, hImc);
|
|
233 }
|
|
234 }
|
376
|
235 #endif
|
7
|
236
|
|
237 void WINAPI
|
|
238 global_ime_set_status(int status)
|
|
239 {
|
|
240 HIMC hImc;
|
|
241
|
|
242 if (pIApp != NULL && SUCCEEDED(pIApp->GetContext(s_hWnd, &hImc)))
|
|
243 {
|
|
244 pIApp->SetOpenStatus(hImc, status ? TRUE : FALSE);
|
|
245 pIApp->ReleaseContext(s_hWnd, hImc);
|
|
246 }
|
|
247 }
|
|
248
|
|
249 int WINAPI
|
|
250 global_ime_get_status()
|
|
251 {
|
|
252 int status = 0;
|
|
253 HIMC hImc;
|
|
254
|
|
255 if (pIApp != NULL && SUCCEEDED(pIApp->GetContext(s_hWnd, &hImc)))
|
|
256 {
|
|
257 status = pIApp->GetOpenStatus(hImc) ? 1 : 0;
|
|
258 pIApp->ReleaseContext(s_hWnd, hImc);
|
|
259 }
|
|
260 return status;
|
|
261 }
|
|
262
|
|
263 #endif /* GLOBAL_IME */
|