1 /* vi:set ts=8 sts=4 sw=4:
3 * VIM - Vi IMproved by Bram Moolenaar
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.
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
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 language version of Global IME at same place.
24 * RUNTIME REQUIREMENTS:
25 * - Internet Explorer 5.01 or higher.
26 * - Global IME (with language pack?).
27 * - Of course Vim for Windows.
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
38 #define WIN32_LEAN_AND_MEAN
47 static IActiveIMMApp
*pIApp
= NULL
;
48 static IActiveIMMMessagePumpOwner
*pIMsg
= NULL
;
49 static HWND s_hWnd
= NULL
;
50 static BOOL s_bStatus
= FALSE
; /* for evacuate */
53 * Initialize Global IME.
54 * "atom" must be return value of RegisterClass(Ex).
57 global_ime_init(ATOM atom
, HWND hWnd
)
62 if (pIApp
!= NULL
|| pIMsg
!= NULL
)
67 * Get interface IUnknown
69 hr
= CoCreateInstance(CLSID_CActiveIMM
, NULL
, CLSCTX_SERVER
,
70 IID_IUnknown
, (void**)&pI
);
71 if (FAILED(hr
) || !pI
)
75 * Get interface IActiveIMMApp
77 hr
= pI
->QueryInterface(IID_IActiveIMMApp
, (void**)&pIApp
);
82 * Get interface IActiveIMMMessagePumpOwner
84 hr
= pI
->QueryInterface(IID_IActiveIMMMessagePumpOwner
, (void**)&pIMsg
);
90 pIApp
->Activate(TRUE
);
91 pIApp
->FilterClientWindows(&atom
, 1);
101 * Reset and clear Global IME.
108 IActiveIMMApp
*p
= pIApp
;
111 p
->FilterClientWindows(NULL
, 0);
117 IActiveIMMMessagePumpOwner
*p
= pIMsg
;
127 * Replacement for DefWindowProc().
130 global_ime_DefWindowProc(HWND hWnd
, UINT Msg
, WPARAM wParam
, LPARAM lParam
)
134 if (pIApp
== NULL
|| pIApp
->OnDefWindowProc(hWnd
, Msg
,
135 wParam
, lParam
, &lResult
) != S_OK
)
137 #if defined(WIN3264) && defined(FEAT_MBYTE)
139 lResult
= DefWindowProcW(hWnd
, Msg
, wParam
, lParam
);
142 lResult
= DefWindowProc(hWnd
, Msg
, wParam
, lParam
);
148 * Replace with TranslateMessage()
151 global_ime_TranslateMessage(CONST MSG
*lpMsg
)
153 if (pIMsg
== NULL
|| pIMsg
->OnTranslateMessage(lpMsg
) == S_FALSE
)
154 return TranslateMessage(lpMsg
);
159 * Set position of IME compotision window.
161 * You have to call this before starting composition. If once composition
162 * started, this can take no effect until that composition have finished. So
163 * you should handle WM_IME_STARTCOMPOSITION and call this function.
166 global_ime_set_position(POINT
*pPoint
)
170 if (pIApp
== NULL
|| pPoint
== NULL
)
173 if (SUCCEEDED(pIApp
->GetContext(s_hWnd
, &hImc
)))
175 COMPOSITIONFORM CompForm
;
177 CompForm
.dwStyle
= CFS_POINT
;
178 CompForm
.ptCurrentPos
= *pPoint
;
179 pIApp
->SetCompositionWindow(hImc
, &CompForm
);
180 pIApp
->ReleaseContext(s_hWnd
, hImc
);
185 * Set font to Global IME
189 global_ime_set_font(LOGFONT
*pFont
)
193 if (pIApp
== NULL
|| pFont
== NULL
)
196 if (SUCCEEDED(pIApp
->GetContext(s_hWnd
, &hImc
)))
198 pIApp
->SetCompositionFontA(hImc
, pFont
);
199 pIApp
->ReleaseContext(s_hWnd
, hImc
);
205 * for IME control. Save current status of IME, and set force new-status to
206 * English (turn off).
209 global_ime_status_evacuate()
213 if (pIApp
!= NULL
&& SUCCEEDED(pIApp
->GetContext(s_hWnd
, &hImc
)))
215 s_bStatus
= (pIApp
->GetOpenStatus(hImc
) == 0) ? TRUE
: FALSE
;
216 pIApp
->SetOpenStatus(hImc
, FALSE
);
217 pIApp
->ReleaseContext(s_hWnd
, hImc
);
222 * for IME control. Change IME status to last saved one.
225 global_ime_status_restore()
229 if (pIApp
!= NULL
&& SUCCEEDED(pIApp
->GetContext(s_hWnd
, &hImc
)))
231 pIApp
->SetOpenStatus(hImc
, s_bStatus
);
232 pIApp
->ReleaseContext(s_hWnd
, hImc
);
238 global_ime_set_status(int status
)
242 if (pIApp
!= NULL
&& SUCCEEDED(pIApp
->GetContext(s_hWnd
, &hImc
)))
244 pIApp
->SetOpenStatus(hImc
, status
? TRUE
: FALSE
);
245 pIApp
->ReleaseContext(s_hWnd
, hImc
);
250 global_ime_get_status()
255 if (pIApp
!= NULL
&& SUCCEEDED(pIApp
->GetContext(s_hWnd
, &hImc
)))
257 status
= pIApp
->GetOpenStatus(hImc
) ? 1 : 0;
258 pIApp
->ReleaseContext(s_hWnd
, hImc
);
263 #endif /* GLOBAL_IME */