mirror of
https://github.com/reactos/reactos.git
synced 2024-07-01 02:10:07 +00:00
23bb27037d
Implementing Japanese input... - Add User32CreateImeUIWindow, User32GetImeShowStatus, User32SendImeUIMessage, User32UpdateImcOfImeUI, User32SetImeWindowOfImc and User32NotifyOpenStatus helper functions. - Add WM_IME_SELECT, WM_IME_COMPOSITION, WM_IME_STARTCOMPOSITION and WM_IME_ENDCOMPOSITION message handling of the IME window. - Rename ImeWnd_OnDestroy as User32DestroyImeUIWindow. - Rename CheckIMCForWindow as User32CanSetImeWindowToImc. - Improve ImeWnd_OnCreate function. CORE-11700
645 lines
15 KiB
C
645 lines
15 KiB
C
/*
|
|
* COPYRIGHT: See COPYING in the top level directory
|
|
* PROJECT: ReactOS user32.dll
|
|
* FILE: win32ss/user/user32/misc/imm.c
|
|
* PURPOSE: User32.dll Imm functions
|
|
* PROGRAMMERS: Dmitry Chapyshev (dmitry@reactos.org)
|
|
* Katayama Hirofumi MZ (katayama.hirofumi.mz@gmail.com)
|
|
* UPDATE HISTORY:
|
|
* 01/27/2009 Created
|
|
*/
|
|
|
|
#include <user32.h>
|
|
#include <strsafe.h>
|
|
|
|
WINE_DEFAULT_DEBUG_CHANNEL(user32);
|
|
|
|
#define IMM_INIT_MAGIC 0x19650412
|
|
|
|
/* Is != NULL when we have loaded the IMM ourselves */
|
|
HINSTANCE ghImm32 = NULL;
|
|
|
|
BOOL bImmInitializing = FALSE;
|
|
|
|
/* define stub functions */
|
|
#undef DEFINE_IMM_ENTRY
|
|
#define DEFINE_IMM_ENTRY(type, name, params, retval, retkind) \
|
|
static type WINAPI IMMSTUB_##name params { IMM_RETURN_##retkind((type)retval); }
|
|
#include "immtable.h"
|
|
|
|
Imm32ApiTable gImmApiEntries = {
|
|
/* initialize by stubs */
|
|
#undef DEFINE_IMM_ENTRY
|
|
#define DEFINE_IMM_ENTRY(type, name, params, retval, retkind) \
|
|
IMMSTUB_##name,
|
|
#include "immtable.h"
|
|
};
|
|
|
|
HRESULT
|
|
GetImmFileName(_Out_ LPWSTR lpBuffer,
|
|
_In_ size_t cchBuffer)
|
|
{
|
|
UINT length = GetSystemDirectoryW(lpBuffer, cchBuffer);
|
|
if (length && length < cchBuffer)
|
|
{
|
|
StringCchCatW(lpBuffer, cchBuffer, L"\\");
|
|
return StringCchCatW(lpBuffer, cchBuffer, L"imm32.dll");
|
|
}
|
|
return StringCchCopyW(lpBuffer, cchBuffer, L"imm32.dll");
|
|
}
|
|
|
|
/*
|
|
* @unimplemented
|
|
*/
|
|
static BOOL IntInitializeImmEntryTable(VOID)
|
|
{
|
|
WCHAR ImmFile[MAX_PATH];
|
|
HMODULE imm32 = ghImm32;
|
|
|
|
/* Check whether the IMM table has already been initialized */
|
|
if (IMM_FN(ImmWINNLSEnableIME) != IMMSTUB_ImmWINNLSEnableIME)
|
|
return TRUE;
|
|
|
|
GetImmFileName(ImmFile, _countof(ImmFile));
|
|
TRACE("File %S\n", ImmFile);
|
|
|
|
/* If IMM32 is already loaded, use it without increasing reference count. */
|
|
if (imm32 == NULL)
|
|
imm32 = GetModuleHandleW(ImmFile);
|
|
|
|
/*
|
|
* Loading imm32.dll will call imm32!DllMain function.
|
|
* imm32!DllMain calls User32InitializeImmEntryTable.
|
|
* Thus, if imm32.dll was loaded, the table has been loaded.
|
|
*/
|
|
if (imm32 == NULL)
|
|
{
|
|
imm32 = ghImm32 = LoadLibraryW(ImmFile);
|
|
if (imm32 == NULL)
|
|
{
|
|
ERR("Did not load imm32.dll!\n");
|
|
return FALSE;
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
/* load imm procedures */
|
|
#undef DEFINE_IMM_ENTRY
|
|
#define DEFINE_IMM_ENTRY(type, name, params, retval, retkind) \
|
|
do { \
|
|
FN_##name proc = (FN_##name)GetProcAddress(imm32, #name); \
|
|
if (!proc) { \
|
|
ERR("Could not load %s\n", #name); \
|
|
return FALSE; \
|
|
} \
|
|
IMM_FN(name) = proc; \
|
|
} while (0);
|
|
#include "immtable.h"
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL WINAPI InitializeImmEntryTable(VOID)
|
|
{
|
|
bImmInitializing = TRUE;
|
|
return IntInitializeImmEntryTable();
|
|
}
|
|
|
|
BOOL WINAPI User32InitializeImmEntryTable(DWORD magic)
|
|
{
|
|
TRACE("Imm (%x)\n", magic);
|
|
|
|
if (magic != IMM_INIT_MAGIC)
|
|
return FALSE;
|
|
|
|
/* Check whether the IMM table has already been initialized */
|
|
if (IMM_FN(ImmWINNLSEnableIME) != IMMSTUB_ImmWINNLSEnableIME)
|
|
return TRUE;
|
|
|
|
IntInitializeImmEntryTable();
|
|
|
|
if (ghImm32 == NULL && !bImmInitializing)
|
|
{
|
|
WCHAR ImmFile[MAX_PATH];
|
|
GetImmFileName(ImmFile, _countof(ImmFile));
|
|
ghImm32 = LoadLibraryW(ImmFile);
|
|
if (ghImm32 == NULL)
|
|
{
|
|
ERR("Did not load imm32.dll!\n");
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
return IMM_FN(ImmRegisterClient)(&gSharedInfo, ghImm32);
|
|
}
|
|
|
|
static BOOL User32CanSetImeWindowToImc(HIMC hIMC, HWND hImeWnd)
|
|
{
|
|
PIMC pIMC = ValidateHandle(hIMC, TYPE_INPUTCONTEXT);
|
|
return pIMC && (!pIMC->hImeWnd || pIMC->hImeWnd == hImeWnd || !ValidateHwnd(pIMC->hImeWnd));
|
|
}
|
|
|
|
static BOOL User32GetImeShowStatus(VOID)
|
|
{
|
|
return (BOOL)NtUserCallNoParam(NOPARAM_ROUTINE_GETIMESHOWSTATUS);
|
|
}
|
|
|
|
static LRESULT
|
|
User32SendImeUIMessage(PIMEUI pimeui, UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL unicode)
|
|
{
|
|
LRESULT ret = 0;
|
|
HWND hwndUI = pimeui->hwndUI;
|
|
PWND pwnd, pwndUI;
|
|
|
|
pwnd = pimeui->spwnd;
|
|
pwndUI = ValidateHwnd(hwndUI);
|
|
if (!pwnd || (pwnd->state & WNDS_DESTROYED) || (pwnd->state2 & WNDS2_INDESTROY) ||
|
|
!pwndUI || (pwndUI->state & WNDS_DESTROYED) || (pwndUI->state2 & WNDS2_INDESTROY))
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
InterlockedIncrement(&pimeui->nCntInIMEProc);
|
|
|
|
if (unicode)
|
|
ret = SendMessageW(hwndUI, uMsg, wParam, lParam);
|
|
else
|
|
ret = SendMessageA(hwndUI, uMsg, wParam, lParam);
|
|
|
|
InterlockedDecrement(&pimeui->nCntInIMEProc);
|
|
|
|
return ret;
|
|
}
|
|
|
|
static VOID User32NotifyOpenStatus(PIMEUI pimeui, HWND hwndIMC, BOOL bOpen)
|
|
{
|
|
WPARAM wParam = (bOpen ? IMN_OPENSTATUSWINDOW : IMN_CLOSESTATUSWINDOW);
|
|
|
|
pimeui->fShowStatus = bOpen;
|
|
|
|
if (LOWORD(GetWin32ClientInfo()->dwExpWinVer) >= 0x400)
|
|
SendMessageW(hwndIMC, WM_IME_NOTIFY, wParam, 0);
|
|
else
|
|
User32SendImeUIMessage(pimeui, WM_IME_NOTIFY, wParam, 0, TRUE);
|
|
}
|
|
|
|
static VOID User32SetImeWindowOfImc(HIMC hIMC, HWND hImeWnd)
|
|
{
|
|
PIMC pIMC = ValidateHandle(hIMC, TYPE_INPUTCONTEXT);
|
|
if (!pIMC || pIMC->hImeWnd == hImeWnd)
|
|
return;
|
|
|
|
NtUserUpdateInputContext(hIMC, UIC_IMEWINDOW, (ULONG_PTR)hImeWnd);
|
|
}
|
|
|
|
static VOID User32UpdateImcOfImeUI(PIMEUI pimeui, HIMC hNewIMC)
|
|
{
|
|
HWND hImeWnd = UserHMGetHandle(pimeui->spwnd);
|
|
HIMC hOldIMC = pimeui->hIMC;
|
|
|
|
if (hNewIMC == hOldIMC)
|
|
return;
|
|
|
|
if (hOldIMC)
|
|
User32SetImeWindowOfImc(hOldIMC, NULL);
|
|
|
|
pimeui->hIMC = hNewIMC;
|
|
|
|
if (hNewIMC)
|
|
User32SetImeWindowOfImc(hNewIMC, hImeWnd);
|
|
}
|
|
|
|
static HWND User32CreateImeUIWindow(PIMEUI pimeui, HKL hKL)
|
|
{
|
|
IMEINFOEX ImeInfoEx;
|
|
PIMEDPI pImeDpi;
|
|
WNDCLASSW wc;
|
|
HWND hwndUI = NULL;
|
|
CHAR szUIClass[32];
|
|
PWND pwnd = pimeui->spwnd;
|
|
|
|
if (!pwnd || !IMM_FN(ImmGetImeInfoEx)(&ImeInfoEx, ImeInfoExKeyboardLayout, &hKL))
|
|
return NULL;
|
|
|
|
pImeDpi = IMM_FN(ImmLockImeDpi)(hKL);
|
|
if (!pImeDpi)
|
|
return NULL;
|
|
|
|
if (!GetClassInfoW(pImeDpi->hInst, ImeInfoEx.wszUIClass, &wc))
|
|
goto Quit;
|
|
|
|
if (ImeInfoEx.ImeInfo.fdwProperty & IME_PROP_UNICODE)
|
|
{
|
|
hwndUI = CreateWindowW(ImeInfoEx.wszUIClass, ImeInfoEx.wszUIClass, WS_POPUP | WS_DISABLED,
|
|
0, 0, 0, 0, UserHMGetHandle(pwnd), 0, wc.hInstance, NULL);
|
|
}
|
|
else
|
|
{
|
|
WideCharToMultiByte(CP_ACP, 0, ImeInfoEx.wszUIClass, -1,
|
|
szUIClass, _countof(szUIClass), NULL, NULL);
|
|
szUIClass[_countof(szUIClass) - 1] = 0;
|
|
|
|
hwndUI = CreateWindowA(szUIClass, szUIClass, WS_POPUP | WS_DISABLED,
|
|
0, 0, 0, 0, UserHMGetHandle(pwnd), 0, wc.hInstance, NULL);
|
|
}
|
|
|
|
if (hwndUI)
|
|
NtUserSetWindowLong(hwndUI, IMMGWL_IMC, (LONG_PTR)pimeui->hIMC, FALSE);
|
|
|
|
Quit:
|
|
IMM_FN(ImmUnlockImeDpi)(pImeDpi);
|
|
return hwndUI;
|
|
}
|
|
|
|
static BOOL ImeWnd_OnCreate(PIMEUI pimeui, LPCREATESTRUCT lpCS)
|
|
{
|
|
PWND pParentWnd, pWnd = pimeui->spwnd;
|
|
HIMC hIMC = NULL;
|
|
|
|
if (!pWnd || (pWnd->style & (WS_DISABLED | WS_POPUP)) != (WS_DISABLED | WS_POPUP))
|
|
return FALSE;
|
|
|
|
pParentWnd = ValidateHwnd(lpCS->hwndParent);
|
|
if (pParentWnd)
|
|
{
|
|
hIMC = pParentWnd->hImc;
|
|
if (hIMC && !User32CanSetImeWindowToImc(hIMC, UserHMGetHandle(pWnd)))
|
|
hIMC = NULL;
|
|
}
|
|
|
|
User32UpdateImcOfImeUI(pimeui, hIMC);
|
|
|
|
pimeui->fShowStatus = FALSE;
|
|
pimeui->nCntInIMEProc = 0;
|
|
pimeui->fActivate = FALSE;
|
|
pimeui->fDestroy = FALSE;
|
|
pimeui->hwndIMC = NULL;
|
|
pimeui->hKL = GetWin32ClientInfo()->hKL;
|
|
pimeui->fCtrlShowStatus = TRUE;
|
|
|
|
IMM_FN(ImmLoadIME)(pimeui->hKL);
|
|
|
|
pimeui->hwndUI = NULL;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
static VOID User32DestroyImeUIWindow(PIMEUI pimeui)
|
|
{
|
|
HWND hwndUI = pimeui->hwndUI;
|
|
|
|
if (IsWindow(hwndUI))
|
|
{
|
|
pimeui->fDestroy = TRUE;
|
|
NtUserDestroyWindow(hwndUI);
|
|
}
|
|
|
|
pimeui->fShowStatus = pimeui->fDestroy = FALSE;
|
|
pimeui->hwndUI = NULL;
|
|
}
|
|
|
|
VOID ImeWnd_OnImeSelect(PIMEUI pimeui, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
HKL hKL;
|
|
HWND hwndUI, hwndIMC = pimeui->hwndIMC;
|
|
|
|
if (wParam)
|
|
{
|
|
pimeui->hKL = hKL = (HKL)lParam;
|
|
pimeui->hwndUI = hwndUI = User32CreateImeUIWindow(pimeui, hKL);
|
|
if (hwndUI)
|
|
User32SendImeUIMessage(pimeui, WM_IME_SELECT, wParam, lParam, TRUE);
|
|
|
|
if (User32GetImeShowStatus() && pimeui->fCtrlShowStatus)
|
|
{
|
|
if (!pimeui->fShowStatus && pimeui->fActivate && IsWindow(hwndIMC))
|
|
User32NotifyOpenStatus(pimeui, hwndIMC, TRUE);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (pimeui->fShowStatus && pimeui->fActivate && IsWindow(hwndIMC))
|
|
User32NotifyOpenStatus(pimeui, hwndIMC, FALSE);
|
|
|
|
User32SendImeUIMessage(pimeui, WM_IME_SELECT, wParam, lParam, TRUE);
|
|
User32DestroyImeUIWindow(pimeui);
|
|
pimeui->hKL = NULL;
|
|
}
|
|
}
|
|
|
|
LRESULT WINAPI ImeWndProc_common( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam, BOOL unicode ) // ReactOS
|
|
{
|
|
PWND pWnd;
|
|
PIMEUI pimeui;
|
|
|
|
pWnd = ValidateHwnd(hwnd);
|
|
if (pWnd)
|
|
{
|
|
if (!pWnd->fnid)
|
|
{
|
|
if (msg != WM_NCCREATE)
|
|
{
|
|
if (unicode)
|
|
return DefWindowProcW(hwnd, msg, wParam, lParam);
|
|
return DefWindowProcA(hwnd, msg, wParam, lParam);
|
|
}
|
|
NtUserSetWindowFNID(hwnd, FNID_IME);
|
|
pimeui = HeapAlloc( GetProcessHeap(), 0, sizeof(IMEUI) );
|
|
pimeui->spwnd = pWnd;
|
|
SetWindowLongPtrW(hwnd, 0, (LONG_PTR)pimeui);
|
|
}
|
|
else
|
|
{
|
|
if (pWnd->fnid != FNID_IME)
|
|
{
|
|
ERR("Wrong window class for Ime! fnId 0x%x\n",pWnd->fnid);
|
|
return 0;
|
|
}
|
|
pimeui = ((PIMEWND)pWnd)->pimeui;
|
|
if (pimeui == NULL)
|
|
{
|
|
ERR("Window is not set to IME!\n");
|
|
return 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (pimeui->nCntInIMEProc > 0)
|
|
{
|
|
switch (msg)
|
|
{
|
|
case WM_IME_CHAR:
|
|
case WM_IME_COMPOSITIONFULL:
|
|
case WM_IME_CONTROL:
|
|
case WM_IME_NOTIFY:
|
|
case WM_IME_REQUEST:
|
|
case WM_IME_SELECT:
|
|
case WM_IME_SETCONTEXT:
|
|
case WM_IME_STARTCOMPOSITION:
|
|
case WM_IME_COMPOSITION:
|
|
case WM_IME_ENDCOMPOSITION:
|
|
return 0;
|
|
|
|
case WM_IME_SYSTEM:
|
|
// TODO:
|
|
return 0;
|
|
|
|
default:
|
|
{
|
|
if (unicode)
|
|
return DefWindowProcW(hwnd, msg, wParam, lParam);
|
|
return DefWindowProcA(hwnd, msg, wParam, lParam);
|
|
}
|
|
}
|
|
}
|
|
|
|
switch (msg)
|
|
{
|
|
case WM_CREATE:
|
|
return (ImeWnd_OnCreate(pimeui, (LPCREATESTRUCT)lParam) ? 0 : -1);
|
|
|
|
case WM_DESTROY:
|
|
User32DestroyImeUIWindow(pimeui);
|
|
break;
|
|
|
|
case WM_NCDESTROY:
|
|
HeapFree(GetProcessHeap(), 0, pimeui);
|
|
SetWindowLongPtrW(hwnd, 0, 0);
|
|
NtUserSetWindowFNID(hwnd, FNID_DESTROY);
|
|
break;
|
|
|
|
case WM_ERASEBKGND:
|
|
return TRUE;
|
|
|
|
case WM_PAINT:
|
|
break;
|
|
|
|
case WM_COPYDATA:
|
|
// TODO:
|
|
break;
|
|
|
|
case WM_IME_STARTCOMPOSITION:
|
|
case WM_IME_COMPOSITION:
|
|
case WM_IME_ENDCOMPOSITION:
|
|
return User32SendImeUIMessage(pimeui, msg, wParam, lParam, unicode);
|
|
|
|
case WM_IME_CONTROL:
|
|
// TODO:
|
|
break;
|
|
|
|
case WM_IME_NOTIFY:
|
|
// TODO:
|
|
break;
|
|
|
|
case WM_IME_REQUEST:
|
|
break;
|
|
|
|
case WM_IME_SELECT:
|
|
ImeWnd_OnImeSelect(pimeui, wParam, lParam);
|
|
break;
|
|
|
|
case WM_IME_SETCONTEXT:
|
|
// TODO:
|
|
break;
|
|
|
|
case WM_IME_SYSTEM:
|
|
// TODO:
|
|
break;
|
|
|
|
default:
|
|
{
|
|
if (unicode)
|
|
return DefWindowProcW(hwnd, msg, wParam, lParam);
|
|
return DefWindowProcA(hwnd, msg, wParam, lParam);
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
LRESULT WINAPI ImeWndProcA( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
|
|
{
|
|
return ImeWndProc_common(hwnd, msg, wParam, lParam, FALSE);
|
|
}
|
|
|
|
LRESULT WINAPI ImeWndProcW( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
|
|
{
|
|
return ImeWndProc_common(hwnd, msg, wParam, lParam, TRUE);
|
|
}
|
|
|
|
BOOL
|
|
WINAPI
|
|
UpdatePerUserImmEnabling(VOID)
|
|
{
|
|
BOOL Ret = NtUserCallNoParam(NOPARAM_ROUTINE_UPDATEPERUSERIMMENABLING);
|
|
if ( Ret )
|
|
{
|
|
if ( gpsi->dwSRVIFlags & SRVINFO_IMM32 )
|
|
{
|
|
HMODULE imm32 = GetModuleHandleW(L"imm32.dll");
|
|
if ( !imm32 )
|
|
{
|
|
imm32 = LoadLibraryW(L"imm32.dll");
|
|
if (!imm32)
|
|
{
|
|
ERR("UPUIE: Imm32 not installed!\n");
|
|
Ret = FALSE;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return Ret;
|
|
}
|
|
|
|
static const WCHAR imeW[] = {'I','M','E',0};
|
|
|
|
BOOL
|
|
WINAPI
|
|
RegisterIMEClass(VOID)
|
|
{
|
|
WNDCLASSEXW WndClass;
|
|
ATOM atom;
|
|
|
|
ZeroMemory(&WndClass, sizeof(WndClass));
|
|
|
|
WndClass.cbSize = sizeof(WndClass);
|
|
WndClass.lpszClassName = imeW;
|
|
WndClass.style = CS_GLOBALCLASS;
|
|
WndClass.lpfnWndProc = ImeWndProcW;
|
|
WndClass.cbWndExtra = sizeof(LONG_PTR);
|
|
WndClass.hCursor = LoadCursorW(NULL, IDC_ARROW);
|
|
|
|
atom = RegisterClassExWOWW( &WndClass,
|
|
0,
|
|
FNID_IME,
|
|
0,
|
|
FALSE);
|
|
if (atom)
|
|
{
|
|
RegisterDefaultClasses |= ICLASS_TO_MASK(ICLS_IME);
|
|
TRACE("Register IME Class!\n");
|
|
return TRUE;
|
|
}
|
|
ERR("Failed to register IME Class!\n");
|
|
return FALSE;
|
|
}
|
|
|
|
/*
|
|
* @unimplemented
|
|
*/
|
|
BOOL WINAPI CliImmSetHotKey(DWORD dwID, UINT uModifiers, UINT uVirtualKey, HKL hKl)
|
|
{
|
|
UNIMPLEMENTED;
|
|
return FALSE;
|
|
}
|
|
|
|
/*
|
|
* @implemented
|
|
*/
|
|
BOOL
|
|
WINAPI
|
|
IMPSetIMEW(HWND hwnd, LPIMEPROW ime)
|
|
{
|
|
return IMM_FN(ImmIMPSetIMEW)(hwnd, ime);
|
|
}
|
|
|
|
/*
|
|
* @implemented
|
|
*/
|
|
BOOL
|
|
WINAPI
|
|
IMPQueryIMEW(LPIMEPROW ime)
|
|
{
|
|
return IMM_FN(ImmIMPQueryIMEW)(ime);
|
|
}
|
|
|
|
/*
|
|
* @implemented
|
|
*/
|
|
BOOL
|
|
WINAPI
|
|
IMPGetIMEW(HWND hwnd, LPIMEPROW ime)
|
|
{
|
|
return IMM_FN(ImmIMPGetIMEW)(hwnd, ime);
|
|
}
|
|
|
|
/*
|
|
* @implemented
|
|
*/
|
|
BOOL
|
|
WINAPI
|
|
IMPSetIMEA(HWND hwnd, LPIMEPROA ime)
|
|
{
|
|
return IMM_FN(ImmIMPSetIMEA)(hwnd, ime);
|
|
}
|
|
|
|
/*
|
|
* @implemented
|
|
*/
|
|
BOOL
|
|
WINAPI
|
|
IMPQueryIMEA(LPIMEPROA ime)
|
|
{
|
|
return IMM_FN(ImmIMPQueryIMEA)(ime);
|
|
}
|
|
|
|
/*
|
|
* @implemented
|
|
*/
|
|
BOOL
|
|
WINAPI
|
|
IMPGetIMEA(HWND hwnd, LPIMEPROA ime)
|
|
{
|
|
return IMM_FN(ImmIMPGetIMEA)(hwnd, ime);
|
|
}
|
|
|
|
/*
|
|
* @implemented
|
|
*/
|
|
LRESULT
|
|
WINAPI
|
|
SendIMEMessageExW(HWND hwnd, LPARAM lParam)
|
|
{
|
|
return IMM_FN(ImmSendIMEMessageExW)(hwnd, lParam);
|
|
}
|
|
|
|
/*
|
|
* @implemented
|
|
*/
|
|
LRESULT
|
|
WINAPI
|
|
SendIMEMessageExA(HWND hwnd, LPARAM lParam)
|
|
{
|
|
return IMM_FN(ImmSendIMEMessageExA)(hwnd, lParam);
|
|
}
|
|
|
|
/*
|
|
* @implemented
|
|
*/
|
|
BOOL
|
|
WINAPI
|
|
WINNLSEnableIME(HWND hwnd, BOOL enable)
|
|
{
|
|
return IMM_FN(ImmWINNLSEnableIME)(hwnd, enable);
|
|
}
|
|
|
|
/*
|
|
* @implemented
|
|
*/
|
|
BOOL
|
|
WINAPI
|
|
WINNLSGetEnableStatus(HWND hwnd)
|
|
{
|
|
return IMM_FN(ImmWINNLSGetEnableStatus)(hwnd);
|
|
}
|
|
|
|
/*
|
|
* @implemented
|
|
*/
|
|
UINT
|
|
WINAPI
|
|
WINNLSGetIMEHotkey(HWND hwnd)
|
|
{
|
|
return FALSE;
|
|
}
|