ReactOS 0.4.15-dev-7918-g2a2556c
JapanImeConvTest.h
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS api tests
3 * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
4 * PURPOSE: Test for Japanese IME conversion
5 * COPYRIGHT: Copyright 2022 Katayama Hirofumi MZ (katayama.hirofumi.mz@gmail.com)
6 */
7
8#include <windows.h>
9#include <windowsx.h>
10#include <imm.h>
11#include <wine/test.h>
12
13/*
14 * We emulate some keyboard typing on dialog box and watch the conversion of Japanese IME.
15 * This program needs Japanese environment and Japanese IME.
16 * Tested on Japanese WinXP and Japanese Win10.
17 */
18
19#define INTERVAL 300
20#define WM_PRESS_KEY_COMPLETE (WM_USER + 100)
21
22/* The test entry structure */
23typedef struct tagTEST_ENTRY
24{
25 const UINT *pKeys;
27 const void *pvResult;
30
31// The Japanese word "テスト" conversion in Romaji
32static const UINT s_keys1[] =
33{
34 'T', 'E', 'S', 'U', 'T', 'O', VK_SPACE, VK_RETURN
35};
36// The Japanese word "調査員" conversion in Romaji
37static const UINT s_keys2[] =
38{
39 'C', 'H', 'O', 'U', 'S', 'A', 'I', 'N', 'N', VK_SPACE, VK_RETURN
40};
41
42#ifdef UNICODE
43 #define AorW(a, w) w
44#else
45 #define AorW(a, w) a
46#endif
47
48/* The test entries */
49static const TEST_ENTRY s_entries[] =
50{
51 // "テスト"
52 { s_keys1, _countof(s_keys1), AorW("\x83\x65\x83\x58\x83\x67", L"\x30C6\x30B9\x30C8"), 1 },
53 // "調査員"
54 { s_keys2, _countof(s_keys2), AorW("\x92\xB2\x8D\xB8\x88\xF5", L"\x8ABF\x67FB\x54E1"), 1 },
55};
56
57static INT s_iEntry = 0;
60
61#ifdef UNICODE
62static LPSTR WideToAnsi(INT nCodePage, LPCWSTR pszWide)
63{
64 static CHAR s_sz[512];
65 WideCharToMultiByte(nCodePage, 0, pszWide, -1, s_sz, _countof(s_sz), NULL, NULL);
66 return s_sz;
67}
68#endif
69
70/* The window procedure for textbox to watch the IME conversion */
71static LRESULT CALLBACK
73{
74 switch (uMsg)
75 {
76 case WM_IME_ENDCOMPOSITION:
77 {
79 HIMC hIMC;
80 LONG cbResult, cbBuffer;
81 LPTSTR pszResult;
82
83 /* Check conversion results of composition string */
84 hIMC = ImmGetContext(hwnd);
85 cbResult = ImmGetCompositionString(hIMC, GCS_RESULTSTR, NULL, 0);
86 trace("cbResult: %ld\n", cbResult);
87 if (cbResult > 0) /* Ignore zero string */
88 {
89 ok(hIMC != NULL, "hIMC was NULL\n");
91
92 cbBuffer = cbResult + sizeof(WCHAR);
93 pszResult = (LPTSTR)calloc(cbBuffer, sizeof(BYTE)); /* Zero-fill */
94 ok(pszResult != NULL, "pszResult was NULL\n");
95 ImmGetCompositionString(hIMC, GCS_RESULTSTR, pszResult, cbBuffer);
96#ifdef UNICODE
97 trace("%s\n", WideToAnsi(CP_ACP, (LPTSTR)pszResult));
98#else
99 trace("%s\n", (LPTSTR)pszResult);
100#endif
101 ok(lstrcmp(pszResult, (LPTSTR)entry->pvResult) == 0, "pszResult differs\n");
102 free(pszResult);
103 }
104
105 ImmReleaseContext(hwnd, hIMC);
106 }
107 break;
108 }
109
111}
112
113/* Timer IDs */
114#define STAGE_1 10001
115#define STAGE_2 10002
116#define STAGE_3 10003
117#define STAGE_4 10004
118#define STAGE_5 10005
119
120/* WM_INITDIALOG */
122{
123 /* Subclass the textbox to watch the IME conversion */
124 HWND hEdt1 = GetDlgItem(hwnd, edt1);
126
127 /* Go to first stage */
129 return TRUE;
130}
131
132/* WM_COMMAND */
133static void OnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify)
134{
135 switch (id)
136 {
137 case IDOK:
138 case IDCANCEL:
139 EndDialog(hwnd, id);
140 break;
141 }
142}
143
144/* Emulate keyboard typing */
146{
147 INPUT inputs[2];
148 ZeroMemory(inputs, sizeof(inputs));
149 inputs[0].type = INPUT_KEYBOARD;
150 inputs[0].ki.wVk = vk;
151 inputs[1].type = INPUT_KEYBOARD;
152 inputs[1].ki.wVk = vk;
153 inputs[1].ki.dwFlags = KEYEVENTF_KEYUP;
154 SendInput(_countof(inputs), inputs, sizeof(INPUT));
155}
156
157/* WM_TIMER */
158static void OnTimer(HWND hwnd, UINT id)
159{
160 HIMC hIMC;
161 INT i;
163 static DWORD dwOldConversion, dwOldSentence;
164
165 KillTimer(hwnd, id);
166
167 switch (id)
168 {
169 case STAGE_1:
170 /* Check focus. See WM_INITDIALOG return code. */
171 ok(GetFocus() == GetDlgItem(hwnd, edt1), "GetFocus() was %p\n", GetFocus());
172
173 hIMC = ImmGetContext(hwnd);
174 ok(hIMC != NULL, "hIMC was NULL");
175 if (hIMC)
176 {
177 /* Open the IME */
178 ImmSetOpenStatus(hIMC, TRUE);
179 /* Save the IME conversion status */
180 ImmGetConversionStatus(hIMC, &dwOldConversion, &dwOldSentence);
181 /* Modify the IME conversion status */
185
186 ImmReleaseContext(hwnd, hIMC);
187 }
188 /* Initialize the counter */
190 /* Go to next stage */
192 break;
193
194 case STAGE_2:
195 /* Emulate keyboard typing */
196 for (i = 0; i < entry->cKeys; ++i)
197 {
198 PressKey(entry->pKeys[i]);
199 }
200 /* Wait for message queue processed */
202 break;
203
204 case STAGE_3:
205 /* Revert the IME conversion status */
206 hIMC = ImmGetContext(hwnd);
207 ok(hIMC != NULL, "hIMC was NULL");
208 if (hIMC)
209 {
210 ImmSetConversionStatus(hIMC, dwOldConversion, dwOldSentence);
211 ImmReleaseContext(hwnd, hIMC);
212 }
213 /* Go to next stage */
215 break;
216
217 case STAGE_4:
218 /* Check the counter */
219 ok_int(s_cWM_IME_ENDCOMPOSITION, entry->cWM_IME_ENDCOMPOSITION);
220 if (s_cWM_IME_ENDCOMPOSITION < entry->cWM_IME_ENDCOMPOSITION)
221 {
222 skip("Some tests were skipped.\n");
223 }
224
225 /* Go to next test entry */
226 ++s_iEntry;
228 PostMessage(hwnd, WM_CLOSE, 0, 0); /* No more entry */
229 else
231 break;
232 }
233}
234
235/* Dialog procedure */
236static INT_PTR CALLBACK
238{
239 switch (uMsg)
240 {
244
246 /* Message queue is processed. Go to next stage. */
248 break;
249 }
250 return 0;
251}
252
253#ifdef UNICODE
254START_TEST(JapanImeConvTestW)
255#else
256START_TEST(JapanImeConvTestA)
257#endif
258{
259 /* Is the system Japanese? */
261 {
262 skip("This testcase is for Japanese only.\n");
263 return;
264 }
265
266 /* Is IMM enabled? */
267 if (!GetSystemMetrics(SM_IMMENABLED))
268 {
269 skip("SM_IMMENABLED is OFF.\n");
270 return;
271 }
272
273 /* Check the current keyboard layout is IME */
275 {
276 skip("The IME keyboard layout was not default\n");
277 return;
278 }
279
281
283 skip("Some tests were skipped.\n");
284}
static INT_PTR CALLBACK DialogProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
#define AorW(a, w)
static BOOL OnInitDialog(HWND hwnd, HWND hwndFocus, LPARAM lParam)
static const UINT s_keys2[]
static const TEST_ENTRY s_entries[]
static void OnTimer(HWND hwnd, UINT id)
struct tagTEST_ENTRY * PTEST_ENTRY
static WNDPROC s_fnOldEditWndProc
static INT s_cWM_IME_ENDCOMPOSITION
struct tagTEST_ENTRY TEST_ENTRY
#define WM_PRESS_KEY_COMPLETE
#define STAGE_2
static void OnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify)
static const UINT s_keys1[]
#define STAGE_4
#define INTERVAL
static VOID PressKey(UINT vk)
#define STAGE_3
static INT s_iEntry
#define STAGE_1
static LRESULT CALLBACK EditWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
#define trace
Definition: atltest.h:70
#define ok(value,...)
Definition: atltest.h:57
#define skip(...)
Definition: atltest.h:64
#define START_TEST(x)
Definition: atltest.h:75
#define ok_int(expression, result)
Definition: atltest.h:134
WPARAM wParam
Definition: combotst.c:138
LPARAM lParam
Definition: combotst.c:139
#define free
Definition: debug_ros.c:5
DWORD HIMC
Definition: dimm.idl:75
#define edt1
Definition: dlgs.h:65
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define CP_ACP
Definition: compat.h:109
#define CALLBACK
Definition: compat.h:35
#define WideCharToMultiByte
Definition: compat.h:111
BOOL WINAPI ImmIsIME(HKL hKL)
Definition: ime.c:880
BOOL WINAPI ImmSetConversionStatus(HIMC hIMC, DWORD fdwConversion, DWORD fdwSentence)
Definition: ime.c:1941
BOOL WINAPI ImmGetConversionStatus(HIMC hIMC, LPDWORD lpfdwConversion, LPDWORD lpfdwSentence)
Definition: ime.c:1912
BOOL WINAPI ImmSetOpenStatus(HIMC hIMC, BOOL fOpen)
Definition: ime.c:1466
HIMC WINAPI ImmGetContext(HWND hWnd)
Definition: imm.c:1044
BOOL WINAPI ImmReleaseContext(HWND hWnd, HIMC hIMC)
Definition: imm.c:1085
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define IME_CMODE_ROMAN
Definition: imm.h:346
#define IME_CMODE_NATIVE
Definition: imm.h:337
#define GCS_RESULTSTR
Definition: imm.h:234
#define ImmGetCompositionString
Definition: imm.h:825
#define IME_SMODE_SINGLECONVERT
Definition: imm.h:358
#define IME_CMODE_FULLSHAPE
Definition: imm.h:345
uint32_t entry
Definition: isohybrid.c:63
LANGID WINAPI GetSystemDefaultLangID(void)
Definition: lang.c:761
WORD vk
Definition: input.c:77
__int3264 LONG_PTR
Definition: mstsclib_h.h:276
unsigned int UINT
Definition: ndis.h:50
#define L(x)
Definition: ntvdm.h:50
long LONG
Definition: pedump.c:60
#define calloc
Definition: rosglue.h:14
#define LANG_JAPANESE
Definition: nls.h:76
#define PRIMARYLANGID(l)
Definition: nls.h:16
#define _countof(array)
Definition: sndvol32.h:68
Definition: cmd.c:13
KEYBDINPUT ki
Definition: winable.h:62
DWORD type
Definition: winable.h:59
DWORD dwFlags
Definition: winable.h:49
WORD wVk
Definition: winable.h:47
UINT cKeys
const void * pvResult
INT cWM_IME_ENDCOMPOSITION
const UINT * pKeys
#define SetWindowLongPtr
Definition: treelist.c:70
#define GWLP_WNDPROC
Definition: treelist.c:66
int32_t INT_PTR
Definition: typedefs.h:64
int32_t INT
Definition: typedefs.h:58
UINT WINAPI SendInput(UINT, LPINPUT, int)
Definition: ntwrapper.h:344
#define INPUT_KEYBOARD
Definition: winable.h:10
#define ZeroMemory
Definition: winbase.h:1712
#define lstrcmp
Definition: winbase.h:3872
#define GetModuleHandle
Definition: winbase.h:3827
_In_ LONG _In_ HWND hwnd
Definition: winddi.h:4023
LONG_PTR LPARAM
Definition: windef.h:208
LONG_PTR LRESULT
Definition: windef.h:209
UINT_PTR WPARAM
Definition: windef.h:207
#define HANDLE_MSG(hwnd, message, fn)
Definition: windowsx.h:322
HWND WINAPI GetFocus(void)
Definition: window.c:1893
HKL WINAPI GetKeyboardLayout(_In_ DWORD)
#define WM_CLOSE
Definition: winuser.h:1621
#define CallWindowProc
Definition: winuser.h:5735
#define IDCANCEL
Definition: winuser.h:831
#define VK_SPACE
Definition: winuser.h:2219
#define WM_COMMAND
Definition: winuser.h:1740
#define WM_INITDIALOG
Definition: winuser.h:1739
HWND WINAPI GetDlgItem(_In_opt_ HWND, _In_ int)
#define IDOK
Definition: winuser.h:830
UINT_PTR WINAPI SetTimer(_In_opt_ HWND, _In_ UINT_PTR, _In_ UINT, _In_opt_ TIMERPROC)
#define VK_RETURN
Definition: winuser.h:2201
#define WM_TIMER
Definition: winuser.h:1742
#define PostMessage
Definition: winuser.h:5832
LRESULT(CALLBACK * WNDPROC)(HWND, UINT, WPARAM, LPARAM)
Definition: winuser.h:2906
BOOL WINAPI KillTimer(_In_opt_ HWND, _In_ UINT_PTR)
#define MAKEINTRESOURCE
Definition: winuser.h:591
int WINAPI GetSystemMetrics(_In_ int)
#define KEYEVENTF_KEYUP
Definition: winuser.h:1102
#define DialogBox
Definition: winuser.h:5761
BOOL WINAPI EndDialog(_In_ HWND, _In_ INT_PTR)
char * LPSTR
Definition: xmlstorage.h:182
__wchar_t WCHAR
Definition: xmlstorage.h:180
CHAR * LPTSTR
Definition: xmlstorage.h:192
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
char CHAR
Definition: xmlstorage.h:175
unsigned char BYTE
Definition: xxhash.c:193