2 * Implementation of the 'IME window' class
4 * Copyright 2000 Hidenori Takeshima
8 * - handle all messages.
9 * - handle all notifications.
11 * This library is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Lesser General Public
13 * License as published by the Free Software Foundation; either
14 * version 2.1 of the License, or (at your option) any later version.
16 * This library is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * Lesser General Public License for more details.
21 * You should have received a copy of the GNU Lesser General Public
22 * License along with this library; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
35 #include "wine/debug.h"
36 WINE_DEFAULT_DEBUG_CHANNEL(imm);
38 #include "imm_private.h"
40 #define IMM32_CONVERSION_BUFSIZE 200
42 static CHAR IMM32_szIMEClass[] = "IME";
43 static CHAR IMM32_szIMEWindowName[] = "Default IME";
52 CHAR A[IMM32_CONVERSION_BUFSIZE];
53 WCHAR W[IMM32_CONVERSION_BUFSIZE];
58 static BOOL IMM32_IsUIMessage( UINT nMsg );
61 LRESULT IMM32_IMEWnd_WM_KEYDOWN( IMM32_IMEWNDPARAM* pParam,
62 WPARAM wParam, LPARAM lParam )
64 BYTE bKeyState[ 256 ];
70 const IMM32_IMEKL* pkl;
72 if ( pParam->hwndActive == (HWND)NULL )
75 /* get context -> get pkl. */
76 hIMC = ImmGetContext( pParam->hwndActive );
77 if ( hIMC == NULLIMC )
79 pIMC = IMM32_LockIMC( hIMC );
82 ImmReleaseContext( pParam->hwndActive, hIMC );
87 GetKeyboardState( bKeyState );
88 if ( !pkl->handlers.pImeProcessKey
89 ( hIMC, wParam, lParam, bKeyState ) )
91 lr = SendMessageA( pParam->hwndActive, WM_IME_KEYDOWN,
97 nNumOfMsg = pkl->handlers.pImeToAsciiEx
98 ( wParam, (lParam>>16)&0xff,
99 bKeyState, &dwTransBufSize,
100 0, /* FIXME!!! - 1 if a menu is active */
103 /* FIXME - process generated messages */
104 /* I cannot use ImmGenerateMessage() since
105 * the IME window must handle generated messages. */
107 /* NOTE - I must check pkl->fUnicode. */
108 FIXME( "%d messages generated.\n", nNumOfMsg );
112 IMM32_UnlockIMC( hIMC );
113 ImmReleaseContext( pParam->hwndActive, hIMC );
119 LRESULT IMM32_IMEWnd_WM_KEYUP( IMM32_IMEWNDPARAM* pParam,
120 WPARAM wParam, LPARAM lParam )
122 BYTE bKeyState[ 256 ];
126 const IMM32_IMEKL* pkl;
128 if ( pParam->hwndActive == (HWND)NULL )
131 /* get context -> get pkl. */
132 hIMC = ImmGetContext( pParam->hwndActive );
133 if ( hIMC == NULLIMC )
135 pIMC = IMM32_LockIMC( hIMC );
138 ImmReleaseContext( pParam->hwndActive, hIMC );
143 GetKeyboardState( bKeyState );
144 if ( !pkl->handlers.pImeProcessKey
145 ( hIMC, wParam, lParam, bKeyState ) )
147 lr = SendMessageA( pParam->hwndActive, WM_IME_KEYUP,
154 IMM32_UnlockIMC( hIMC );
155 ImmReleaseContext( pParam->hwndActive, hIMC );
162 LRESULT CALLBACK IMM32_IMEWndProc( HWND hwnd, UINT nMsg,
163 WPARAM wParam, LPARAM lParam )
165 IMM32_IMEWNDPARAM* pParam =
166 (IMM32_IMEWNDPARAM*)GetWindowLongA( hwnd, 0L );
168 if ( nMsg == WM_CREATE )
170 pParam = (IMM32_IMEWNDPARAM*)IMM32_HeapAlloc(
171 HEAP_ZERO_MEMORY, sizeof(IMM32_IMEWNDPARAM) );
172 if ( pParam == NULL )
174 SetWindowLongA( hwnd, 0L, (LONG)pParam );
176 /* Initialize pParam. */
177 pParam->hwndSelf = hwnd;
178 pParam->hwndActive = (HWND)NULL;
179 pParam->dwBufUsed = 0;
183 else if ( nMsg == WM_DESTROY )
185 /* Uninitialize pParam. */
187 IMM32_HeapFree( pParam );
188 SetWindowLongA( hwnd, 0L, (LONG)NULL );
192 if ( pParam == NULL )
194 if ( IMM32_IsUIMessage( nMsg ) )
196 return DefWindowProcA( hwnd, nMsg, wParam, lParam );
199 /* FIXME - handle all messages. */
200 /* FIXME - handle all notifications. */
204 return IMM32_IMEWnd_WM_KEYDOWN( pParam, wParam, lParam );
206 return IMM32_IMEWnd_WM_KEYUP( pParam, wParam, lParam );
208 ERR( "Why WM_IME_KEYDOWN is generated?\n" );
211 ERR( "Why WM_IME_KEYUP is generated?\n" );
214 FIXME( "ignore WM_IME_CHAR - wParam %08x, lParam %08lx.\n",
218 /* TranslateMessage don't support IME HKL. - FIXME? */
219 FIXME( "ignore WM_CHAR - wParam %08x, lParam %08lx.\n",
224 case WM_IME_STARTCOMPOSITION:
225 case WM_IME_ENDCOMPOSITION:
226 case WM_IME_COMPOSITION:
227 case WM_IME_SETCONTEXT:
229 case WM_IME_COMPOSITIONFULL:
231 case 0x287: /* What is this message? IMM32.DLL returns TRUE. */
232 FIXME( "handle message %08x\n", nMsg );
236 return DefWindowProcA( hwnd, nMsg, wParam, lParam );
240 /***********************************************************************
241 * IMM32_RegisterClass (internal)
243 BOOL IMM32_RegisterIMEWndClass( HINSTANCE hInstDLL )
247 /* SDK says the "IME" window class is a system global class. */
248 wc.style = CS_GLOBALCLASS;
249 wc.lpfnWndProc = IMM32_IMEWndProc;
251 wc.cbWndExtra = sizeof(LONG);
252 wc.hInstance = hInstDLL;
253 wc.hIcon = (HICON)NULL;
254 wc.hCursor = LoadCursorA((HINSTANCE)NULL,IDC_ARROWA);
255 wc.hbrBackground = (HBRUSH)NULL;
256 wc.lpszMenuName = NULL;
257 wc.lpszClassName = IMM32_szIMEClass;
258 if ( !RegisterClassA( &wc ) )
264 /***********************************************************************
265 * IMM32_UnregisterClass (internal)
267 void IMM32_UnregisterIMEWndClass( HINSTANCE hInstDLL )
269 (void)UnregisterClassA( IMM32_szIMEClass, hInstDLL );
272 /***********************************************************************
273 * IMM32_CreateDefaultIMEWnd (internal)
276 HWND IMM32_CreateDefaultIMEWnd( void )
278 return CreateWindowExA( 0L,
280 IMM32_szIMEWindowName,
281 WS_POPUP | WS_CLIPSIBLINGS | WS_OVERLAPPED,
285 (HINSTANCE)GetModuleHandleA(NULL),
289 static BOOL IMM32_IsUIMessage( UINT nMsg )
293 case WM_IME_STARTCOMPOSITION:
294 case WM_IME_ENDCOMPOSITION:
295 case WM_IME_COMPOSITION:
296 case WM_IME_SETCONTEXT:
298 case WM_IME_COMPOSITIONFULL:
300 case 0x287: /* What is this message? IMM32.DLL returns TRUE. */
308 /***********************************************************************
309 * ImmIsUIMessageA (IMM32.@)
311 BOOL WINAPI ImmIsUIMessageA(
312 HWND hwndIME, UINT msg, WPARAM wParam, LPARAM lParam)
314 TRACE("(0x%08x, %d, %d, %ld)\n",
315 hwndIME, msg, wParam, lParam);
317 if ( !IMM32_IsUIMessage( msg ) )
319 if ( hwndIME == (HWND)NULL )
324 case WM_IME_STARTCOMPOSITION:
325 case WM_IME_ENDCOMPOSITION:
326 case WM_IME_COMPOSITION:
327 case WM_IME_SETCONTEXT:
329 case WM_IME_COMPOSITIONFULL:
331 SendMessageA( hwndIME, msg, wParam, lParam );
333 case 0x287: /* What is this message? */
334 FIXME("(0x%08x, %d, %d, %ld) - unknown message 0x287.\n",
335 hwndIME, msg, wParam, lParam);
336 SendMessageA( hwndIME, msg, wParam, lParam );
343 /***********************************************************************
344 * ImmIsUIMessageW (IMM32.@)
346 BOOL WINAPI ImmIsUIMessageW(
347 HWND hwndIME, UINT msg, WPARAM wParam, LPARAM lParam)
349 TRACE("(0x%08x, %d, %d, %ld)\n",
350 hwndIME, msg, wParam, lParam);
352 if ( !IMM32_IsUIMessage( msg ) )
354 if ( hwndIME == (HWND)NULL )
359 case WM_IME_STARTCOMPOSITION:
360 case WM_IME_ENDCOMPOSITION:
361 case WM_IME_COMPOSITION:
362 case WM_IME_SETCONTEXT:
364 case WM_IME_COMPOSITIONFULL:
366 SendMessageW( hwndIME, msg, wParam, lParam );
368 case 0x287: /* What is this message? */
369 FIXME("(0x%08x, %d, %d, %ld) - unknown message 0x287.\n",
370 hwndIME, msg, wParam, lParam);
371 SendMessageW( hwndIME, msg, wParam, lParam );