ReactOS 0.4.16-dev-1537-g4e425b5
imepro.c
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS IMM32
3 * LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later)
4 * PURPOSE: Implementing ImmIMP* functions
5 * COPYRIGHT: Copyright 2020-2025 Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com>
6 */
7
8#include "precomp.h"
9
11
12/*
13 * An IMEPROA/IMEPROW structure is an IME program information.
14 * The ImmIMP* functions just treat these information.
15 */
16
17static VOID
19 _In_ const IMEPROW *pProW,
20 _Out_ PIMEPROA pProA)
21{
22 ASSERT(pProW);
23 ASSERT(pProA);
24
25 pProA->hWnd = pProW->hWnd;
26 pProA->InstDate = pProW->InstDate;
27 pProA->wVersion = pProW->wVersion;
28
29 WideCharToMultiByte(CP_ACP, 0, pProW->szDescription, -1,
30 (PSTR)pProA->szDescription, _countof(pProA->szDescription), NULL, NULL);
31 pProA->szDescription[_countof(pProA->szDescription) - 1] = ANSI_NULL; /* Avoid buffer overrun */
32
33 WideCharToMultiByte(CP_ACP, 0, pProW->szName, -1,
34 (PSTR)pProA->szName, _countof(pProA->szName), NULL, NULL);
35 pProA->szName[_countof(pProA->szName) - 1] = ANSI_NULL; /* Avoid buffer overrun */
36
37 pProA->szOptions[0] = ANSI_NULL;
38}
39
40static BOOL
42 _In_ HKL hKL,
43 _Out_ PIMEPROW pProW)
44{
45 ASSERT(pProW);
46
47 IMEINFOEX ImeInfoEx;
48 if (!ImmGetImeInfoEx(&ImeInfoEx, ImeInfoExKeyboardLayout, &hKL))
49 return FALSE;
50
51 pProW->hWnd = NULL;
52 ZeroMemory(&pProW->InstDate, sizeof(pProW->InstDate));
53 pProW->wVersion = ImeInfoEx.dwImeWinVersion;
54
55 StringCchCopyNW(pProW->szDescription, _countof(pProW->szDescription),
56 ImeInfoEx.wszImeDescription, _countof(ImeInfoEx.wszImeDescription));
57 StringCchCopyNW(pProW->szName, _countof(pProW->szName),
58 ImeInfoEx.wszImeFile, _countof(ImeInfoEx.wszImeFile));
59 pProW->szOptions[0] = UNICODE_NULL;
60
61 return TRUE;
62}
63
64/***********************************************************************
65 * ImmIMPGetIMEA(IMM32.@)
66 */
70 _Out_ LPIMEPROA pImePro)
71{
73
74 TRACE("(%p, %p)\n", hWnd, pImePro);
75
76 ASSERT(pImePro);
77
79 {
81 return FALSE;
82 }
83
84 IMEPROW ImeProW;
85 HKL hKL = GetKeyboardLayout(0);
86 if (!Imm32IMPGetIME(hKL, &ImeProW))
87 return FALSE;
88
89 Imm32ConvertImeProWideToAnsi(&ImeProW, pImePro);
90 return TRUE;
91}
92
93/***********************************************************************
94 * ImmIMPGetIMEW(IMM32.@)
95 */
99 _Out_ LPIMEPROW pImePro)
100{
102
103 TRACE("(%p, %p)\n", hWnd, pImePro);
104
105 ASSERT(pImePro);
106
108 {
110 return FALSE;
111 }
112
113 HKL hKL = GetKeyboardLayout(0);
114 return Imm32IMPGetIME(hKL, pImePro);
115}
116
117/***********************************************************************
118 * ImmIMPQueryIMEA(IMM32.@)
119 */
122{
123 TRACE("(%p)\n", pImePro);
124
125 ASSERT(pImePro);
126
128 {
130 return FALSE;
131 }
132
133 IMEPROW ProW;
134 if (pImePro->szName[0])
135 {
136 /* pImePro->szName is BYTE[], so we need type cast */
137 if (!MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, (PSTR)pImePro->szName, -1,
138 ProW.szName, _countof(ProW.szName)))
139 {
140 ERR("szName: %s\n", debugstr_a((PSTR)pImePro->szName));
141 return FALSE;
142 }
143 ProW.szName[_countof(ProW.szName) - 1] = UNICODE_NULL; /* Avoid buffer overrun */
144 }
145 else
146 {
147 ProW.szName[0] = UNICODE_NULL;
148 }
149
150 if (!ImmIMPQueryIMEW(&ProW))
151 return FALSE;
152
153 Imm32ConvertImeProWideToAnsi(&ProW, pImePro);
154 return TRUE;
155}
156
157/***********************************************************************
158 * ImmIMPQueryIMEW(IMM32.@)
159 */
162{
163 TRACE("(%p)\n", pImePro);
164
165 ASSERT(pImePro);
166
168 {
170 return FALSE;
171 }
172
173 INT nLayouts = GetKeyboardLayoutList(0, NULL);
174 if (nLayouts <= 0)
175 {
176 ERR("nLayouts: %d\n", nLayouts);
177 return FALSE;
178 }
179
180 HKL *phKLs = ImmLocalAlloc(0, nLayouts * sizeof(HKL));
181 if (!phKLs)
182 {
183 ERR("Out of memory\n");
184 return FALSE;
185 }
186
187 if (GetKeyboardLayoutList(nLayouts, phKLs) != nLayouts)
188 {
189 ERR("KL count mismatch\n");
190 ImmLocalFree(phKLs);
191 return FALSE;
192 }
193
194 BOOL result = FALSE;
195 if (pImePro->szName[0])
196 {
197 IMEINFOEX ImeInfoEx;
198 if (ImmGetImeInfoEx(&ImeInfoEx, ImeInfoExImeFileName, pImePro->szName))
199 {
200 for (INT iKL = 0; iKL < nLayouts; ++iKL)
201 {
202 if (phKLs[iKL] == ImeInfoEx.hkl)
203 {
204 result = Imm32IMPGetIME(phKLs[iKL], pImePro);
205 break;
206 }
207 }
208 }
209 }
210 else
211 {
212 for (INT iKL = 0; iKL < nLayouts; ++iKL)
213 {
214 result = Imm32IMPGetIME(phKLs[iKL], pImePro);
215 if (result)
216 break;
217 }
218 }
219
220 ImmLocalFree(phKLs);
221 return result;
222}
223
224/***********************************************************************
225 * ImmIMPSetIMEA(IMM32.@)
226 */
230 _Inout_ LPIMEPROA pImePro)
231{
232 TRACE("(%p, %p)\n", hWnd, pImePro);
233
234 ASSERT(pImePro);
235
236 IMEPROW ProW;
238 {
240 return FALSE;
241 }
242
243 if (pImePro->szName[0])
244 {
245 /* pImePro->szName is BYTE[], so we need type cast */
246 if (!MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, (PSTR)pImePro->szName, -1,
247 ProW.szName, _countof(ProW.szName)))
248 {
249 ERR("szName: %s\n", debugstr_a((PSTR)pImePro->szName));
250 return FALSE;
251 }
252 ProW.szName[_countof(ProW.szName) - 1] = UNICODE_NULL; /* Avoid buffer overrun */
253 }
254 else
255 {
256 ProW.szName[0] = UNICODE_NULL;
257 }
258
259 return ImmIMPSetIMEW(hWnd, &ProW);
260}
261
262/***********************************************************************
263 * ImmIMPSetIMEW(IMM32.@)
264 */
268 _Inout_ LPIMEPROW pImePro)
269{
271
272 TRACE("(%p, %p)\n", hWnd, pImePro);
273
274 ASSERT(pImePro);
275
277 {
279 return FALSE;
280 }
281
282 HKL hTargetKL = NULL;
283 if (pImePro->szName[0])
284 {
285 IMEINFOEX ImeInfoEx;
286 if (!ImmGetImeInfoEx(&ImeInfoEx, ImeInfoExImeFileName, pImePro->szName))
287 return FALSE;
288
289 hTargetKL = ImeInfoEx.hkl;
290 }
291 else
292 {
293 INT nLayouts = GetKeyboardLayoutList(0, NULL);
294 if (nLayouts <= 0)
295 {
296 ERR("nLayouts: %d\n", nLayouts);
297 return FALSE;
298 }
299
300 HKL *phKLs = ImmLocalAlloc(0, nLayouts * sizeof(HKL));
301 if (!phKLs)
302 {
303 ERR("Out of memory\n");
304 return FALSE;
305 }
306
307 if (GetKeyboardLayoutList(nLayouts, phKLs) == nLayouts)
308 {
309 for (INT iKL = 0; iKL < nLayouts; ++iKL)
310 {
311 if (!ImmIsIME(phKLs[iKL]))
312 {
313 hTargetKL = phKLs[iKL];
314 break;
315 }
316 }
317 }
318 else
319 {
320 ERR("KL count mismatch\n");
321 }
322
323 ImmLocalFree(phKLs);
324 }
325
326 if (hTargetKL && GetKeyboardLayout(0) != hTargetKL)
327 {
328 HWND hwndFocus = GetFocus();
329 if (hwndFocus)
330 {
331 PostMessageW(hwndFocus, WM_INPUTLANGCHANGEREQUEST, INPUTLANGCHANGE_SYSCHARSET,
332 (LPARAM)hTargetKL);
333 return TRUE;
334 }
335 }
336
337 return FALSE;
338}
HWND hWnd
Definition: settings.c:17
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
#define ERR(fmt,...)
Definition: precomp.h:57
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define ERROR_CALL_NOT_IMPLEMENTED
Definition: compat.h:102
#define CP_ACP
Definition: compat.h:109
#define SetLastError(x)
Definition: compat.h:752
#define WideCharToMultiByte
Definition: compat.h:111
#define MultiByteToWideChar
Definition: compat.h:110
unsigned int BOOL
Definition: ntddk_ex.h:94
GLuint64EXT * result
Definition: glext.h:11304
BOOL WINAPI ImmIMPQueryIMEA(_Inout_ LPIMEPROA pImePro)
Definition: imepro.c:121
BOOL WINAPI ImmIMPGetIMEW(_In_opt_ HWND hWnd, _Out_ LPIMEPROW pImePro)
Definition: imepro.c:97
BOOL WINAPI ImmIMPGetIMEA(_In_opt_ HWND hWnd, _Out_ LPIMEPROA pImePro)
Definition: imepro.c:68
BOOL WINAPI ImmIMPQueryIMEW(_Inout_ LPIMEPROW pImePro)
Definition: imepro.c:161
BOOL WINAPI ImmIMPSetIMEW(_In_opt_ HWND hWnd, _Inout_ LPIMEPROW pImePro)
Definition: imepro.c:266
static VOID Imm32ConvertImeProWideToAnsi(_In_ const IMEPROW *pProW, _Out_ PIMEPROA pProA)
Definition: imepro.c:18
static BOOL Imm32IMPGetIME(_In_ HKL hKL, _Out_ PIMEPROW pProW)
Definition: imepro.c:41
BOOL WINAPI ImmIMPSetIMEA(_In_opt_ HWND hWnd, _Inout_ LPIMEPROA pImePro)
Definition: imepro.c:228
BOOL WINAPI ImmGetImeInfoEx(_Out_ PIMEINFOEX pImeInfoEx, _In_ IMEINFOEXCLASS SearchType, _In_ PVOID pvSearchKey)
@ ImeInfoExImeFileName
Definition: imm32_undoc.h:82
@ ImeInfoExKeyboardLayout
Definition: imm32_undoc.h:79
BOOL WINAPI ImmIsIME(_In_ HKL hKL)
Definition: ime.c:429
#define debugstr_a
Definition: kernel32.h:31
#define ASSERT(a)
Definition: mode.c:44
UINT_PTR HKL
Definition: msctf.idl:125
#define _Inout_
Definition: no_sal2.h:162
#define _Out_
Definition: no_sal2.h:160
#define _In_
Definition: no_sal2.h:158
#define _In_opt_
Definition: no_sal2.h:212
#define UNICODE_NULL
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:329
#define ANSI_NULL
#define _countof(array)
Definition: sndvol32.h:70
#define TRACE(s)
Definition: solgame.cpp:4
STRSAFEAPI StringCchCopyNW(STRSAFE_LPWSTR pszDest, size_t cchDest, STRSAFE_LPCWSTR pszSrc, size_t cchToCopy)
Definition: strsafe.h:236
WCHAR szName[80]
Definition: winnls32.h:34
WCHAR wszImeDescription[50]
Definition: imm32_undoc.h:68
WCHAR wszImeFile[80]
Definition: imm32_undoc.h:69
DWORD dwImeWinVersion
Definition: imm32_undoc.h:67
char * PSTR
Definition: typedefs.h:51
int32_t INT
Definition: typedefs.h:58
#define ImmLocalFree(lpData)
Definition: precomp.h:105
BOOL Imm32IsSystemJapaneseOrKorean(VOID)
Definition: utils.c:72
LPVOID ImmLocalAlloc(_In_ DWORD dwFlags, _In_ DWORD dwBytes)
Definition: utils.c:275
#define ZeroMemory
Definition: winbase.h:1753
LONG_PTR LPARAM
Definition: windef.h:208
#define WINAPI
Definition: msvc.h:6
#define MB_PRECOMPOSED
Definition: winnls.h:299
HWND WINAPI GetFocus(void)
Definition: window.c:1863
HKL WINAPI GetKeyboardLayout(_In_ DWORD)
BOOL WINAPI PostMessageW(_In_opt_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
UINT WINAPI GetKeyboardLayoutList(_In_ int nBuff, _Out_writes_to_opt_(nBuff, return) HKL FAR *lpList)