diff --git a/reactos/dll/win32/imm32/imm.c b/reactos/dll/win32/imm32/imm.c
index 22cd75c7b71..02a362e0c33 100644
--- a/reactos/dll/win32/imm32/imm.c
+++ b/reactos/dll/win32/imm32/imm.c
@@ -51,6 +51,7 @@ typedef struct tagInputContextData
BOOL bOpen;
BOOL bInternalState;
BOOL bRead;
+ BOOL bInComposition;
LOGFONTW font;
HFONT textfont;
COMPOSITIONFORM CompForm;
@@ -60,6 +61,7 @@ static InputContextData *root_context = NULL;
static HWND hwndDefault = NULL;
static HANDLE hImeInst;
static const WCHAR WC_IMECLASSNAME[] = {'I','M','E',0};
+static ATOM atIMEClass = 0;
/* MSIME messages */
static UINT WM_MSIME_SERVICE;
@@ -109,12 +111,14 @@ static void IMM_Register(void)
wndClass.hbrBackground = (HBRUSH)(COLOR_WINDOW +1);
wndClass.lpszMenuName = 0;
wndClass.lpszClassName = WC_IMECLASSNAME;
- RegisterClassW(&wndClass);
+ atIMEClass = RegisterClassW(&wndClass);
}
static void IMM_Unregister(void)
{
- UnregisterClassW(WC_IMECLASSNAME, NULL);
+ if (atIMEClass) {
+ UnregisterClassW(WC_IMECLASSNAME, NULL);
+ }
}
static void IMM_RegisterMessages(void)
@@ -165,6 +169,18 @@ static void ImmInternalPostIMEMessage(UINT msg, WPARAM wParam, LPARAM lParam)
PostMessageW(target, msg, wParam, lParam);
}
+static LRESULT ImmInternalSendIMENotify(WPARAM notify, LPARAM lParam)
+{
+ HWND target;
+
+ target = root_context->hwnd;
+ if (!target) target = GetFocus();
+
+ if (target)
+ return SendMessageW(target, WM_IME_NOTIFY, notify, lParam);
+
+ return 0;
+}
static void ImmInternalSetOpenStatus(BOOL fOpen)
{
@@ -198,7 +214,7 @@ static void ImmInternalSetOpenStatus(BOOL fOpen)
else
ShowWindow(hwndDefault, SW_SHOWNOACTIVATE);
- SendMessageW(root_context->hwnd, WM_IME_NOTIFY, IMN_SETOPENSTATUS, 0);
+ ImmInternalSendIMENotify(IMN_SETOPENSTATUS, 0);
}
@@ -560,6 +576,21 @@ LONG WINAPI ImmGetCompositionStringA(
}
rc = sizeof(DWORD)*2;
}
+ else if (dwIndex == GCS_RESULTCLAUSE)
+ {
+ TRACE("GSC_RESULTCLAUSE %p %i\n", data->ResultString, data->dwResultStringSize);
+
+ rc = WideCharToMultiByte(CP_ACP, 0, (LPWSTR)data->ResultString,
+ data->dwResultStringSize/ sizeof(WCHAR), NULL,
+ 0, NULL, NULL);
+
+ if (dwBufLen >= sizeof(DWORD)*2)
+ {
+ ((LPDWORD)lpBuf)[0] = 0;
+ ((LPDWORD)lpBuf)[1] = rc;
+ }
+ rc = sizeof(DWORD)*2;
+ }
else
{
FIXME("Unhandled index 0x%x\n",dwIndex);
@@ -1112,6 +1143,9 @@ BOOL WINAPI ImmNotifyIME(
ImmInternalPostIMEMessage(WM_IME_COMPOSITION,
root_context->ResultString[0],
GCS_RESULTSTR|GCS_RESULTCLAUSE);
+
+ ImmInternalPostIMEMessage(WM_IME_ENDCOMPOSITION, 0, 0);
+ root_context->bInComposition = FALSE;
}
break;
case CPS_CONVERT:
@@ -1209,7 +1243,7 @@ BOOL WINAPI ImmSetCompositionFontA(HIMC hIMC, LPLOGFONTA lplf)
MultiByteToWideChar(CP_ACP, 0, lplf->lfFaceName, -1, data->font.lfFaceName,
LF_FACESIZE);
- SendMessageW(root_context->hwnd, WM_IME_NOTIFY, IMN_SETCOMPOSITIONFONT, 0);
+ ImmInternalSendIMENotify(IMN_SETCOMPOSITIONFONT, 0);
if (data->textfont)
{
@@ -1233,7 +1267,7 @@ BOOL WINAPI ImmSetCompositionFontW(HIMC hIMC, LPLOGFONTW lplf)
return FALSE;
memcpy(&data->font,lplf,sizeof(LOGFONTW));
- SendMessageW(root_context->hwnd, WM_IME_NOTIFY, IMN_SETCOMPOSITIONFONT, 0);
+ ImmInternalSendIMENotify(IMN_SETCOMPOSITIONFONT, 0);
if (data->textfont)
{
@@ -1319,6 +1353,12 @@ BOOL WINAPI ImmSetCompositionStringW(
if (dwIndex == SCS_SETSTR)
{
+ if (!root_context->bInComposition)
+ {
+ ImmInternalPostIMEMessage(WM_IME_STARTCOMPOSITION, 0, 0);
+ root_context->bInComposition = TRUE;
+ }
+
flags = GCS_COMPSTR;
if (root_context->dwCompStringLength)
@@ -1378,7 +1418,7 @@ BOOL WINAPI ImmSetCompositionWindow(
if (reshow)
ShowWindow(hwndDefault,SW_SHOWNOACTIVATE);
- SendMessageW(root_context->hwnd, WM_IME_NOTIFY,IMN_SETCOMPOSITIONWINDOW, 0);
+ ImmInternalSendIMENotify(IMN_SETCOMPOSITIONWINDOW, 0);
return TRUE;
}
@@ -1406,14 +1446,8 @@ BOOL WINAPI ImmSetOpenStatus(HIMC hIMC, BOOL fOpen)
if (hIMC == (HIMC)FROM_IME)
{
- if (fOpen)
- ImmInternalPostIMEMessage(WM_IME_STARTCOMPOSITION, 0, 0);
-
ImmInternalSetOpenStatus(fOpen);
-
- if (!fOpen)
- ImmInternalPostIMEMessage(WM_IME_ENDCOMPOSITION, 0, 0);
-
+ ImmInternalSendIMENotify(IMN_SETOPENSTATUS, 0);
return TRUE;
}
@@ -1489,6 +1523,29 @@ BOOL WINAPI ImmUnregisterWordW(
return FALSE;
}
+/***********************************************************************
+ * ImmGetImeMenuItemsA (IMM32.@)
+ */
+DWORD WINAPI ImmGetImeMenuItemsA( HIMC hIMC, DWORD dwFlags, DWORD dwType,
+ LPIMEMENUITEMINFOA lpImeParentMenu, LPIMEMENUITEMINFOA lpImeMenu,
+ DWORD dwSize)
+{
+ FIXME("(%p, %i, %i, %p, %p, %i): stub\n", hIMC, dwFlags, dwType,
+ lpImeParentMenu, lpImeMenu, dwSize);
+ return 0;
+}
+
+/***********************************************************************
+* ImmGetImeMenuItemsW (IMM32.@)
+*/
+DWORD WINAPI ImmGetImeMenuItemsW( HIMC hIMC, DWORD dwFlags, DWORD dwType,
+ LPIMEMENUITEMINFOW lpImeParentMenu, LPIMEMENUITEMINFOW lpImeMenu,
+ DWORD dwSize)
+{
+ FIXME("(%p, %i, %i, %p, %p, %i): stub\n", hIMC, dwFlags, dwType,
+ lpImeParentMenu, lpImeMenu, dwSize);
+ return 0;
+}
/*****
* Internal functions to help with IME window management
@@ -1566,7 +1623,7 @@ static LRESULT WINAPI IME_WindowProc(HWND hwnd, UINT msg, WPARAM wParam,
TRACE("IME message %s, 0x%x, 0x%x (%i)\n",
"WM_IME_COMPOSITION", (UINT)wParam, (UINT)lParam,
root_context->bRead);
- if ((lParam & GCS_RESULTSTR) && (!root_context->bRead))
+ if (lParam & GCS_RESULTSTR)
IMM_PostResult(root_context);
else
UpdateDataInDefaultIMEWindow(hwnd);
diff --git a/reactos/dll/win32/imm32/imm32.rbuild b/reactos/dll/win32/imm32/imm32.rbuild
index 3f54930bb08..4018cde39e0 100644
--- a/reactos/dll/win32/imm32/imm32.rbuild
+++ b/reactos/dll/win32/imm32/imm32.rbuild
@@ -14,5 +14,6 @@
kernel32
ntdll
imm.c
+ version.rc
imm32.spec
diff --git a/reactos/dll/win32/imm32/imm32.spec b/reactos/dll/win32/imm32/imm32.spec
index bf8ceaa90ed..01349540d1b 100644
--- a/reactos/dll/win32/imm32/imm32.spec
+++ b/reactos/dll/win32/imm32/imm32.spec
@@ -43,10 +43,10 @@
@ stub ImmGetIMCCSize
@ stub ImmGetIMCLockCount
@ stdcall ImmGetIMEFileNameA(long ptr long)
-@ stdcall ImmGetIMEFileNameW(long ptr long)
+@ stdcall ImmGetIMEFileNameW(long ptr long)
@ stub ImmGetImeInfoEx
-@ stub ImmGetImeMenuItemsA
-@ stub ImmGetImeMenuItemsW
+@ stdcall ImmGetImeMenuItemsA(long long long ptr ptr long)
+@ stdcall ImmGetImeMenuItemsW(long long long ptr ptr long)
@ stdcall ImmGetOpenStatus(long)
@ stdcall ImmGetProperty(long long)
@ stdcall ImmGetRegisterWordStyleA(long long ptr)
diff --git a/reactos/dll/win32/imm32/version.rc b/reactos/dll/win32/imm32/version.rc
new file mode 100644
index 00000000000..ae821025c01
--- /dev/null
+++ b/reactos/dll/win32/imm32/version.rc
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2007 Alexandre Julliard
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#define WINE_FILEDESCRIPTION_STR "Wine imm32"
+#define WINE_FILENAME_STR "imm32.dll"
+#define WINE_FILEVERSION 5,1,2600,2180
+#define WINE_FILEVERSION_STR "5.1.2600.2180"
+#define WINE_PRODUCTVERSION 5,1,2600,2180
+#define WINE_PRODUCTVERSION_STR "5.1.2600.2180"
+
+#include "wine/wine_common_ver.rc"