2005-12-12 20:59:55 +00:00
|
|
|
/*
|
|
|
|
* IMM32 library
|
|
|
|
*
|
|
|
|
* Copyright 1998 Patrik Stridvall
|
2007-09-14 08:03:04 +00:00
|
|
|
* Copyright 2002, 2003, 2007 CodeWeavers, Aric Stewart
|
2005-12-12 20:59:55 +00:00
|
|
|
*
|
|
|
|
* 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
|
2006-07-06 11:22:04 +00:00
|
|
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
2005-12-12 20:59:55 +00:00
|
|
|
*/
|
|
|
|
|
2013-01-24 23:00:42 +00:00
|
|
|
#define WIN32_NO_STATUS
|
|
|
|
|
|
|
|
//#include <stdarg.h>
|
2010-03-07 11:27:14 +00:00
|
|
|
#include <stdio.h>
|
2005-12-12 20:59:55 +00:00
|
|
|
|
2013-01-24 23:00:42 +00:00
|
|
|
#include <windef.h>
|
|
|
|
#include <winbase.h>
|
|
|
|
//#include "wingdi.h"
|
|
|
|
#include <winuser.h>
|
|
|
|
//#include "winerror.h"
|
|
|
|
#include <wine/debug.h>
|
|
|
|
//#include "imm.h"
|
|
|
|
#include <ddk/imm.h>
|
|
|
|
#include <winnls.h>
|
|
|
|
#include <winreg.h>
|
|
|
|
#include <wine/list.h>
|
2014-09-28 18:27:58 +00:00
|
|
|
#include <wine/unicode.h>
|
2005-12-12 20:59:55 +00:00
|
|
|
|
|
|
|
WINE_DEFAULT_DEBUG_CHANNEL(imm);
|
|
|
|
|
2017-12-08 03:14:21 +00:00
|
|
|
#define IMM_INIT_MAGIC 0x19650412
|
|
|
|
BOOL WINAPI User32InitializeImmEntryTable(DWORD);
|
|
|
|
|
2008-04-04 13:20:27 +00:00
|
|
|
#define MAKE_FUNCPTR(f) typeof(f) * p##f
|
|
|
|
typedef struct _tagImmHkl{
|
|
|
|
struct list entry;
|
|
|
|
HKL hkl;
|
|
|
|
HMODULE hIME;
|
|
|
|
IMEINFO imeInfo;
|
|
|
|
WCHAR imeClassName[17]; /* 16 character max */
|
|
|
|
ULONG uSelected;
|
2013-02-03 20:58:12 +00:00
|
|
|
HWND UIWnd;
|
2008-04-04 13:20:27 +00:00
|
|
|
|
|
|
|
/* Function Pointers */
|
|
|
|
MAKE_FUNCPTR(ImeInquire);
|
|
|
|
MAKE_FUNCPTR(ImeConfigure);
|
|
|
|
MAKE_FUNCPTR(ImeDestroy);
|
|
|
|
MAKE_FUNCPTR(ImeEscape);
|
|
|
|
MAKE_FUNCPTR(ImeSelect);
|
|
|
|
MAKE_FUNCPTR(ImeSetActiveContext);
|
|
|
|
MAKE_FUNCPTR(ImeToAsciiEx);
|
|
|
|
MAKE_FUNCPTR(NotifyIME);
|
|
|
|
MAKE_FUNCPTR(ImeRegisterWord);
|
|
|
|
MAKE_FUNCPTR(ImeUnregisterWord);
|
|
|
|
MAKE_FUNCPTR(ImeEnumRegisterWord);
|
|
|
|
MAKE_FUNCPTR(ImeSetCompositionString);
|
|
|
|
MAKE_FUNCPTR(ImeConversionList);
|
|
|
|
MAKE_FUNCPTR(ImeProcessKey);
|
|
|
|
MAKE_FUNCPTR(ImeGetRegisterWordStyle);
|
|
|
|
MAKE_FUNCPTR(ImeGetImeMenuItems);
|
|
|
|
} ImmHkl;
|
|
|
|
#undef MAKE_FUNCPTR
|
|
|
|
|
2005-12-12 20:59:55 +00:00
|
|
|
typedef struct tagInputContextData
|
|
|
|
{
|
2007-09-14 08:03:04 +00:00
|
|
|
DWORD dwLock;
|
|
|
|
INPUTCONTEXT IMC;
|
2017-12-08 03:14:21 +00:00
|
|
|
DWORD threadID;
|
2008-04-04 13:20:27 +00:00
|
|
|
|
|
|
|
ImmHkl *immKbd;
|
2010-03-07 11:27:14 +00:00
|
|
|
UINT lastVK;
|
2017-12-08 03:14:21 +00:00
|
|
|
BOOL threadDefault;
|
2014-09-28 18:27:58 +00:00
|
|
|
DWORD magic;
|
2005-12-12 20:59:55 +00:00
|
|
|
} InputContextData;
|
|
|
|
|
2014-09-28 18:27:58 +00:00
|
|
|
#define WINE_IMC_VALID_MAGIC 0x56434D49
|
|
|
|
|
2008-04-04 13:20:27 +00:00
|
|
|
typedef struct _tagTRANSMSG {
|
|
|
|
UINT message;
|
|
|
|
WPARAM wParam;
|
|
|
|
LPARAM lParam;
|
|
|
|
} TRANSMSG, *LPTRANSMSG;
|
|
|
|
|
2010-03-07 11:27:14 +00:00
|
|
|
typedef struct _tagIMMThreadData {
|
2017-12-08 03:14:21 +00:00
|
|
|
struct list entry;
|
|
|
|
DWORD threadID;
|
2010-03-07 11:27:14 +00:00
|
|
|
HIMC defaultContext;
|
|
|
|
HWND hwndDefault;
|
2017-12-08 03:14:21 +00:00
|
|
|
BOOL disableIME;
|
|
|
|
DWORD windowRefs;
|
2010-03-07 11:27:14 +00:00
|
|
|
} IMMThreadData;
|
2005-12-12 20:59:55 +00:00
|
|
|
|
2008-04-04 13:20:27 +00:00
|
|
|
static struct list ImmHklList = LIST_INIT(ImmHklList);
|
2017-12-08 03:14:21 +00:00
|
|
|
static struct list ImmThreadDataList = LIST_INIT(ImmThreadDataList);
|
2005-12-12 20:59:55 +00:00
|
|
|
|
2008-04-04 13:20:27 +00:00
|
|
|
static const WCHAR szwWineIMCProperty[] = {'W','i','n','e','I','m','m','H','I','M','C','P','r','o','p','e','r','t','y',0};
|
2010-03-07 11:27:14 +00:00
|
|
|
|
|
|
|
static const WCHAR szImeFileW[] = {'I','m','e',' ','F','i','l','e',0};
|
|
|
|
static const WCHAR szLayoutTextW[] = {'L','a','y','o','u','t',' ','T','e','x','t',0};
|
|
|
|
static const WCHAR szImeRegFmt[] = {'S','y','s','t','e','m','\\','C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\','C','o','n','t','r','o','l','\\','K','e','y','b','o','a','r','d',' ','L','a','y','o','u','t','s','\\','%','0','8','l','x',0};
|
|
|
|
|
2013-02-03 20:58:12 +00:00
|
|
|
static const WCHAR szwIME[] = {'I','M','E',0};
|
2017-12-08 03:14:21 +00:00
|
|
|
static const WCHAR szwDefaultIME[] = {'D','e','f','a','u','l','t',' ','I','M','E',0};
|
2013-02-03 20:58:12 +00:00
|
|
|
|
2017-12-08 03:14:21 +00:00
|
|
|
static CRITICAL_SECTION threaddata_cs;
|
|
|
|
static CRITICAL_SECTION_DEBUG critsect_debug =
|
|
|
|
{
|
|
|
|
0, 0, &threaddata_cs,
|
|
|
|
{ &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList },
|
|
|
|
0, 0, { (DWORD_PTR)(__FILE__ ": threaddata_cs") }
|
|
|
|
};
|
|
|
|
static CRITICAL_SECTION threaddata_cs = { &critsect_debug, -1, 0, 0, 0, 0 };
|
|
|
|
static BOOL disable_ime;
|
2010-03-07 11:27:14 +00:00
|
|
|
|
|
|
|
#define is_himc_ime_unicode(p) (p->immKbd->imeInfo.fdwProperty & IME_PROP_UNICODE)
|
|
|
|
#define is_kbd_ime_unicode(p) (p->imeInfo.fdwProperty & IME_PROP_UNICODE)
|
|
|
|
|
|
|
|
static BOOL IMM_DestroyContext(HIMC hIMC);
|
2017-12-08 03:14:21 +00:00
|
|
|
static InputContextData* get_imc_data(HIMC hIMC);
|
2010-03-07 11:27:14 +00:00
|
|
|
|
|
|
|
static inline WCHAR *strdupAtoW( const char *str )
|
|
|
|
{
|
|
|
|
WCHAR *ret = NULL;
|
|
|
|
if (str)
|
|
|
|
{
|
|
|
|
DWORD len = MultiByteToWideChar( CP_ACP, 0, str, -1, NULL, 0 );
|
|
|
|
if ((ret = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) )))
|
|
|
|
MultiByteToWideChar( CP_ACP, 0, str, -1, ret, len );
|
|
|
|
}
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline CHAR *strdupWtoA( const WCHAR *str )
|
|
|
|
{
|
|
|
|
CHAR *ret = NULL;
|
|
|
|
if (str)
|
|
|
|
{
|
|
|
|
DWORD len = WideCharToMultiByte( CP_ACP, 0, str, -1, NULL, 0, NULL, NULL );
|
|
|
|
if ((ret = HeapAlloc( GetProcessHeap(), 0, len )))
|
|
|
|
WideCharToMultiByte( CP_ACP, 0, str, -1, ret, len, NULL, NULL );
|
|
|
|
}
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static DWORD convert_candidatelist_WtoA(
|
|
|
|
LPCANDIDATELIST lpSrc, LPCANDIDATELIST lpDst, DWORD dwBufLen)
|
|
|
|
{
|
|
|
|
DWORD ret, i, len;
|
|
|
|
|
|
|
|
ret = FIELD_OFFSET( CANDIDATELIST, dwOffset[lpSrc->dwCount] );
|
|
|
|
if ( lpDst && dwBufLen > 0 )
|
|
|
|
{
|
|
|
|
*lpDst = *lpSrc;
|
|
|
|
lpDst->dwOffset[0] = ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
for ( i = 0; i < lpSrc->dwCount; i++)
|
|
|
|
{
|
|
|
|
LPBYTE src = (LPBYTE)lpSrc + lpSrc->dwOffset[i];
|
|
|
|
|
|
|
|
if ( lpDst && dwBufLen > 0 )
|
|
|
|
{
|
|
|
|
LPBYTE dest = (LPBYTE)lpDst + lpDst->dwOffset[i];
|
|
|
|
|
|
|
|
len = WideCharToMultiByte(CP_ACP, 0, (LPCWSTR)src, -1,
|
|
|
|
(LPSTR)dest, dwBufLen, NULL, NULL);
|
|
|
|
|
|
|
|
if ( i + 1 < lpSrc->dwCount )
|
|
|
|
lpDst->dwOffset[i+1] = lpDst->dwOffset[i] + len * sizeof(char);
|
|
|
|
dwBufLen -= len * sizeof(char);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
len = WideCharToMultiByte(CP_ACP, 0, (LPCWSTR)src, -1, NULL, 0, NULL, NULL);
|
|
|
|
|
|
|
|
ret += len * sizeof(char);
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( lpDst )
|
|
|
|
lpDst->dwSize = ret;
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static DWORD convert_candidatelist_AtoW(
|
|
|
|
LPCANDIDATELIST lpSrc, LPCANDIDATELIST lpDst, DWORD dwBufLen)
|
|
|
|
{
|
|
|
|
DWORD ret, i, len;
|
|
|
|
|
|
|
|
ret = FIELD_OFFSET( CANDIDATELIST, dwOffset[lpSrc->dwCount] );
|
|
|
|
if ( lpDst && dwBufLen > 0 )
|
|
|
|
{
|
|
|
|
*lpDst = *lpSrc;
|
|
|
|
lpDst->dwOffset[0] = ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
for ( i = 0; i < lpSrc->dwCount; i++)
|
|
|
|
{
|
|
|
|
LPBYTE src = (LPBYTE)lpSrc + lpSrc->dwOffset[i];
|
|
|
|
|
|
|
|
if ( lpDst && dwBufLen > 0 )
|
|
|
|
{
|
|
|
|
LPBYTE dest = (LPBYTE)lpDst + lpDst->dwOffset[i];
|
|
|
|
|
|
|
|
len = MultiByteToWideChar(CP_ACP, 0, (LPCSTR)src, -1,
|
|
|
|
(LPWSTR)dest, dwBufLen);
|
|
|
|
|
|
|
|
if ( i + 1 < lpSrc->dwCount )
|
|
|
|
lpDst->dwOffset[i+1] = lpDst->dwOffset[i] + len * sizeof(WCHAR);
|
|
|
|
dwBufLen -= len * sizeof(WCHAR);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
len = MultiByteToWideChar(CP_ACP, 0, (LPCSTR)src, -1, NULL, 0);
|
|
|
|
|
|
|
|
ret += len * sizeof(WCHAR);
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( lpDst )
|
|
|
|
lpDst->dwSize = ret;
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2017-12-08 03:14:21 +00:00
|
|
|
static IMMThreadData *IMM_GetThreadData(HWND hwnd, DWORD thread)
|
2010-03-07 11:27:14 +00:00
|
|
|
{
|
2017-12-08 03:14:21 +00:00
|
|
|
IMMThreadData *data;
|
|
|
|
DWORD process;
|
|
|
|
|
|
|
|
if (hwnd)
|
2010-03-07 11:27:14 +00:00
|
|
|
{
|
2017-12-08 03:14:21 +00:00
|
|
|
if (!(thread = GetWindowThreadProcessId(hwnd, &process))) return NULL;
|
|
|
|
if (process != GetCurrentProcessId()) return NULL;
|
2010-03-07 11:27:14 +00:00
|
|
|
}
|
2017-12-08 03:14:21 +00:00
|
|
|
else if (thread)
|
|
|
|
{
|
|
|
|
HANDLE h = OpenThread(THREAD_QUERY_INFORMATION, FALSE, thread);
|
|
|
|
if (!h) return NULL;
|
|
|
|
process = GetProcessIdOfThread(h);
|
|
|
|
CloseHandle(h);
|
|
|
|
if (process != GetCurrentProcessId()) return NULL;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
thread = GetCurrentThreadId();
|
|
|
|
|
|
|
|
EnterCriticalSection(&threaddata_cs);
|
|
|
|
LIST_FOR_EACH_ENTRY(data, &ImmThreadDataList, IMMThreadData, entry)
|
|
|
|
if (data->threadID == thread) return data;
|
|
|
|
|
|
|
|
data = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*data));
|
|
|
|
data->threadID = thread;
|
|
|
|
list_add_head(&ImmThreadDataList,&data->entry);
|
|
|
|
TRACE("Thread Data Created (%x)\n",thread);
|
2010-03-07 11:27:14 +00:00
|
|
|
return data;
|
|
|
|
}
|
|
|
|
|
2017-12-08 03:14:21 +00:00
|
|
|
static BOOL IMM_IsDefaultContext(HIMC imc)
|
|
|
|
{
|
|
|
|
InputContextData *data = get_imc_data(imc);
|
|
|
|
|
|
|
|
if (!data)
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
return data->threadDefault;
|
|
|
|
}
|
|
|
|
|
2010-03-07 11:27:14 +00:00
|
|
|
static void IMM_FreeThreadData(void)
|
|
|
|
{
|
2017-12-08 03:14:21 +00:00
|
|
|
IMMThreadData *data;
|
|
|
|
|
|
|
|
EnterCriticalSection(&threaddata_cs);
|
|
|
|
LIST_FOR_EACH_ENTRY(data, &ImmThreadDataList, IMMThreadData, entry)
|
2010-03-07 11:27:14 +00:00
|
|
|
{
|
2017-12-08 03:14:21 +00:00
|
|
|
if (data->threadID == GetCurrentThreadId())
|
|
|
|
{
|
|
|
|
list_remove(&data->entry);
|
|
|
|
LeaveCriticalSection(&threaddata_cs);
|
|
|
|
IMM_DestroyContext(data->defaultContext);
|
|
|
|
HeapFree(GetProcessHeap(),0,data);
|
|
|
|
TRACE("Thread Data Destroyed\n");
|
|
|
|
return;
|
|
|
|
}
|
2010-03-07 11:27:14 +00:00
|
|
|
}
|
2017-12-08 03:14:21 +00:00
|
|
|
LeaveCriticalSection(&threaddata_cs);
|
2010-03-07 11:27:14 +00:00
|
|
|
}
|
|
|
|
|
2014-09-28 18:27:58 +00:00
|
|
|
static HMODULE load_graphics_driver(void)
|
2010-03-07 11:27:14 +00:00
|
|
|
{
|
2014-09-28 18:27:58 +00:00
|
|
|
static const WCHAR display_device_guid_propW[] = {
|
|
|
|
'_','_','w','i','n','e','_','d','i','s','p','l','a','y','_',
|
|
|
|
'd','e','v','i','c','e','_','g','u','i','d',0 };
|
|
|
|
static const WCHAR key_pathW[] = {
|
|
|
|
'S','y','s','t','e','m','\\',
|
|
|
|
'C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\',
|
|
|
|
'C','o','n','t','r','o','l','\\',
|
|
|
|
'V','i','d','e','o','\\','{',0};
|
|
|
|
static const WCHAR displayW[] = {'}','\\','0','0','0','0',0};
|
|
|
|
static const WCHAR driverW[] = {'G','r','a','p','h','i','c','s','D','r','i','v','e','r',0};
|
2010-03-07 11:27:14 +00:00
|
|
|
|
2014-09-28 18:27:58 +00:00
|
|
|
HMODULE ret = 0;
|
|
|
|
HKEY hkey;
|
|
|
|
DWORD size;
|
|
|
|
WCHAR path[MAX_PATH];
|
|
|
|
WCHAR key[(sizeof(key_pathW) + sizeof(displayW)) / sizeof(WCHAR) + 40];
|
|
|
|
UINT guid_atom = HandleToULong( GetPropW( GetDesktopWindow(), display_device_guid_propW ));
|
|
|
|
|
|
|
|
if (!guid_atom) return 0;
|
|
|
|
memcpy( key, key_pathW, sizeof(key_pathW) );
|
|
|
|
if (!GlobalGetAtomNameW( guid_atom, key + strlenW(key), 40 )) return 0;
|
|
|
|
strcatW( key, displayW );
|
|
|
|
if (RegOpenKeyW( HKEY_LOCAL_MACHINE, key, &hkey )) return 0;
|
|
|
|
size = sizeof(path);
|
|
|
|
if (!RegQueryValueExW( hkey, driverW, NULL, NULL, (BYTE *)path, &size )) ret = LoadLibraryW( path );
|
|
|
|
RegCloseKey( hkey );
|
|
|
|
TRACE( "%s %p\n", debugstr_w(path), ret );
|
|
|
|
return ret;
|
2010-03-07 11:27:14 +00:00
|
|
|
}
|
2005-12-12 20:59:55 +00:00
|
|
|
|
2008-04-04 13:20:27 +00:00
|
|
|
/* ImmHkl loading and freeing */
|
|
|
|
#define LOAD_FUNCPTR(f) if((ptr->p##f = (LPVOID)GetProcAddress(ptr->hIME, #f)) == NULL){WARN("Can't find function %s in ime\n", #f);}
|
|
|
|
static ImmHkl *IMM_GetImmHkl(HKL hkl)
|
|
|
|
{
|
|
|
|
ImmHkl *ptr;
|
|
|
|
WCHAR filename[MAX_PATH];
|
|
|
|
|
2010-03-07 11:27:14 +00:00
|
|
|
TRACE("Seeking ime for keyboard %p\n",hkl);
|
2008-04-04 13:20:27 +00:00
|
|
|
|
|
|
|
LIST_FOR_EACH_ENTRY(ptr, &ImmHklList, ImmHkl, entry)
|
|
|
|
{
|
|
|
|
if (ptr->hkl == hkl)
|
|
|
|
return ptr;
|
|
|
|
}
|
|
|
|
/* not found... create it */
|
|
|
|
|
|
|
|
ptr = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(ImmHkl));
|
|
|
|
|
|
|
|
ptr->hkl = hkl;
|
|
|
|
if (ImmGetIMEFileNameW(hkl, filename, MAX_PATH)) ptr->hIME = LoadLibraryW(filename);
|
2014-09-28 18:27:58 +00:00
|
|
|
if (!ptr->hIME) ptr->hIME = load_graphics_driver();
|
2008-04-04 13:20:27 +00:00
|
|
|
if (ptr->hIME)
|
|
|
|
{
|
|
|
|
LOAD_FUNCPTR(ImeInquire);
|
2010-03-07 11:27:14 +00:00
|
|
|
if (!ptr->pImeInquire || !ptr->pImeInquire(&ptr->imeInfo, ptr->imeClassName, NULL))
|
2008-04-04 13:20:27 +00:00
|
|
|
{
|
|
|
|
FreeLibrary(ptr->hIME);
|
|
|
|
ptr->hIME = NULL;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2010-03-07 11:27:14 +00:00
|
|
|
LOAD_FUNCPTR(ImeDestroy);
|
|
|
|
LOAD_FUNCPTR(ImeSelect);
|
|
|
|
if (!ptr->pImeSelect || !ptr->pImeDestroy)
|
|
|
|
{
|
|
|
|
FreeLibrary(ptr->hIME);
|
|
|
|
ptr->hIME = NULL;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
LOAD_FUNCPTR(ImeConfigure);
|
|
|
|
LOAD_FUNCPTR(ImeEscape);
|
|
|
|
LOAD_FUNCPTR(ImeSetActiveContext);
|
|
|
|
LOAD_FUNCPTR(ImeToAsciiEx);
|
|
|
|
LOAD_FUNCPTR(NotifyIME);
|
|
|
|
LOAD_FUNCPTR(ImeRegisterWord);
|
|
|
|
LOAD_FUNCPTR(ImeUnregisterWord);
|
|
|
|
LOAD_FUNCPTR(ImeEnumRegisterWord);
|
|
|
|
LOAD_FUNCPTR(ImeSetCompositionString);
|
|
|
|
LOAD_FUNCPTR(ImeConversionList);
|
|
|
|
LOAD_FUNCPTR(ImeProcessKey);
|
|
|
|
LOAD_FUNCPTR(ImeGetRegisterWordStyle);
|
|
|
|
LOAD_FUNCPTR(ImeGetImeMenuItems);
|
|
|
|
/* make sure our classname is WCHAR */
|
|
|
|
if (!is_kbd_ime_unicode(ptr))
|
|
|
|
{
|
|
|
|
WCHAR bufW[17];
|
|
|
|
MultiByteToWideChar(CP_ACP, 0, (LPSTR)ptr->imeClassName,
|
|
|
|
-1, bufW, 17);
|
|
|
|
lstrcpyW(ptr->imeClassName, bufW);
|
|
|
|
}
|
|
|
|
}
|
2008-04-04 13:20:27 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
list_add_head(&ImmHklList,&ptr->entry);
|
|
|
|
|
|
|
|
return ptr;
|
|
|
|
}
|
|
|
|
#undef LOAD_FUNCPTR
|
|
|
|
|
2017-12-08 03:14:21 +00:00
|
|
|
HWND WINAPI __wine_get_ui_window(HKL hkl)
|
|
|
|
{
|
|
|
|
ImmHkl *immHkl = IMM_GetImmHkl(hkl);
|
|
|
|
return immHkl->UIWnd;
|
|
|
|
}
|
|
|
|
|
2008-04-04 13:20:27 +00:00
|
|
|
static void IMM_FreeAllImmHkl(void)
|
|
|
|
{
|
|
|
|
ImmHkl *ptr,*cursor2;
|
|
|
|
|
|
|
|
LIST_FOR_EACH_ENTRY_SAFE(ptr, cursor2, &ImmHklList, ImmHkl, entry)
|
|
|
|
{
|
|
|
|
list_remove(&ptr->entry);
|
|
|
|
if (ptr->hIME)
|
|
|
|
{
|
|
|
|
ptr->pImeDestroy(1);
|
|
|
|
FreeLibrary(ptr->hIME);
|
|
|
|
}
|
2013-02-03 20:58:12 +00:00
|
|
|
if (ptr->UIWnd)
|
|
|
|
DestroyWindow(ptr->UIWnd);
|
2008-04-04 13:20:27 +00:00
|
|
|
HeapFree(GetProcessHeap(),0,ptr);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-12-12 20:59:55 +00:00
|
|
|
BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpReserved)
|
|
|
|
{
|
2006-11-26 21:05:00 +00:00
|
|
|
TRACE("%p, %x, %p\n",hInstDLL,fdwReason,lpReserved);
|
2005-12-12 20:59:55 +00:00
|
|
|
switch (fdwReason)
|
|
|
|
{
|
|
|
|
case DLL_PROCESS_ATTACH:
|
2017-12-08 03:14:21 +00:00
|
|
|
if (!User32InitializeImmEntryTable(IMM_INIT_MAGIC))
|
|
|
|
{
|
2010-03-07 11:27:14 +00:00
|
|
|
return FALSE;
|
2017-12-08 03:14:21 +00:00
|
|
|
}
|
2010-03-07 11:27:14 +00:00
|
|
|
break;
|
|
|
|
case DLL_THREAD_ATTACH:
|
|
|
|
break;
|
|
|
|
case DLL_THREAD_DETACH:
|
|
|
|
IMM_FreeThreadData();
|
2005-12-12 20:59:55 +00:00
|
|
|
break;
|
|
|
|
case DLL_PROCESS_DETACH:
|
2013-12-01 15:57:34 +00:00
|
|
|
if (lpReserved) break;
|
2010-03-07 11:27:14 +00:00
|
|
|
IMM_FreeThreadData();
|
2008-04-04 13:20:27 +00:00
|
|
|
IMM_FreeAllImmHkl();
|
2005-12-12 20:59:55 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* for posting messages as the IME */
|
2008-04-04 13:20:27 +00:00
|
|
|
static void ImmInternalPostIMEMessage(InputContextData *data, UINT msg, WPARAM wParam, LPARAM lParam)
|
2005-12-12 20:59:55 +00:00
|
|
|
{
|
|
|
|
HWND target = GetFocus();
|
|
|
|
if (!target)
|
2008-04-04 13:20:27 +00:00
|
|
|
PostMessageW(data->IMC.hWnd,msg,wParam,lParam);
|
2007-09-14 08:03:04 +00:00
|
|
|
else
|
2005-12-12 20:59:55 +00:00
|
|
|
PostMessageW(target, msg, wParam, lParam);
|
|
|
|
}
|
|
|
|
|
2017-12-08 03:14:21 +00:00
|
|
|
/* for sending messages as the IME */
|
|
|
|
static void ImmInternalSendIMEMessage(InputContextData *data, UINT msg, WPARAM wParam, LPARAM lParam)
|
|
|
|
{
|
|
|
|
HWND target = GetFocus();
|
|
|
|
if (!target)
|
|
|
|
SendMessageW(data->IMC.hWnd,msg,wParam,lParam);
|
|
|
|
else
|
|
|
|
SendMessageW(target, msg, wParam, lParam);
|
|
|
|
}
|
|
|
|
|
2008-04-04 13:20:27 +00:00
|
|
|
static LRESULT ImmInternalSendIMENotify(InputContextData *data, WPARAM notify, LPARAM lParam)
|
2007-03-14 14:34:47 +00:00
|
|
|
{
|
|
|
|
HWND target;
|
|
|
|
|
2008-04-04 13:20:27 +00:00
|
|
|
target = data->IMC.hWnd;
|
2007-03-14 14:34:47 +00:00
|
|
|
if (!target) target = GetFocus();
|
|
|
|
|
|
|
|
if (target)
|
|
|
|
return SendMessageW(target, WM_IME_NOTIFY, notify, lParam);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
2005-12-12 20:59:55 +00:00
|
|
|
|
2008-04-04 13:20:27 +00:00
|
|
|
static HIMCC ImmCreateBlankCompStr(void)
|
|
|
|
{
|
|
|
|
HIMCC rc;
|
|
|
|
LPCOMPOSITIONSTRING ptr;
|
|
|
|
rc = ImmCreateIMCC(sizeof(COMPOSITIONSTRING));
|
2010-03-07 11:27:14 +00:00
|
|
|
ptr = ImmLockIMCC(rc);
|
2008-04-04 13:20:27 +00:00
|
|
|
memset(ptr,0,sizeof(COMPOSITIONSTRING));
|
|
|
|
ptr->dwSize = sizeof(COMPOSITIONSTRING);
|
|
|
|
ImmUnlockIMCC(rc);
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
2014-09-28 18:27:58 +00:00
|
|
|
static InputContextData* get_imc_data(HIMC hIMC)
|
|
|
|
{
|
|
|
|
InputContextData *data = hIMC;
|
|
|
|
|
|
|
|
if (hIMC == NULL)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
if(IsBadReadPtr(data, sizeof(InputContextData)) || data->magic != WINE_IMC_VALID_MAGIC)
|
|
|
|
{
|
|
|
|
SetLastError(ERROR_INVALID_HANDLE);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
return data;
|
|
|
|
}
|
|
|
|
|
2017-12-08 03:14:21 +00:00
|
|
|
static HIMC get_default_context( HWND hwnd )
|
|
|
|
{
|
|
|
|
HIMC ret;
|
|
|
|
IMMThreadData* thread_data = IMM_GetThreadData( hwnd, 0 );
|
|
|
|
|
|
|
|
if (!thread_data) return 0;
|
|
|
|
|
|
|
|
if (thread_data->defaultContext)
|
|
|
|
{
|
|
|
|
ret = thread_data->defaultContext;
|
|
|
|
LeaveCriticalSection(&threaddata_cs);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* can't create a default context in another thread */
|
|
|
|
if (thread_data->threadID != GetCurrentThreadId())
|
|
|
|
{
|
|
|
|
LeaveCriticalSection(&threaddata_cs);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
LeaveCriticalSection(&threaddata_cs);
|
|
|
|
|
|
|
|
ret = ImmCreateContext();
|
|
|
|
if (!ret) return 0;
|
|
|
|
((InputContextData*)ret)->threadDefault = TRUE;
|
|
|
|
|
|
|
|
/* thread_data is in the current thread so we can assume it's still valid */
|
|
|
|
EnterCriticalSection(&threaddata_cs);
|
|
|
|
|
|
|
|
if (thread_data->defaultContext) /* someone beat us */
|
|
|
|
{
|
|
|
|
IMM_DestroyContext( ret );
|
|
|
|
ret = thread_data->defaultContext;
|
|
|
|
}
|
|
|
|
else thread_data->defaultContext = ret;
|
|
|
|
|
|
|
|
LeaveCriticalSection(&threaddata_cs);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static BOOL IMM_IsCrossThreadAccess(HWND hWnd, HIMC hIMC)
|
|
|
|
{
|
|
|
|
InputContextData *data;
|
|
|
|
|
|
|
|
if (hWnd)
|
|
|
|
{
|
|
|
|
DWORD thread = GetWindowThreadProcessId(hWnd, NULL);
|
|
|
|
if (thread != GetCurrentThreadId()) return TRUE;
|
|
|
|
}
|
|
|
|
data = get_imc_data(hIMC);
|
|
|
|
if (data && data->threadID != GetCurrentThreadId())
|
|
|
|
return TRUE;
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2005-12-12 20:59:55 +00:00
|
|
|
/***********************************************************************
|
|
|
|
* ImmAssociateContext (IMM32.@)
|
|
|
|
*/
|
|
|
|
HIMC WINAPI ImmAssociateContext(HWND hWnd, HIMC hIMC)
|
|
|
|
{
|
2008-04-04 13:20:27 +00:00
|
|
|
HIMC old = NULL;
|
2014-09-28 18:27:58 +00:00
|
|
|
InputContextData *data = get_imc_data(hIMC);
|
2005-12-12 20:59:55 +00:00
|
|
|
|
2008-04-04 13:20:27 +00:00
|
|
|
TRACE("(%p, %p):\n", hWnd, hIMC);
|
2005-12-12 20:59:55 +00:00
|
|
|
|
2014-09-28 18:27:58 +00:00
|
|
|
if(hIMC && !data)
|
|
|
|
return NULL;
|
|
|
|
|
2005-12-12 20:59:55 +00:00
|
|
|
/*
|
|
|
|
* If already associated just return
|
|
|
|
*/
|
2008-04-04 13:20:27 +00:00
|
|
|
if (hIMC && data->IMC.hWnd == hWnd)
|
2006-07-06 11:22:04 +00:00
|
|
|
return hIMC;
|
2005-12-12 20:59:55 +00:00
|
|
|
|
2017-12-08 03:14:21 +00:00
|
|
|
if (hIMC && IMM_IsCrossThreadAccess(hWnd, hIMC))
|
|
|
|
return NULL;
|
|
|
|
|
2008-04-04 13:20:27 +00:00
|
|
|
if (hWnd)
|
|
|
|
{
|
2017-12-08 03:14:21 +00:00
|
|
|
HIMC defaultContext = get_default_context( hWnd );
|
2010-03-07 11:27:14 +00:00
|
|
|
old = RemovePropW(hWnd,szwWineIMCProperty);
|
2008-04-04 13:20:27 +00:00
|
|
|
|
|
|
|
if (old == NULL)
|
2017-12-08 03:14:21 +00:00
|
|
|
old = defaultContext;
|
2008-04-04 13:20:27 +00:00
|
|
|
else if (old == (HIMC)-1)
|
|
|
|
old = NULL;
|
|
|
|
|
2017-12-08 03:14:21 +00:00
|
|
|
if (hIMC != defaultContext)
|
2008-04-04 13:20:27 +00:00
|
|
|
{
|
|
|
|
if (hIMC == NULL) /* Meaning disable imm for that window*/
|
|
|
|
SetPropW(hWnd,szwWineIMCProperty,(HANDLE)-1);
|
|
|
|
else
|
2010-03-07 11:27:14 +00:00
|
|
|
SetPropW(hWnd,szwWineIMCProperty,hIMC);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (old)
|
|
|
|
{
|
|
|
|
InputContextData *old_data = old;
|
|
|
|
if (old_data->IMC.hWnd == hWnd)
|
|
|
|
old_data->IMC.hWnd = NULL;
|
2008-04-04 13:20:27 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!hIMC)
|
|
|
|
return old;
|
|
|
|
|
2017-12-08 03:14:21 +00:00
|
|
|
SendMessageW(data->IMC.hWnd, WM_IME_SETCONTEXT, FALSE, ISC_SHOWUIALL);
|
2007-09-14 08:03:04 +00:00
|
|
|
data->IMC.hWnd = hWnd;
|
2017-12-08 03:14:21 +00:00
|
|
|
SendMessageW(data->IMC.hWnd, WM_IME_SETCONTEXT, TRUE, ISC_SHOWUIALL);
|
2005-12-12 20:59:55 +00:00
|
|
|
|
2008-04-04 13:20:27 +00:00
|
|
|
return old;
|
2005-12-12 20:59:55 +00:00
|
|
|
}
|
|
|
|
|
2010-03-07 11:27:14 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Helper function for ImmAssociateContextEx
|
|
|
|
*/
|
|
|
|
static BOOL CALLBACK _ImmAssociateContextExEnumProc(HWND hwnd, LPARAM lParam)
|
|
|
|
{
|
|
|
|
HIMC hImc = (HIMC)lParam;
|
|
|
|
ImmAssociateContext(hwnd,hImc);
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2005-12-12 20:59:55 +00:00
|
|
|
/***********************************************************************
|
|
|
|
* ImmAssociateContextEx (IMM32.@)
|
|
|
|
*/
|
|
|
|
BOOL WINAPI ImmAssociateContextEx(HWND hWnd, HIMC hIMC, DWORD dwFlags)
|
|
|
|
{
|
Sync avifil, credui, crypt32, cryptdlg, cryptui, dnsapi, gdiplus, hhctrl, hnetcfg, iccvid, imaadp32, imm32, jscript, localspl, localui, mapi32, mciavi32, mcicda, mciqtz32, mciseq, mciwave, mshtml, msrle32, msvfw32, msvidc32, msxml3, oleacc, oleaut32 to Wine 1.2rc5 (Samuel Serapion, small changes by me)
Remove Esperanto and Walon languages from comctl32, comdlg32, mpr, msi, shlwapi, wininet
svn path=/trunk/; revision=47920
2010-07-01 11:09:47 +00:00
|
|
|
TRACE("(%p, %p, 0x%x):\n", hWnd, hIMC, dwFlags);
|
2010-03-07 11:27:14 +00:00
|
|
|
|
2017-12-08 03:14:21 +00:00
|
|
|
if (!hWnd)
|
|
|
|
return FALSE;
|
Sync avifil, credui, crypt32, cryptdlg, cryptui, dnsapi, gdiplus, hhctrl, hnetcfg, iccvid, imaadp32, imm32, jscript, localspl, localui, mapi32, mciavi32, mcicda, mciqtz32, mciseq, mciwave, mshtml, msrle32, msvfw32, msvidc32, msxml3, oleacc, oleaut32 to Wine 1.2rc5 (Samuel Serapion, small changes by me)
Remove Esperanto and Walon languages from comctl32, comdlg32, mpr, msi, shlwapi, wininet
svn path=/trunk/; revision=47920
2010-07-01 11:09:47 +00:00
|
|
|
|
|
|
|
switch (dwFlags)
|
2010-03-07 11:27:14 +00:00
|
|
|
{
|
Sync avifil, credui, crypt32, cryptdlg, cryptui, dnsapi, gdiplus, hhctrl, hnetcfg, iccvid, imaadp32, imm32, jscript, localspl, localui, mapi32, mciavi32, mcicda, mciqtz32, mciseq, mciwave, mshtml, msrle32, msvfw32, msvidc32, msxml3, oleacc, oleaut32 to Wine 1.2rc5 (Samuel Serapion, small changes by me)
Remove Esperanto and Walon languages from comctl32, comdlg32, mpr, msi, shlwapi, wininet
svn path=/trunk/; revision=47920
2010-07-01 11:09:47 +00:00
|
|
|
case 0:
|
|
|
|
ImmAssociateContext(hWnd,hIMC);
|
|
|
|
return TRUE;
|
|
|
|
case IACE_DEFAULT:
|
2017-12-08 03:14:21 +00:00
|
|
|
{
|
|
|
|
HIMC defaultContext = get_default_context( hWnd );
|
|
|
|
if (!defaultContext) return FALSE;
|
|
|
|
ImmAssociateContext(hWnd,defaultContext);
|
2010-03-07 11:27:14 +00:00
|
|
|
return TRUE;
|
2017-12-08 03:14:21 +00:00
|
|
|
}
|
Sync avifil, credui, crypt32, cryptdlg, cryptui, dnsapi, gdiplus, hhctrl, hnetcfg, iccvid, imaadp32, imm32, jscript, localspl, localui, mapi32, mciavi32, mcicda, mciqtz32, mciseq, mciwave, mshtml, msrle32, msvfw32, msvidc32, msxml3, oleacc, oleaut32 to Wine 1.2rc5 (Samuel Serapion, small changes by me)
Remove Esperanto and Walon languages from comctl32, comdlg32, mpr, msi, shlwapi, wininet
svn path=/trunk/; revision=47920
2010-07-01 11:09:47 +00:00
|
|
|
case IACE_IGNORENOCONTEXT:
|
2010-03-07 11:27:14 +00:00
|
|
|
if (GetPropW(hWnd,szwWineIMCProperty))
|
|
|
|
ImmAssociateContext(hWnd,hIMC);
|
|
|
|
return TRUE;
|
Sync avifil, credui, crypt32, cryptdlg, cryptui, dnsapi, gdiplus, hhctrl, hnetcfg, iccvid, imaadp32, imm32, jscript, localspl, localui, mapi32, mciavi32, mcicda, mciqtz32, mciseq, mciwave, mshtml, msrle32, msvfw32, msvidc32, msxml3, oleacc, oleaut32 to Wine 1.2rc5 (Samuel Serapion, small changes by me)
Remove Esperanto and Walon languages from comctl32, comdlg32, mpr, msi, shlwapi, wininet
svn path=/trunk/; revision=47920
2010-07-01 11:09:47 +00:00
|
|
|
case IACE_CHILDREN:
|
2010-03-07 11:27:14 +00:00
|
|
|
EnumChildWindows(hWnd,_ImmAssociateContextExEnumProc,(LPARAM)hIMC);
|
|
|
|
return TRUE;
|
Sync avifil, credui, crypt32, cryptdlg, cryptui, dnsapi, gdiplus, hhctrl, hnetcfg, iccvid, imaadp32, imm32, jscript, localspl, localui, mapi32, mciavi32, mcicda, mciqtz32, mciseq, mciwave, mshtml, msrle32, msvfw32, msvidc32, msxml3, oleacc, oleaut32 to Wine 1.2rc5 (Samuel Serapion, small changes by me)
Remove Esperanto and Walon languages from comctl32, comdlg32, mpr, msi, shlwapi, wininet
svn path=/trunk/; revision=47920
2010-07-01 11:09:47 +00:00
|
|
|
default:
|
|
|
|
FIXME("Unknown dwFlags 0x%x\n",dwFlags);
|
2010-03-07 11:27:14 +00:00
|
|
|
return FALSE;
|
|
|
|
}
|
2005-12-12 20:59:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ImmConfigureIMEA (IMM32.@)
|
|
|
|
*/
|
|
|
|
BOOL WINAPI ImmConfigureIMEA(
|
|
|
|
HKL hKL, HWND hWnd, DWORD dwMode, LPVOID lpData)
|
|
|
|
{
|
2010-03-07 11:27:14 +00:00
|
|
|
ImmHkl *immHkl = IMM_GetImmHkl(hKL);
|
|
|
|
|
|
|
|
TRACE("(%p, %p, %d, %p):\n", hKL, hWnd, dwMode, lpData);
|
|
|
|
|
|
|
|
if (dwMode == IME_CONFIG_REGISTERWORD && !lpData)
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
if (immHkl->hIME && immHkl->pImeConfigure)
|
|
|
|
{
|
|
|
|
if (dwMode != IME_CONFIG_REGISTERWORD || !is_kbd_ime_unicode(immHkl))
|
|
|
|
return immHkl->pImeConfigure(hKL,hWnd,dwMode,lpData);
|
|
|
|
else
|
|
|
|
{
|
|
|
|
REGISTERWORDW rww;
|
|
|
|
REGISTERWORDA *rwa = lpData;
|
|
|
|
BOOL rc;
|
|
|
|
|
|
|
|
rww.lpReading = strdupAtoW(rwa->lpReading);
|
|
|
|
rww.lpWord = strdupAtoW(rwa->lpWord);
|
|
|
|
rc = immHkl->pImeConfigure(hKL,hWnd,dwMode,&rww);
|
|
|
|
HeapFree(GetProcessHeap(),0,rww.lpReading);
|
|
|
|
HeapFree(GetProcessHeap(),0,rww.lpWord);
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
return FALSE;
|
2005-12-12 20:59:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ImmConfigureIMEW (IMM32.@)
|
|
|
|
*/
|
|
|
|
BOOL WINAPI ImmConfigureIMEW(
|
|
|
|
HKL hKL, HWND hWnd, DWORD dwMode, LPVOID lpData)
|
|
|
|
{
|
2010-03-07 11:27:14 +00:00
|
|
|
ImmHkl *immHkl = IMM_GetImmHkl(hKL);
|
|
|
|
|
|
|
|
TRACE("(%p, %p, %d, %p):\n", hKL, hWnd, dwMode, lpData);
|
|
|
|
|
|
|
|
if (dwMode == IME_CONFIG_REGISTERWORD && !lpData)
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
if (immHkl->hIME && immHkl->pImeConfigure)
|
|
|
|
{
|
|
|
|
if (dwMode != IME_CONFIG_REGISTERWORD || is_kbd_ime_unicode(immHkl))
|
|
|
|
return immHkl->pImeConfigure(hKL,hWnd,dwMode,lpData);
|
|
|
|
else
|
|
|
|
{
|
|
|
|
REGISTERWORDW *rww = lpData;
|
|
|
|
REGISTERWORDA rwa;
|
|
|
|
BOOL rc;
|
|
|
|
|
|
|
|
rwa.lpReading = strdupWtoA(rww->lpReading);
|
|
|
|
rwa.lpWord = strdupWtoA(rww->lpWord);
|
|
|
|
rc = immHkl->pImeConfigure(hKL,hWnd,dwMode,&rwa);
|
|
|
|
HeapFree(GetProcessHeap(),0,rwa.lpReading);
|
|
|
|
HeapFree(GetProcessHeap(),0,rwa.lpWord);
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
return FALSE;
|
2005-12-12 20:59:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ImmCreateContext (IMM32.@)
|
|
|
|
*/
|
|
|
|
HIMC WINAPI ImmCreateContext(void)
|
|
|
|
{
|
|
|
|
InputContextData *new_context;
|
2010-03-07 11:27:14 +00:00
|
|
|
LPGUIDELINE gl;
|
|
|
|
LPCANDIDATEINFO ci;
|
2014-09-28 18:27:58 +00:00
|
|
|
int i;
|
2005-12-12 20:59:55 +00:00
|
|
|
|
2007-09-14 08:03:04 +00:00
|
|
|
new_context = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(InputContextData));
|
2005-12-12 20:59:55 +00:00
|
|
|
|
2008-04-04 13:20:27 +00:00
|
|
|
/* Load the IME */
|
|
|
|
new_context->immKbd = IMM_GetImmHkl(GetKeyboardLayout(0));
|
|
|
|
|
|
|
|
if (!new_context->immKbd->hIME)
|
2010-03-07 11:27:14 +00:00
|
|
|
{
|
2008-04-04 13:20:27 +00:00
|
|
|
TRACE("IME dll could not be loaded\n");
|
2010-03-07 11:27:14 +00:00
|
|
|
HeapFree(GetProcessHeap(),0,new_context);
|
|
|
|
return 0;
|
|
|
|
}
|
2008-04-04 13:20:27 +00:00
|
|
|
|
2010-03-07 11:27:14 +00:00
|
|
|
/* the HIMCCs are never NULL */
|
2008-04-04 13:20:27 +00:00
|
|
|
new_context->IMC.hCompStr = ImmCreateBlankCompStr();
|
2010-03-07 11:27:14 +00:00
|
|
|
new_context->IMC.hMsgBuf = ImmCreateIMCC(0);
|
|
|
|
new_context->IMC.hCandInfo = ImmCreateIMCC(sizeof(CANDIDATEINFO));
|
|
|
|
ci = ImmLockIMCC(new_context->IMC.hCandInfo);
|
|
|
|
memset(ci,0,sizeof(CANDIDATEINFO));
|
|
|
|
ci->dwSize = sizeof(CANDIDATEINFO);
|
|
|
|
ImmUnlockIMCC(new_context->IMC.hCandInfo);
|
|
|
|
new_context->IMC.hGuideLine = ImmCreateIMCC(sizeof(GUIDELINE));
|
|
|
|
gl = ImmLockIMCC(new_context->IMC.hGuideLine);
|
|
|
|
memset(gl,0,sizeof(GUIDELINE));
|
|
|
|
gl->dwSize = sizeof(GUIDELINE);
|
|
|
|
ImmUnlockIMCC(new_context->IMC.hGuideLine);
|
2008-04-04 13:20:27 +00:00
|
|
|
|
2014-09-28 18:27:58 +00:00
|
|
|
for (i = 0; i < sizeof(new_context->IMC.cfCandForm) / sizeof(CANDIDATEFORM); i++)
|
|
|
|
new_context->IMC.cfCandForm[i].dwIndex = ~0u;
|
|
|
|
|
2008-04-04 13:20:27 +00:00
|
|
|
/* Initialize the IME Private */
|
|
|
|
new_context->IMC.hPrivate = ImmCreateIMCC(new_context->immKbd->imeInfo.dwPrivateDataSize);
|
|
|
|
|
2014-09-28 18:27:58 +00:00
|
|
|
new_context->IMC.fdwConversion = new_context->immKbd->imeInfo.fdwConversionCaps;
|
|
|
|
new_context->IMC.fdwSentence = new_context->immKbd->imeInfo.fdwSentenceCaps;
|
|
|
|
|
2010-03-07 11:27:14 +00:00
|
|
|
if (!new_context->immKbd->pImeSelect(new_context, TRUE))
|
2008-04-04 13:20:27 +00:00
|
|
|
{
|
|
|
|
TRACE("Selection of IME failed\n");
|
2010-03-07 11:27:14 +00:00
|
|
|
IMM_DestroyContext(new_context);
|
2008-04-04 13:20:27 +00:00
|
|
|
return 0;
|
|
|
|
}
|
2017-12-08 03:14:21 +00:00
|
|
|
new_context->threadID = GetCurrentThreadId();
|
|
|
|
SendMessageW(GetFocus(), WM_IME_SELECT, TRUE, (LPARAM)new_context->immKbd);
|
2008-04-04 13:20:27 +00:00
|
|
|
|
|
|
|
new_context->immKbd->uSelected++;
|
2010-03-07 11:27:14 +00:00
|
|
|
TRACE("Created context %p\n",new_context);
|
2008-04-04 13:20:27 +00:00
|
|
|
|
2014-09-28 18:27:58 +00:00
|
|
|
new_context->magic = WINE_IMC_VALID_MAGIC;
|
2010-03-07 11:27:14 +00:00
|
|
|
return new_context;
|
2005-12-12 20:59:55 +00:00
|
|
|
}
|
|
|
|
|
2010-03-07 11:27:14 +00:00
|
|
|
static BOOL IMM_DestroyContext(HIMC hIMC)
|
2005-12-12 20:59:55 +00:00
|
|
|
{
|
2014-09-28 18:27:58 +00:00
|
|
|
InputContextData *data = get_imc_data(hIMC);
|
2005-12-12 20:59:55 +00:00
|
|
|
|
|
|
|
TRACE("Destroying %p\n",hIMC);
|
|
|
|
|
2014-09-28 18:27:58 +00:00
|
|
|
if (!data)
|
|
|
|
return FALSE;
|
2010-03-07 11:27:14 +00:00
|
|
|
|
2014-09-28 18:27:58 +00:00
|
|
|
data->immKbd->uSelected --;
|
|
|
|
data->immKbd->pImeSelect(hIMC, FALSE);
|
2017-12-08 03:14:21 +00:00
|
|
|
SendMessageW(data->IMC.hWnd, WM_IME_SELECT, FALSE, (LPARAM)data->immKbd);
|
2014-09-28 18:27:58 +00:00
|
|
|
|
|
|
|
ImmDestroyIMCC(data->IMC.hCompStr);
|
|
|
|
ImmDestroyIMCC(data->IMC.hCandInfo);
|
|
|
|
ImmDestroyIMCC(data->IMC.hGuideLine);
|
|
|
|
ImmDestroyIMCC(data->IMC.hPrivate);
|
|
|
|
ImmDestroyIMCC(data->IMC.hMsgBuf);
|
|
|
|
|
|
|
|
data->magic = 0;
|
|
|
|
HeapFree(GetProcessHeap(),0,data);
|
2005-12-12 20:59:55 +00:00
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2010-03-07 11:27:14 +00:00
|
|
|
/***********************************************************************
|
|
|
|
* ImmDestroyContext (IMM32.@)
|
|
|
|
*/
|
|
|
|
BOOL WINAPI ImmDestroyContext(HIMC hIMC)
|
|
|
|
{
|
2017-12-08 03:14:21 +00:00
|
|
|
if (!IMM_IsDefaultContext(hIMC) && !IMM_IsCrossThreadAccess(NULL, hIMC))
|
2010-03-07 11:27:14 +00:00
|
|
|
return IMM_DestroyContext(hIMC);
|
|
|
|
else
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2005-12-12 20:59:55 +00:00
|
|
|
/***********************************************************************
|
|
|
|
* ImmDisableIME (IMM32.@)
|
|
|
|
*/
|
|
|
|
BOOL WINAPI ImmDisableIME(DWORD idThread)
|
|
|
|
{
|
2017-12-08 03:14:21 +00:00
|
|
|
if (idThread == (DWORD)-1)
|
|
|
|
disable_ime = TRUE;
|
|
|
|
else {
|
|
|
|
IMMThreadData *thread_data = IMM_GetThreadData(NULL, idThread);
|
|
|
|
if (!thread_data) return FALSE;
|
|
|
|
thread_data->disableIME = TRUE;
|
|
|
|
LeaveCriticalSection(&threaddata_cs);
|
|
|
|
}
|
2005-12-12 20:59:55 +00:00
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ImmEnumRegisterWordA (IMM32.@)
|
|
|
|
*/
|
|
|
|
UINT WINAPI ImmEnumRegisterWordA(
|
|
|
|
HKL hKL, REGISTERWORDENUMPROCA lpfnEnumProc,
|
|
|
|
LPCSTR lpszReading, DWORD dwStyle,
|
|
|
|
LPCSTR lpszRegister, LPVOID lpData)
|
|
|
|
{
|
2010-03-07 11:27:14 +00:00
|
|
|
ImmHkl *immHkl = IMM_GetImmHkl(hKL);
|
|
|
|
TRACE("(%p, %p, %s, %d, %s, %p):\n", hKL, lpfnEnumProc,
|
|
|
|
debugstr_a(lpszReading), dwStyle, debugstr_a(lpszRegister), lpData);
|
|
|
|
if (immHkl->hIME && immHkl->pImeEnumRegisterWord)
|
|
|
|
{
|
|
|
|
if (!is_kbd_ime_unicode(immHkl))
|
|
|
|
return immHkl->pImeEnumRegisterWord((REGISTERWORDENUMPROCW)lpfnEnumProc,
|
|
|
|
(LPCWSTR)lpszReading, dwStyle, (LPCWSTR)lpszRegister, lpData);
|
|
|
|
else
|
|
|
|
{
|
|
|
|
LPWSTR lpszwReading = strdupAtoW(lpszReading);
|
|
|
|
LPWSTR lpszwRegister = strdupAtoW(lpszRegister);
|
|
|
|
BOOL rc;
|
|
|
|
|
|
|
|
rc = immHkl->pImeEnumRegisterWord((REGISTERWORDENUMPROCW)lpfnEnumProc,
|
|
|
|
lpszwReading, dwStyle, lpszwRegister,
|
|
|
|
lpData);
|
|
|
|
|
|
|
|
HeapFree(GetProcessHeap(),0,lpszwReading);
|
|
|
|
HeapFree(GetProcessHeap(),0,lpszwRegister);
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
return 0;
|
2005-12-12 20:59:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ImmEnumRegisterWordW (IMM32.@)
|
|
|
|
*/
|
|
|
|
UINT WINAPI ImmEnumRegisterWordW(
|
|
|
|
HKL hKL, REGISTERWORDENUMPROCW lpfnEnumProc,
|
|
|
|
LPCWSTR lpszReading, DWORD dwStyle,
|
|
|
|
LPCWSTR lpszRegister, LPVOID lpData)
|
|
|
|
{
|
2010-03-07 11:27:14 +00:00
|
|
|
ImmHkl *immHkl = IMM_GetImmHkl(hKL);
|
|
|
|
TRACE("(%p, %p, %s, %d, %s, %p):\n", hKL, lpfnEnumProc,
|
|
|
|
debugstr_w(lpszReading), dwStyle, debugstr_w(lpszRegister), lpData);
|
|
|
|
if (immHkl->hIME && immHkl->pImeEnumRegisterWord)
|
|
|
|
{
|
|
|
|
if (is_kbd_ime_unicode(immHkl))
|
|
|
|
return immHkl->pImeEnumRegisterWord(lpfnEnumProc, lpszReading, dwStyle,
|
|
|
|
lpszRegister, lpData);
|
|
|
|
else
|
|
|
|
{
|
|
|
|
LPSTR lpszaReading = strdupWtoA(lpszReading);
|
|
|
|
LPSTR lpszaRegister = strdupWtoA(lpszRegister);
|
|
|
|
BOOL rc;
|
|
|
|
|
|
|
|
rc = immHkl->pImeEnumRegisterWord(lpfnEnumProc, (LPCWSTR)lpszaReading,
|
|
|
|
dwStyle, (LPCWSTR)lpszaRegister, lpData);
|
|
|
|
|
|
|
|
HeapFree(GetProcessHeap(),0,lpszaReading);
|
|
|
|
HeapFree(GetProcessHeap(),0,lpszaRegister);
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline BOOL EscapeRequiresWA(UINT uEscape)
|
|
|
|
{
|
|
|
|
if (uEscape == IME_ESC_GET_EUDC_DICTIONARY ||
|
|
|
|
uEscape == IME_ESC_SET_EUDC_DICTIONARY ||
|
|
|
|
uEscape == IME_ESC_IME_NAME ||
|
|
|
|
uEscape == IME_ESC_GETHELPFILENAME)
|
|
|
|
return TRUE;
|
|
|
|
return FALSE;
|
2005-12-12 20:59:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ImmEscapeA (IMM32.@)
|
|
|
|
*/
|
|
|
|
LRESULT WINAPI ImmEscapeA(
|
|
|
|
HKL hKL, HIMC hIMC,
|
|
|
|
UINT uEscape, LPVOID lpData)
|
|
|
|
{
|
2010-03-07 11:27:14 +00:00
|
|
|
ImmHkl *immHkl = IMM_GetImmHkl(hKL);
|
|
|
|
TRACE("(%p, %p, %d, %p):\n", hKL, hIMC, uEscape, lpData);
|
|
|
|
|
|
|
|
if (immHkl->hIME && immHkl->pImeEscape)
|
|
|
|
{
|
|
|
|
if (!EscapeRequiresWA(uEscape) || !is_kbd_ime_unicode(immHkl))
|
|
|
|
return immHkl->pImeEscape(hIMC,uEscape,lpData);
|
|
|
|
else
|
|
|
|
{
|
|
|
|
WCHAR buffer[81]; /* largest required buffer should be 80 */
|
|
|
|
LRESULT rc;
|
|
|
|
if (uEscape == IME_ESC_SET_EUDC_DICTIONARY)
|
|
|
|
{
|
|
|
|
MultiByteToWideChar(CP_ACP,0,lpData,-1,buffer,81);
|
|
|
|
rc = immHkl->pImeEscape(hIMC,uEscape,buffer);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
rc = immHkl->pImeEscape(hIMC,uEscape,buffer);
|
|
|
|
WideCharToMultiByte(CP_ACP,0,buffer,-1,lpData,80, NULL, NULL);
|
|
|
|
}
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
return 0;
|
2005-12-12 20:59:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ImmEscapeW (IMM32.@)
|
|
|
|
*/
|
|
|
|
LRESULT WINAPI ImmEscapeW(
|
|
|
|
HKL hKL, HIMC hIMC,
|
|
|
|
UINT uEscape, LPVOID lpData)
|
|
|
|
{
|
2010-03-07 11:27:14 +00:00
|
|
|
ImmHkl *immHkl = IMM_GetImmHkl(hKL);
|
|
|
|
TRACE("(%p, %p, %d, %p):\n", hKL, hIMC, uEscape, lpData);
|
|
|
|
|
|
|
|
if (immHkl->hIME && immHkl->pImeEscape)
|
|
|
|
{
|
|
|
|
if (!EscapeRequiresWA(uEscape) || is_kbd_ime_unicode(immHkl))
|
|
|
|
return immHkl->pImeEscape(hIMC,uEscape,lpData);
|
|
|
|
else
|
|
|
|
{
|
|
|
|
CHAR buffer[81]; /* largest required buffer should be 80 */
|
|
|
|
LRESULT rc;
|
|
|
|
if (uEscape == IME_ESC_SET_EUDC_DICTIONARY)
|
|
|
|
{
|
|
|
|
WideCharToMultiByte(CP_ACP,0,lpData,-1,buffer,81, NULL, NULL);
|
|
|
|
rc = immHkl->pImeEscape(hIMC,uEscape,buffer);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
rc = immHkl->pImeEscape(hIMC,uEscape,buffer);
|
|
|
|
MultiByteToWideChar(CP_ACP,0,buffer,-1,lpData,80);
|
|
|
|
}
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
return 0;
|
2005-12-12 20:59:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ImmGetCandidateListA (IMM32.@)
|
|
|
|
*/
|
|
|
|
DWORD WINAPI ImmGetCandidateListA(
|
2010-03-07 11:27:14 +00:00
|
|
|
HIMC hIMC, DWORD dwIndex,
|
2005-12-12 20:59:55 +00:00
|
|
|
LPCANDIDATELIST lpCandList, DWORD dwBufLen)
|
|
|
|
{
|
2014-09-28 18:27:58 +00:00
|
|
|
InputContextData *data = get_imc_data(hIMC);
|
2010-03-07 11:27:14 +00:00
|
|
|
LPCANDIDATEINFO candinfo;
|
|
|
|
LPCANDIDATELIST candlist;
|
|
|
|
DWORD ret = 0;
|
|
|
|
|
|
|
|
TRACE("%p, %d, %p, %d\n", hIMC, dwIndex, lpCandList, dwBufLen);
|
|
|
|
|
|
|
|
if (!data || !data->IMC.hCandInfo)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
candinfo = ImmLockIMCC(data->IMC.hCandInfo);
|
|
|
|
if ( dwIndex >= candinfo->dwCount ||
|
|
|
|
dwIndex >= (sizeof(candinfo->dwOffset) / sizeof(DWORD)) )
|
|
|
|
goto done;
|
|
|
|
|
|
|
|
candlist = (LPCANDIDATELIST)((LPBYTE)candinfo + candinfo->dwOffset[dwIndex]);
|
|
|
|
if ( !candlist->dwSize || !candlist->dwCount )
|
|
|
|
goto done;
|
|
|
|
|
|
|
|
if ( !is_himc_ime_unicode(data) )
|
|
|
|
{
|
|
|
|
ret = candlist->dwSize;
|
|
|
|
if ( lpCandList && dwBufLen >= ret )
|
|
|
|
memcpy(lpCandList, candlist, ret);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
ret = convert_candidatelist_WtoA( candlist, lpCandList, dwBufLen);
|
|
|
|
|
|
|
|
done:
|
|
|
|
ImmUnlockIMCC(data->IMC.hCandInfo);
|
|
|
|
return ret;
|
2005-12-12 20:59:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ImmGetCandidateListCountA (IMM32.@)
|
|
|
|
*/
|
|
|
|
DWORD WINAPI ImmGetCandidateListCountA(
|
|
|
|
HIMC hIMC, LPDWORD lpdwListCount)
|
|
|
|
{
|
2014-09-28 18:27:58 +00:00
|
|
|
InputContextData *data = get_imc_data(hIMC);
|
2010-03-07 11:27:14 +00:00
|
|
|
LPCANDIDATEINFO candinfo;
|
|
|
|
DWORD ret, count;
|
|
|
|
|
|
|
|
TRACE("%p, %p\n", hIMC, lpdwListCount);
|
|
|
|
|
|
|
|
if (!data || !lpdwListCount || !data->IMC.hCandInfo)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
candinfo = ImmLockIMCC(data->IMC.hCandInfo);
|
|
|
|
|
|
|
|
*lpdwListCount = count = candinfo->dwCount;
|
|
|
|
|
|
|
|
if ( !is_himc_ime_unicode(data) )
|
|
|
|
ret = candinfo->dwSize;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
ret = sizeof(CANDIDATEINFO);
|
|
|
|
while ( count-- )
|
|
|
|
ret += ImmGetCandidateListA(hIMC, count, NULL, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
ImmUnlockIMCC(data->IMC.hCandInfo);
|
|
|
|
return ret;
|
2005-12-12 20:59:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ImmGetCandidateListCountW (IMM32.@)
|
|
|
|
*/
|
|
|
|
DWORD WINAPI ImmGetCandidateListCountW(
|
|
|
|
HIMC hIMC, LPDWORD lpdwListCount)
|
|
|
|
{
|
2014-09-28 18:27:58 +00:00
|
|
|
InputContextData *data = get_imc_data(hIMC);
|
2010-03-07 11:27:14 +00:00
|
|
|
LPCANDIDATEINFO candinfo;
|
|
|
|
DWORD ret, count;
|
|
|
|
|
|
|
|
TRACE("%p, %p\n", hIMC, lpdwListCount);
|
|
|
|
|
|
|
|
if (!data || !lpdwListCount || !data->IMC.hCandInfo)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
candinfo = ImmLockIMCC(data->IMC.hCandInfo);
|
|
|
|
|
|
|
|
*lpdwListCount = count = candinfo->dwCount;
|
|
|
|
|
|
|
|
if ( is_himc_ime_unicode(data) )
|
|
|
|
ret = candinfo->dwSize;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
ret = sizeof(CANDIDATEINFO);
|
|
|
|
while ( count-- )
|
|
|
|
ret += ImmGetCandidateListW(hIMC, count, NULL, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
ImmUnlockIMCC(data->IMC.hCandInfo);
|
|
|
|
return ret;
|
2005-12-12 20:59:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ImmGetCandidateListW (IMM32.@)
|
|
|
|
*/
|
|
|
|
DWORD WINAPI ImmGetCandidateListW(
|
2010-03-07 11:27:14 +00:00
|
|
|
HIMC hIMC, DWORD dwIndex,
|
2005-12-12 20:59:55 +00:00
|
|
|
LPCANDIDATELIST lpCandList, DWORD dwBufLen)
|
|
|
|
{
|
2014-09-28 18:27:58 +00:00
|
|
|
InputContextData *data = get_imc_data(hIMC);
|
2010-03-07 11:27:14 +00:00
|
|
|
LPCANDIDATEINFO candinfo;
|
|
|
|
LPCANDIDATELIST candlist;
|
|
|
|
DWORD ret = 0;
|
|
|
|
|
|
|
|
TRACE("%p, %d, %p, %d\n", hIMC, dwIndex, lpCandList, dwBufLen);
|
|
|
|
|
|
|
|
if (!data || !data->IMC.hCandInfo)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
candinfo = ImmLockIMCC(data->IMC.hCandInfo);
|
|
|
|
if ( dwIndex >= candinfo->dwCount ||
|
|
|
|
dwIndex >= (sizeof(candinfo->dwOffset) / sizeof(DWORD)) )
|
|
|
|
goto done;
|
|
|
|
|
|
|
|
candlist = (LPCANDIDATELIST)((LPBYTE)candinfo + candinfo->dwOffset[dwIndex]);
|
|
|
|
if ( !candlist->dwSize || !candlist->dwCount )
|
|
|
|
goto done;
|
|
|
|
|
|
|
|
if ( is_himc_ime_unicode(data) )
|
|
|
|
{
|
|
|
|
ret = candlist->dwSize;
|
|
|
|
if ( lpCandList && dwBufLen >= ret )
|
|
|
|
memcpy(lpCandList, candlist, ret);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
ret = convert_candidatelist_AtoW( candlist, lpCandList, dwBufLen);
|
|
|
|
|
|
|
|
done:
|
|
|
|
ImmUnlockIMCC(data->IMC.hCandInfo);
|
|
|
|
return ret;
|
2005-12-12 20:59:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ImmGetCandidateWindow (IMM32.@)
|
|
|
|
*/
|
|
|
|
BOOL WINAPI ImmGetCandidateWindow(
|
2010-03-07 11:27:14 +00:00
|
|
|
HIMC hIMC, DWORD dwIndex, LPCANDIDATEFORM lpCandidate)
|
2005-12-12 20:59:55 +00:00
|
|
|
{
|
2014-09-28 18:27:58 +00:00
|
|
|
InputContextData *data = get_imc_data(hIMC);
|
2010-03-07 11:27:14 +00:00
|
|
|
|
|
|
|
TRACE("%p, %d, %p\n", hIMC, dwIndex, lpCandidate);
|
|
|
|
|
|
|
|
if (!data || !lpCandidate)
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
if ( dwIndex >= (sizeof(data->IMC.cfCandForm) / sizeof(CANDIDATEFORM)) )
|
|
|
|
return FALSE;
|
|
|
|
|
2014-09-28 18:27:58 +00:00
|
|
|
if (data->IMC.cfCandForm[dwIndex].dwIndex != dwIndex)
|
|
|
|
return FALSE;
|
|
|
|
|
2010-03-07 11:27:14 +00:00
|
|
|
*lpCandidate = data->IMC.cfCandForm[dwIndex];
|
|
|
|
|
|
|
|
return TRUE;
|
2005-12-12 20:59:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ImmGetCompositionFontA (IMM32.@)
|
|
|
|
*/
|
|
|
|
BOOL WINAPI ImmGetCompositionFontA(HIMC hIMC, LPLOGFONTA lplf)
|
|
|
|
{
|
2008-04-04 13:20:27 +00:00
|
|
|
LOGFONTW lfW;
|
|
|
|
BOOL rc;
|
|
|
|
|
|
|
|
TRACE("(%p, %p):\n", hIMC, lplf);
|
|
|
|
|
|
|
|
rc = ImmGetCompositionFontW(hIMC,&lfW);
|
2010-03-07 11:27:14 +00:00
|
|
|
if (!rc || !lplf)
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
memcpy(lplf,&lfW,sizeof(LOGFONTA));
|
|
|
|
WideCharToMultiByte(CP_ACP, 0, lfW.lfFaceName, -1, lplf->lfFaceName,
|
2008-04-04 13:20:27 +00:00
|
|
|
LF_FACESIZE, NULL, NULL);
|
2010-03-07 11:27:14 +00:00
|
|
|
return TRUE;
|
2005-12-12 20:59:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ImmGetCompositionFontW (IMM32.@)
|
|
|
|
*/
|
|
|
|
BOOL WINAPI ImmGetCompositionFontW(HIMC hIMC, LPLOGFONTW lplf)
|
|
|
|
{
|
2014-09-28 18:27:58 +00:00
|
|
|
InputContextData *data = get_imc_data(hIMC);
|
2008-04-04 13:20:27 +00:00
|
|
|
|
|
|
|
TRACE("(%p, %p):\n", hIMC, lplf);
|
|
|
|
|
2010-03-07 11:27:14 +00:00
|
|
|
if (!data || !lplf)
|
2008-04-04 13:20:27 +00:00
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
*lplf = data->IMC.lfFont.W;
|
|
|
|
|
|
|
|
return TRUE;
|
2005-12-12 20:59:55 +00:00
|
|
|
}
|
|
|
|
|
2010-03-07 11:27:14 +00:00
|
|
|
|
|
|
|
/* Helpers for the GetCompositionString functions */
|
|
|
|
|
|
|
|
static INT CopyCompStringIMEtoClient(InputContextData *data, LPBYTE source, INT slen, LPBYTE target, INT tlen,
|
|
|
|
BOOL unicode )
|
2005-12-12 20:59:55 +00:00
|
|
|
{
|
2010-03-07 11:27:14 +00:00
|
|
|
INT rc;
|
2005-12-12 20:59:55 +00:00
|
|
|
|
2010-03-07 11:27:14 +00:00
|
|
|
if (is_himc_ime_unicode(data) && !unicode)
|
|
|
|
rc = WideCharToMultiByte(CP_ACP, 0, (LPWSTR)source, slen, (LPSTR)target, tlen, NULL, NULL);
|
|
|
|
else if (!is_himc_ime_unicode(data) && unicode)
|
|
|
|
rc = MultiByteToWideChar(CP_ACP, 0, (LPSTR)source, slen, (LPWSTR)target, tlen) * sizeof(WCHAR);
|
|
|
|
else
|
|
|
|
{
|
|
|
|
int dlen = (unicode)?sizeof(WCHAR):sizeof(CHAR);
|
|
|
|
memcpy( target, source, min(slen,tlen)*dlen);
|
|
|
|
rc = slen*dlen;
|
|
|
|
}
|
2005-12-12 20:59:55 +00:00
|
|
|
|
2010-03-07 11:27:14 +00:00
|
|
|
return rc;
|
|
|
|
}
|
2005-12-12 20:59:55 +00:00
|
|
|
|
2010-03-07 11:27:14 +00:00
|
|
|
static INT CopyCompAttrIMEtoClient(InputContextData *data, LPBYTE source, INT slen, LPBYTE ssource, INT sslen,
|
|
|
|
LPBYTE target, INT tlen, BOOL unicode )
|
|
|
|
{
|
|
|
|
INT rc;
|
2007-09-14 08:03:04 +00:00
|
|
|
|
2010-03-07 11:27:14 +00:00
|
|
|
if (is_himc_ime_unicode(data) && !unicode)
|
|
|
|
{
|
|
|
|
rc = WideCharToMultiByte(CP_ACP, 0, (LPWSTR)ssource, sslen, NULL, 0, NULL, NULL);
|
|
|
|
if (tlen)
|
|
|
|
{
|
|
|
|
const BYTE *src = source;
|
|
|
|
LPBYTE dst = target;
|
|
|
|
int i, j = 0, k = 0;
|
2007-09-14 08:03:04 +00:00
|
|
|
|
2010-03-07 11:27:14 +00:00
|
|
|
if (rc < tlen)
|
|
|
|
tlen = rc;
|
|
|
|
for (i = 0; i < sslen; ++i)
|
|
|
|
{
|
|
|
|
int len;
|
|
|
|
|
|
|
|
len = WideCharToMultiByte(CP_ACP, 0, (LPCWSTR)ssource + i, 1,
|
|
|
|
NULL, 0, NULL, NULL);
|
|
|
|
for (; len > 0; --len)
|
|
|
|
{
|
|
|
|
dst[j++] = src[k];
|
|
|
|
|
|
|
|
if (j >= tlen)
|
|
|
|
goto end;
|
|
|
|
}
|
|
|
|
++k;
|
|
|
|
}
|
|
|
|
end:
|
|
|
|
rc = j;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (!is_himc_ime_unicode(data) && unicode)
|
|
|
|
{
|
|
|
|
rc = MultiByteToWideChar(CP_ACP, 0, (LPSTR)ssource, sslen, NULL, 0);
|
|
|
|
if (tlen)
|
|
|
|
{
|
|
|
|
const BYTE *src = source;
|
|
|
|
LPBYTE dst = target;
|
|
|
|
int i, j = 0;
|
|
|
|
|
|
|
|
if (rc < tlen)
|
|
|
|
tlen = rc;
|
|
|
|
for (i = 0; i < sslen; ++i)
|
|
|
|
{
|
|
|
|
if (IsDBCSLeadByte(((LPSTR)ssource)[i]))
|
|
|
|
continue;
|
|
|
|
|
|
|
|
dst[j++] = src[i];
|
|
|
|
|
|
|
|
if (j >= tlen)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
rc = j;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
2005-12-12 20:59:55 +00:00
|
|
|
{
|
2010-03-07 11:27:14 +00:00
|
|
|
memcpy( target, source, min(slen,tlen));
|
|
|
|
rc = slen;
|
|
|
|
}
|
2005-12-12 20:59:55 +00:00
|
|
|
|
2010-03-07 11:27:14 +00:00
|
|
|
return rc;
|
|
|
|
}
|
2007-09-14 08:03:04 +00:00
|
|
|
|
2011-12-15 00:40:35 +00:00
|
|
|
static INT CopyCompClauseIMEtoClient(InputContextData *data, LPBYTE source, INT slen, LPBYTE ssource,
|
2010-03-07 11:27:14 +00:00
|
|
|
LPBYTE target, INT tlen, BOOL unicode )
|
|
|
|
{
|
|
|
|
INT rc;
|
2005-12-12 20:59:55 +00:00
|
|
|
|
2010-03-07 11:27:14 +00:00
|
|
|
if (is_himc_ime_unicode(data) && !unicode)
|
2005-12-12 20:59:55 +00:00
|
|
|
{
|
2010-03-07 11:27:14 +00:00
|
|
|
if (tlen)
|
|
|
|
{
|
|
|
|
int i;
|
2005-12-12 20:59:55 +00:00
|
|
|
|
2010-03-07 11:27:14 +00:00
|
|
|
if (slen < tlen)
|
|
|
|
tlen = slen;
|
|
|
|
tlen /= sizeof (DWORD);
|
|
|
|
for (i = 0; i < tlen; ++i)
|
|
|
|
{
|
|
|
|
((DWORD *)target)[i] = WideCharToMultiByte(CP_ACP, 0, (LPWSTR)ssource,
|
|
|
|
((DWORD *)source)[i],
|
|
|
|
NULL, 0,
|
|
|
|
NULL, NULL);
|
|
|
|
}
|
|
|
|
rc = sizeof (DWORD) * i;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
rc = slen;
|
2005-12-12 20:59:55 +00:00
|
|
|
}
|
2010-03-07 11:27:14 +00:00
|
|
|
else if (!is_himc_ime_unicode(data) && unicode)
|
2005-12-12 20:59:55 +00:00
|
|
|
{
|
2010-03-07 11:27:14 +00:00
|
|
|
if (tlen)
|
|
|
|
{
|
|
|
|
int i;
|
2005-12-12 20:59:55 +00:00
|
|
|
|
2010-03-07 11:27:14 +00:00
|
|
|
if (slen < tlen)
|
|
|
|
tlen = slen;
|
|
|
|
tlen /= sizeof (DWORD);
|
|
|
|
for (i = 0; i < tlen; ++i)
|
|
|
|
{
|
|
|
|
((DWORD *)target)[i] = MultiByteToWideChar(CP_ACP, 0, (LPSTR)ssource,
|
|
|
|
((DWORD *)source)[i],
|
|
|
|
NULL, 0);
|
|
|
|
}
|
|
|
|
rc = sizeof (DWORD) * i;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
rc = slen;
|
2005-12-12 20:59:55 +00:00
|
|
|
}
|
2010-03-07 11:27:14 +00:00
|
|
|
else
|
2005-12-12 20:59:55 +00:00
|
|
|
{
|
2010-03-07 11:27:14 +00:00
|
|
|
memcpy( target, source, min(slen,tlen));
|
|
|
|
rc = slen;
|
2005-12-12 20:59:55 +00:00
|
|
|
}
|
2007-03-14 14:34:47 +00:00
|
|
|
|
2010-03-07 11:27:14 +00:00
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
|
|
|
static INT CopyCompOffsetIMEtoClient(InputContextData *data, DWORD offset, LPBYTE ssource, BOOL unicode)
|
|
|
|
{
|
|
|
|
int rc;
|
|
|
|
|
|
|
|
if (is_himc_ime_unicode(data) && !unicode)
|
2007-09-14 08:03:04 +00:00
|
|
|
{
|
2010-03-07 11:27:14 +00:00
|
|
|
rc = WideCharToMultiByte(CP_ACP, 0, (LPWSTR)ssource, offset, NULL, 0, NULL, NULL);
|
2007-09-14 08:03:04 +00:00
|
|
|
}
|
2010-03-07 11:27:14 +00:00
|
|
|
else if (!is_himc_ime_unicode(data) && unicode)
|
2007-09-14 08:03:04 +00:00
|
|
|
{
|
2010-03-07 11:27:14 +00:00
|
|
|
rc = MultiByteToWideChar(CP_ACP, 0, (LPSTR)ssource, offset, NULL, 0);
|
2007-03-14 14:34:47 +00:00
|
|
|
}
|
2005-12-12 20:59:55 +00:00
|
|
|
else
|
2010-03-07 11:27:14 +00:00
|
|
|
rc = offset;
|
2007-09-14 08:03:04 +00:00
|
|
|
|
2005-12-12 20:59:55 +00:00
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
2010-03-07 11:27:14 +00:00
|
|
|
static LONG ImmGetCompositionStringT( HIMC hIMC, DWORD dwIndex, LPVOID lpBuf,
|
|
|
|
DWORD dwBufLen, BOOL unicode)
|
2005-12-12 20:59:55 +00:00
|
|
|
{
|
2006-04-16 17:04:45 +00:00
|
|
|
LONG rc = 0;
|
2014-09-28 18:27:58 +00:00
|
|
|
InputContextData *data = get_imc_data(hIMC);
|
2007-09-14 08:03:04 +00:00
|
|
|
LPCOMPOSITIONSTRING compstr;
|
|
|
|
LPBYTE compdata;
|
2005-12-12 20:59:55 +00:00
|
|
|
|
2006-11-26 21:05:00 +00:00
|
|
|
TRACE("(%p, 0x%x, %p, %d)\n", hIMC, dwIndex, lpBuf, dwBufLen);
|
2005-12-12 20:59:55 +00:00
|
|
|
|
|
|
|
if (!data)
|
|
|
|
return FALSE;
|
|
|
|
|
2007-09-14 08:03:04 +00:00
|
|
|
if (!data->IMC.hCompStr)
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
compdata = ImmLockIMCC(data->IMC.hCompStr);
|
|
|
|
compstr = (LPCOMPOSITIONSTRING)compdata;
|
|
|
|
|
2010-03-07 11:27:14 +00:00
|
|
|
switch (dwIndex)
|
|
|
|
{
|
|
|
|
case GCS_RESULTSTR:
|
|
|
|
TRACE("GCS_RESULTSTR\n");
|
|
|
|
rc = CopyCompStringIMEtoClient(data, compdata + compstr->dwResultStrOffset, compstr->dwResultStrLen, lpBuf, dwBufLen, unicode);
|
|
|
|
break;
|
|
|
|
case GCS_COMPSTR:
|
|
|
|
TRACE("GCS_COMPSTR\n");
|
|
|
|
rc = CopyCompStringIMEtoClient(data, compdata + compstr->dwCompStrOffset, compstr->dwCompStrLen, lpBuf, dwBufLen, unicode);
|
|
|
|
break;
|
|
|
|
case GCS_COMPATTR:
|
|
|
|
TRACE("GCS_COMPATTR\n");
|
|
|
|
rc = CopyCompAttrIMEtoClient(data, compdata + compstr->dwCompAttrOffset, compstr->dwCompAttrLen,
|
|
|
|
compdata + compstr->dwCompStrOffset, compstr->dwCompStrLen,
|
|
|
|
lpBuf, dwBufLen, unicode);
|
|
|
|
break;
|
|
|
|
case GCS_COMPCLAUSE:
|
|
|
|
TRACE("GCS_COMPCLAUSE\n");
|
|
|
|
rc = CopyCompClauseIMEtoClient(data, compdata + compstr->dwCompClauseOffset,compstr->dwCompClauseLen,
|
2011-12-15 00:40:35 +00:00
|
|
|
compdata + compstr->dwCompStrOffset,
|
2010-03-07 11:27:14 +00:00
|
|
|
lpBuf, dwBufLen, unicode);
|
|
|
|
break;
|
|
|
|
case GCS_RESULTCLAUSE:
|
|
|
|
TRACE("GCS_RESULTCLAUSE\n");
|
|
|
|
rc = CopyCompClauseIMEtoClient(data, compdata + compstr->dwResultClauseOffset,compstr->dwResultClauseLen,
|
2011-12-15 00:40:35 +00:00
|
|
|
compdata + compstr->dwResultStrOffset,
|
2010-03-07 11:27:14 +00:00
|
|
|
lpBuf, dwBufLen, unicode);
|
|
|
|
break;
|
|
|
|
case GCS_RESULTREADSTR:
|
|
|
|
TRACE("GCS_RESULTREADSTR\n");
|
|
|
|
rc = CopyCompStringIMEtoClient(data, compdata + compstr->dwResultReadStrOffset, compstr->dwResultReadStrLen, lpBuf, dwBufLen, unicode);
|
|
|
|
break;
|
|
|
|
case GCS_RESULTREADCLAUSE:
|
|
|
|
TRACE("GCS_RESULTREADCLAUSE\n");
|
|
|
|
rc = CopyCompClauseIMEtoClient(data, compdata + compstr->dwResultReadClauseOffset,compstr->dwResultReadClauseLen,
|
2011-12-15 00:40:35 +00:00
|
|
|
compdata + compstr->dwResultStrOffset,
|
2010-03-07 11:27:14 +00:00
|
|
|
lpBuf, dwBufLen, unicode);
|
|
|
|
break;
|
|
|
|
case GCS_COMPREADSTR:
|
|
|
|
TRACE("GCS_COMPREADSTR\n");
|
|
|
|
rc = CopyCompStringIMEtoClient(data, compdata + compstr->dwCompReadStrOffset, compstr->dwCompReadStrLen, lpBuf, dwBufLen, unicode);
|
|
|
|
break;
|
|
|
|
case GCS_COMPREADATTR:
|
|
|
|
TRACE("GCS_COMPREADATTR\n");
|
|
|
|
rc = CopyCompAttrIMEtoClient(data, compdata + compstr->dwCompReadAttrOffset, compstr->dwCompReadAttrLen,
|
|
|
|
compdata + compstr->dwCompReadStrOffset, compstr->dwCompReadStrLen,
|
|
|
|
lpBuf, dwBufLen, unicode);
|
|
|
|
break;
|
|
|
|
case GCS_COMPREADCLAUSE:
|
|
|
|
TRACE("GCS_COMPREADCLAUSE\n");
|
|
|
|
rc = CopyCompClauseIMEtoClient(data, compdata + compstr->dwCompReadClauseOffset,compstr->dwCompReadClauseLen,
|
2011-12-15 00:40:35 +00:00
|
|
|
compdata + compstr->dwCompStrOffset,
|
2010-03-07 11:27:14 +00:00
|
|
|
lpBuf, dwBufLen, unicode);
|
|
|
|
break;
|
|
|
|
case GCS_CURSORPOS:
|
|
|
|
TRACE("GCS_CURSORPOS\n");
|
|
|
|
rc = CopyCompOffsetIMEtoClient(data, compstr->dwCursorPos, compdata + compstr->dwCompStrOffset, unicode);
|
|
|
|
break;
|
|
|
|
case GCS_DELTASTART:
|
2007-09-14 08:03:04 +00:00
|
|
|
TRACE("GCS_DELTASTART\n");
|
2010-03-07 11:27:14 +00:00
|
|
|
rc = CopyCompOffsetIMEtoClient(data, compstr->dwDeltaStart, compdata + compstr->dwCompStrOffset, unicode);
|
|
|
|
break;
|
|
|
|
default:
|
2006-11-26 21:05:00 +00:00
|
|
|
FIXME("Unhandled index 0x%x\n",dwIndex);
|
2010-03-07 11:27:14 +00:00
|
|
|
break;
|
|
|
|
}
|
2005-12-12 20:59:55 +00:00
|
|
|
|
2007-09-14 08:03:04 +00:00
|
|
|
ImmUnlockIMCC(data->IMC.hCompStr);
|
|
|
|
|
2005-12-12 20:59:55 +00:00
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
2010-03-07 11:27:14 +00:00
|
|
|
/***********************************************************************
|
|
|
|
* ImmGetCompositionStringA (IMM32.@)
|
|
|
|
*/
|
|
|
|
LONG WINAPI ImmGetCompositionStringA(
|
|
|
|
HIMC hIMC, DWORD dwIndex, LPVOID lpBuf, DWORD dwBufLen)
|
|
|
|
{
|
|
|
|
return ImmGetCompositionStringT(hIMC, dwIndex, lpBuf, dwBufLen, FALSE);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ImmGetCompositionStringW (IMM32.@)
|
|
|
|
*/
|
|
|
|
LONG WINAPI ImmGetCompositionStringW(
|
|
|
|
HIMC hIMC, DWORD dwIndex,
|
|
|
|
LPVOID lpBuf, DWORD dwBufLen)
|
|
|
|
{
|
|
|
|
return ImmGetCompositionStringT(hIMC, dwIndex, lpBuf, dwBufLen, TRUE);
|
|
|
|
}
|
|
|
|
|
2005-12-12 20:59:55 +00:00
|
|
|
/***********************************************************************
|
|
|
|
* ImmGetCompositionWindow (IMM32.@)
|
|
|
|
*/
|
|
|
|
BOOL WINAPI ImmGetCompositionWindow(HIMC hIMC, LPCOMPOSITIONFORM lpCompForm)
|
|
|
|
{
|
2014-09-28 18:27:58 +00:00
|
|
|
InputContextData *data = get_imc_data(hIMC);
|
2005-12-12 20:59:55 +00:00
|
|
|
|
|
|
|
TRACE("(%p, %p)\n", hIMC, lpCompForm);
|
|
|
|
|
|
|
|
if (!data)
|
|
|
|
return FALSE;
|
|
|
|
|
2008-04-04 13:20:27 +00:00
|
|
|
*lpCompForm = data->IMC.cfCompForm;
|
2014-09-28 18:27:58 +00:00
|
|
|
return TRUE;
|
2005-12-12 20:59:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ImmGetContext (IMM32.@)
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
HIMC WINAPI ImmGetContext(HWND hWnd)
|
|
|
|
{
|
2011-12-15 00:40:35 +00:00
|
|
|
HIMC rc;
|
2008-04-04 13:20:27 +00:00
|
|
|
|
2006-04-16 17:04:45 +00:00
|
|
|
TRACE("%p\n", hWnd);
|
2011-12-15 00:40:35 +00:00
|
|
|
|
|
|
|
if (!IsWindow(hWnd))
|
|
|
|
{
|
|
|
|
SetLastError(ERROR_INVALID_WINDOW_HANDLE);
|
|
|
|
return NULL;
|
|
|
|
}
|
2005-12-12 20:59:55 +00:00
|
|
|
|
2010-03-07 11:27:14 +00:00
|
|
|
rc = GetPropW(hWnd,szwWineIMCProperty);
|
2008-04-04 13:20:27 +00:00
|
|
|
if (rc == (HIMC)-1)
|
|
|
|
rc = NULL;
|
|
|
|
else if (rc == NULL)
|
2017-12-08 03:14:21 +00:00
|
|
|
rc = get_default_context( hWnd );
|
2008-04-04 13:20:27 +00:00
|
|
|
|
|
|
|
if (rc)
|
|
|
|
{
|
2010-03-07 11:27:14 +00:00
|
|
|
InputContextData *data = rc;
|
2008-04-04 13:20:27 +00:00
|
|
|
data->IMC.hWnd = hWnd;
|
|
|
|
}
|
2017-12-08 03:14:21 +00:00
|
|
|
|
2008-04-04 13:20:27 +00:00
|
|
|
TRACE("returning %p\n", rc);
|
2005-12-12 20:59:55 +00:00
|
|
|
|
2008-04-04 13:20:27 +00:00
|
|
|
return rc;
|
2005-12-12 20:59:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ImmGetConversionListA (IMM32.@)
|
|
|
|
*/
|
|
|
|
DWORD WINAPI ImmGetConversionListA(
|
|
|
|
HKL hKL, HIMC hIMC,
|
|
|
|
LPCSTR pSrc, LPCANDIDATELIST lpDst,
|
|
|
|
DWORD dwBufLen, UINT uFlag)
|
|
|
|
{
|
2010-03-07 11:27:14 +00:00
|
|
|
ImmHkl *immHkl = IMM_GetImmHkl(hKL);
|
|
|
|
TRACE("(%p, %p, %s, %p, %d, %d):\n", hKL, hIMC, debugstr_a(pSrc), lpDst,
|
|
|
|
dwBufLen, uFlag);
|
|
|
|
if (immHkl->hIME && immHkl->pImeConversionList)
|
|
|
|
{
|
|
|
|
if (!is_kbd_ime_unicode(immHkl))
|
|
|
|
return immHkl->pImeConversionList(hIMC,(LPCWSTR)pSrc,lpDst,dwBufLen,uFlag);
|
|
|
|
else
|
|
|
|
{
|
|
|
|
LPCANDIDATELIST lpwDst;
|
|
|
|
DWORD ret = 0, len;
|
|
|
|
LPWSTR pwSrc = strdupAtoW(pSrc);
|
|
|
|
|
|
|
|
len = immHkl->pImeConversionList(hIMC, pwSrc, NULL, 0, uFlag);
|
|
|
|
lpwDst = HeapAlloc(GetProcessHeap(), 0, len);
|
|
|
|
if ( lpwDst )
|
|
|
|
{
|
|
|
|
immHkl->pImeConversionList(hIMC, pwSrc, lpwDst, len, uFlag);
|
|
|
|
ret = convert_candidatelist_WtoA( lpwDst, lpDst, dwBufLen);
|
|
|
|
HeapFree(GetProcessHeap(), 0, lpwDst);
|
|
|
|
}
|
|
|
|
HeapFree(GetProcessHeap(), 0, pwSrc);
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
return 0;
|
2005-12-12 20:59:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ImmGetConversionListW (IMM32.@)
|
|
|
|
*/
|
|
|
|
DWORD WINAPI ImmGetConversionListW(
|
|
|
|
HKL hKL, HIMC hIMC,
|
|
|
|
LPCWSTR pSrc, LPCANDIDATELIST lpDst,
|
|
|
|
DWORD dwBufLen, UINT uFlag)
|
|
|
|
{
|
2010-03-07 11:27:14 +00:00
|
|
|
ImmHkl *immHkl = IMM_GetImmHkl(hKL);
|
|
|
|
TRACE("(%p, %p, %s, %p, %d, %d):\n", hKL, hIMC, debugstr_w(pSrc), lpDst,
|
|
|
|
dwBufLen, uFlag);
|
|
|
|
if (immHkl->hIME && immHkl->pImeConversionList)
|
|
|
|
{
|
|
|
|
if (is_kbd_ime_unicode(immHkl))
|
|
|
|
return immHkl->pImeConversionList(hIMC,pSrc,lpDst,dwBufLen,uFlag);
|
|
|
|
else
|
|
|
|
{
|
|
|
|
LPCANDIDATELIST lpaDst;
|
|
|
|
DWORD ret = 0, len;
|
|
|
|
LPSTR paSrc = strdupWtoA(pSrc);
|
|
|
|
|
|
|
|
len = immHkl->pImeConversionList(hIMC, (LPCWSTR)paSrc, NULL, 0, uFlag);
|
|
|
|
lpaDst = HeapAlloc(GetProcessHeap(), 0, len);
|
|
|
|
if ( lpaDst )
|
|
|
|
{
|
|
|
|
immHkl->pImeConversionList(hIMC, (LPCWSTR)paSrc, lpaDst, len, uFlag);
|
|
|
|
ret = convert_candidatelist_AtoW( lpaDst, lpDst, dwBufLen);
|
|
|
|
HeapFree(GetProcessHeap(), 0, lpaDst);
|
|
|
|
}
|
|
|
|
HeapFree(GetProcessHeap(), 0, paSrc);
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
return 0;
|
2005-12-12 20:59:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ImmGetConversionStatus (IMM32.@)
|
|
|
|
*/
|
|
|
|
BOOL WINAPI ImmGetConversionStatus(
|
|
|
|
HIMC hIMC, LPDWORD lpfdwConversion, LPDWORD lpfdwSentence)
|
|
|
|
{
|
2014-09-28 18:27:58 +00:00
|
|
|
InputContextData *data = get_imc_data(hIMC);
|
2010-03-07 11:27:14 +00:00
|
|
|
|
|
|
|
TRACE("%p %p %p\n", hIMC, lpfdwConversion, lpfdwSentence);
|
|
|
|
|
|
|
|
if (!data)
|
|
|
|
return FALSE;
|
|
|
|
|
2005-12-12 20:59:55 +00:00
|
|
|
if (lpfdwConversion)
|
2010-03-07 11:27:14 +00:00
|
|
|
*lpfdwConversion = data->IMC.fdwConversion;
|
2005-12-12 20:59:55 +00:00
|
|
|
if (lpfdwSentence)
|
2010-03-07 11:27:14 +00:00
|
|
|
*lpfdwSentence = data->IMC.fdwSentence;
|
|
|
|
|
2005-12-12 20:59:55 +00:00
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2017-12-08 03:14:21 +00:00
|
|
|
static BOOL needs_ime_window(HWND hwnd)
|
|
|
|
{
|
|
|
|
WCHAR classW[8];
|
|
|
|
|
|
|
|
if (GetClassNameW(hwnd, classW, sizeof(classW)/sizeof(classW[0])) &&
|
|
|
|
!strcmpW(classW, szwIME))
|
|
|
|
return FALSE;
|
|
|
|
if (GetClassLongPtrW(hwnd, GCL_STYLE) & CS_IME) return FALSE;
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* __wine_register_window (IMM32.@)
|
|
|
|
*/
|
|
|
|
BOOL WINAPI __wine_register_window(HWND hwnd)
|
|
|
|
{
|
|
|
|
HWND new = NULL;
|
|
|
|
IMMThreadData *thread_data;
|
|
|
|
TRACE("(%p)\n", hwnd);
|
|
|
|
|
|
|
|
if (!needs_ime_window(hwnd))
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
thread_data = IMM_GetThreadData(hwnd, 0);
|
|
|
|
if (!thread_data)
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
if (thread_data->disableIME || disable_ime)
|
|
|
|
{
|
|
|
|
TRACE("IME for this thread is disabled\n");
|
|
|
|
LeaveCriticalSection(&threaddata_cs);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
thread_data->windowRefs++;
|
|
|
|
TRACE("windowRefs=%u, hwndDefault=%p\n",
|
|
|
|
thread_data->windowRefs, thread_data->hwndDefault);
|
|
|
|
|
|
|
|
/* Create default IME window */
|
|
|
|
if (thread_data->windowRefs == 1)
|
|
|
|
{
|
|
|
|
/* Do not create the window inside of a critical section */
|
|
|
|
LeaveCriticalSection(&threaddata_cs);
|
|
|
|
new = CreateWindowExW( 0, szwIME, szwDefaultIME,
|
|
|
|
WS_POPUP | WS_DISABLED | WS_CLIPSIBLINGS,
|
|
|
|
0, 0, 1, 1, 0, 0, 0, 0);
|
|
|
|
/* thread_data is in the current thread so we can assume it's still valid */
|
|
|
|
EnterCriticalSection(&threaddata_cs);
|
|
|
|
/* See if anyone beat us */
|
|
|
|
if (thread_data->hwndDefault == NULL)
|
|
|
|
{
|
|
|
|
thread_data->hwndDefault = new;
|
|
|
|
new = NULL;
|
|
|
|
TRACE("Default is %p\n", thread_data->hwndDefault);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
LeaveCriticalSection(&threaddata_cs);
|
|
|
|
|
|
|
|
/* Clean up an unused new window outside of the critical section */
|
|
|
|
if (new != NULL)
|
|
|
|
DestroyWindow(new);
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* __wine_unregister_window (IMM32.@)
|
|
|
|
*/
|
|
|
|
void WINAPI __wine_unregister_window(HWND hwnd)
|
|
|
|
{
|
|
|
|
HWND to_destroy = 0;
|
|
|
|
IMMThreadData *thread_data;
|
|
|
|
TRACE("(%p)\n", hwnd);
|
|
|
|
|
|
|
|
thread_data = IMM_GetThreadData(hwnd, 0);
|
|
|
|
if (!thread_data) return;
|
|
|
|
|
|
|
|
thread_data->windowRefs--;
|
|
|
|
TRACE("windowRefs=%u, hwndDefault=%p\n",
|
|
|
|
thread_data->windowRefs, thread_data->hwndDefault);
|
|
|
|
|
|
|
|
/* Destroy default IME window */
|
|
|
|
if (thread_data->windowRefs == 0 && thread_data->hwndDefault)
|
|
|
|
{
|
|
|
|
to_destroy = thread_data->hwndDefault;
|
|
|
|
thread_data->hwndDefault = NULL;
|
|
|
|
}
|
|
|
|
LeaveCriticalSection(&threaddata_cs);
|
|
|
|
|
|
|
|
if (to_destroy) DestroyWindow( to_destroy );
|
|
|
|
}
|
|
|
|
|
2005-12-12 20:59:55 +00:00
|
|
|
/***********************************************************************
|
|
|
|
* ImmGetDefaultIMEWnd (IMM32.@)
|
|
|
|
*/
|
|
|
|
HWND WINAPI ImmGetDefaultIMEWnd(HWND hWnd)
|
|
|
|
{
|
2017-12-08 03:14:21 +00:00
|
|
|
HWND ret;
|
|
|
|
IMMThreadData* thread_data = IMM_GetThreadData(hWnd, 0);
|
|
|
|
if (!thread_data)
|
|
|
|
return NULL;
|
|
|
|
ret = thread_data->hwndDefault;
|
|
|
|
LeaveCriticalSection(&threaddata_cs);
|
|
|
|
TRACE("Default is %p\n",ret);
|
|
|
|
return ret;
|
2005-12-12 20:59:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ImmGetDescriptionA (IMM32.@)
|
|
|
|
*/
|
|
|
|
UINT WINAPI ImmGetDescriptionA(
|
|
|
|
HKL hKL, LPSTR lpszDescription, UINT uBufLen)
|
|
|
|
{
|
|
|
|
WCHAR *buf;
|
|
|
|
DWORD len;
|
|
|
|
|
|
|
|
TRACE("%p %p %d\n", hKL, lpszDescription, uBufLen);
|
|
|
|
|
|
|
|
/* find out how many characters in the unicode buffer */
|
|
|
|
len = ImmGetDescriptionW( hKL, NULL, 0 );
|
2014-09-28 18:27:58 +00:00
|
|
|
if (!len)
|
|
|
|
return 0;
|
2005-12-12 20:59:55 +00:00
|
|
|
|
|
|
|
/* allocate a buffer of that size */
|
|
|
|
buf = HeapAlloc( GetProcessHeap(), 0, (len + 1) * sizeof (WCHAR) );
|
|
|
|
if( !buf )
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
/* fetch the unicode buffer */
|
|
|
|
len = ImmGetDescriptionW( hKL, buf, len + 1 );
|
|
|
|
|
|
|
|
/* convert it back to ASCII */
|
|
|
|
len = WideCharToMultiByte( CP_ACP, 0, buf, len + 1,
|
|
|
|
lpszDescription, uBufLen, NULL, NULL );
|
|
|
|
|
|
|
|
HeapFree( GetProcessHeap(), 0, buf );
|
|
|
|
|
2014-09-28 18:27:58 +00:00
|
|
|
if (len == 0)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
return len - 1;
|
2005-12-12 20:59:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ImmGetDescriptionW (IMM32.@)
|
|
|
|
*/
|
|
|
|
UINT WINAPI ImmGetDescriptionW(HKL hKL, LPWSTR lpszDescription, UINT uBufLen)
|
|
|
|
{
|
|
|
|
static const WCHAR name[] = { 'W','i','n','e',' ','X','I','M',0 };
|
|
|
|
|
|
|
|
FIXME("(%p, %p, %d): semi stub\n", hKL, lpszDescription, uBufLen);
|
|
|
|
|
2014-09-28 18:27:58 +00:00
|
|
|
if (!hKL) return 0;
|
2005-12-12 20:59:55 +00:00
|
|
|
if (!uBufLen) return lstrlenW( name );
|
|
|
|
lstrcpynW( lpszDescription, name, uBufLen );
|
|
|
|
return lstrlenW( lpszDescription );
|
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ImmGetGuideLineA (IMM32.@)
|
|
|
|
*/
|
|
|
|
DWORD WINAPI ImmGetGuideLineA(
|
|
|
|
HIMC hIMC, DWORD dwIndex, LPSTR lpBuf, DWORD dwBufLen)
|
|
|
|
{
|
2006-11-26 21:05:00 +00:00
|
|
|
FIXME("(%p, %d, %s, %d): stub\n",
|
2005-12-12 20:59:55 +00:00
|
|
|
hIMC, dwIndex, debugstr_a(lpBuf), dwBufLen
|
|
|
|
);
|
|
|
|
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ImmGetGuideLineW (IMM32.@)
|
|
|
|
*/
|
|
|
|
DWORD WINAPI ImmGetGuideLineW(HIMC hIMC, DWORD dwIndex, LPWSTR lpBuf, DWORD dwBufLen)
|
|
|
|
{
|
2006-11-26 21:05:00 +00:00
|
|
|
FIXME("(%p, %d, %s, %d): stub\n",
|
2005-12-12 20:59:55 +00:00
|
|
|
hIMC, dwIndex, debugstr_w(lpBuf), dwBufLen
|
|
|
|
);
|
|
|
|
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ImmGetIMEFileNameA (IMM32.@)
|
|
|
|
*/
|
2008-04-04 13:20:27 +00:00
|
|
|
UINT WINAPI ImmGetIMEFileNameA( HKL hKL, LPSTR lpszFileName, UINT uBufLen)
|
2005-12-12 20:59:55 +00:00
|
|
|
{
|
2008-04-04 13:20:27 +00:00
|
|
|
LPWSTR bufW = NULL;
|
|
|
|
UINT wBufLen = uBufLen;
|
|
|
|
UINT rc;
|
|
|
|
|
|
|
|
if (uBufLen && lpszFileName)
|
|
|
|
bufW = HeapAlloc(GetProcessHeap(),0,uBufLen * sizeof(WCHAR));
|
|
|
|
else /* We need this to get the number of byte required */
|
|
|
|
{
|
|
|
|
bufW = HeapAlloc(GetProcessHeap(),0,MAX_PATH * sizeof(WCHAR));
|
|
|
|
wBufLen = MAX_PATH;
|
|
|
|
}
|
|
|
|
|
|
|
|
rc = ImmGetIMEFileNameW(hKL,bufW,wBufLen);
|
|
|
|
|
|
|
|
if (rc > 0)
|
|
|
|
{
|
|
|
|
if (uBufLen && lpszFileName)
|
|
|
|
rc = WideCharToMultiByte(CP_ACP, 0, bufW, -1, lpszFileName,
|
|
|
|
uBufLen, NULL, NULL);
|
|
|
|
else /* get the length */
|
|
|
|
rc = WideCharToMultiByte(CP_ACP, 0, bufW, -1, NULL, 0, NULL,
|
|
|
|
NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
HeapFree(GetProcessHeap(),0,bufW);
|
|
|
|
return rc;
|
2005-12-12 20:59:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ImmGetIMEFileNameW (IMM32.@)
|
|
|
|
*/
|
2008-04-04 13:20:27 +00:00
|
|
|
UINT WINAPI ImmGetIMEFileNameW(HKL hKL, LPWSTR lpszFileName, UINT uBufLen)
|
2005-12-12 20:59:55 +00:00
|
|
|
{
|
2008-04-04 13:20:27 +00:00
|
|
|
HKEY hkey;
|
|
|
|
DWORD length;
|
|
|
|
DWORD rc;
|
2010-03-07 11:27:14 +00:00
|
|
|
WCHAR regKey[sizeof(szImeRegFmt)/sizeof(WCHAR)+8];
|
2008-04-04 13:20:27 +00:00
|
|
|
|
2010-03-07 11:27:14 +00:00
|
|
|
wsprintfW( regKey, szImeRegFmt, (ULONG_PTR)hKL );
|
2008-04-04 13:20:27 +00:00
|
|
|
rc = RegOpenKeyW( HKEY_LOCAL_MACHINE, regKey, &hkey);
|
|
|
|
if (rc != ERROR_SUCCESS)
|
|
|
|
{
|
|
|
|
SetLastError(rc);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
length = 0;
|
|
|
|
rc = RegGetValueW(hkey, NULL, szImeFileW, RRF_RT_REG_SZ, NULL, NULL, &length);
|
|
|
|
|
|
|
|
if (rc != ERROR_SUCCESS)
|
|
|
|
{
|
|
|
|
RegCloseKey(hkey);
|
|
|
|
SetLastError(rc);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
if (length > uBufLen * sizeof(WCHAR) || !lpszFileName)
|
|
|
|
{
|
|
|
|
RegCloseKey(hkey);
|
|
|
|
if (lpszFileName)
|
|
|
|
{
|
|
|
|
SetLastError(ERROR_INSUFFICIENT_BUFFER);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
return length / sizeof(WCHAR);
|
|
|
|
}
|
|
|
|
|
|
|
|
RegGetValueW(hkey, NULL, szImeFileW, RRF_RT_REG_SZ, NULL, lpszFileName, &length);
|
|
|
|
|
|
|
|
RegCloseKey(hkey);
|
|
|
|
|
|
|
|
return length / sizeof(WCHAR);
|
2005-12-12 20:59:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ImmGetOpenStatus (IMM32.@)
|
|
|
|
*/
|
|
|
|
BOOL WINAPI ImmGetOpenStatus(HIMC hIMC)
|
|
|
|
{
|
2014-09-28 18:27:58 +00:00
|
|
|
InputContextData *data = get_imc_data(hIMC);
|
Sync avifil, credui, crypt32, cryptdlg, cryptui, dnsapi, gdiplus, hhctrl, hnetcfg, iccvid, imaadp32, imm32, jscript, localspl, localui, mapi32, mciavi32, mcicda, mciqtz32, mciseq, mciwave, mshtml, msrle32, msvfw32, msvidc32, msxml3, oleacc, oleaut32 to Wine 1.2rc5 (Samuel Serapion, small changes by me)
Remove Esperanto and Walon languages from comctl32, comdlg32, mpr, msi, shlwapi, wininet
svn path=/trunk/; revision=47920
2010-07-01 11:09:47 +00:00
|
|
|
static int i;
|
2005-12-12 20:59:55 +00:00
|
|
|
|
|
|
|
if (!data)
|
|
|
|
return FALSE;
|
Sync avifil, credui, crypt32, cryptdlg, cryptui, dnsapi, gdiplus, hhctrl, hnetcfg, iccvid, imaadp32, imm32, jscript, localspl, localui, mapi32, mciavi32, mcicda, mciqtz32, mciseq, mciwave, mshtml, msrle32, msvfw32, msvidc32, msxml3, oleacc, oleaut32 to Wine 1.2rc5 (Samuel Serapion, small changes by me)
Remove Esperanto and Walon languages from comctl32, comdlg32, mpr, msi, shlwapi, wininet
svn path=/trunk/; revision=47920
2010-07-01 11:09:47 +00:00
|
|
|
|
|
|
|
TRACE("(%p): semi-stub\n", hIMC);
|
|
|
|
|
|
|
|
if (!i++)
|
|
|
|
FIXME("(%p): semi-stub\n", hIMC);
|
2005-12-12 20:59:55 +00:00
|
|
|
|
2007-09-14 08:03:04 +00:00
|
|
|
return data->IMC.fOpen;
|
2005-12-12 20:59:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ImmGetProperty (IMM32.@)
|
|
|
|
*/
|
|
|
|
DWORD WINAPI ImmGetProperty(HKL hKL, DWORD fdwIndex)
|
|
|
|
{
|
|
|
|
DWORD rc = 0;
|
2010-03-07 11:27:14 +00:00
|
|
|
ImmHkl *kbd;
|
|
|
|
|
2006-11-26 21:05:00 +00:00
|
|
|
TRACE("(%p, %d)\n", hKL, fdwIndex);
|
2010-03-07 11:27:14 +00:00
|
|
|
kbd = IMM_GetImmHkl(hKL);
|
2005-12-12 20:59:55 +00:00
|
|
|
|
2010-03-07 11:27:14 +00:00
|
|
|
if (kbd && kbd->hIME)
|
2005-12-12 20:59:55 +00:00
|
|
|
{
|
2010-03-07 11:27:14 +00:00
|
|
|
switch (fdwIndex)
|
|
|
|
{
|
|
|
|
case IGP_PROPERTY: rc = kbd->imeInfo.fdwProperty; break;
|
|
|
|
case IGP_CONVERSION: rc = kbd->imeInfo.fdwConversionCaps; break;
|
|
|
|
case IGP_SENTENCE: rc = kbd->imeInfo.fdwSentenceCaps; break;
|
|
|
|
case IGP_SETCOMPSTR: rc = kbd->imeInfo.fdwSCSCaps; break;
|
|
|
|
case IGP_SELECT: rc = kbd->imeInfo.fdwSelectCaps; break;
|
|
|
|
case IGP_GETIMEVERSION: rc = IMEVER_0400; break;
|
|
|
|
case IGP_UI: rc = 0; break;
|
|
|
|
default: rc = 0;
|
|
|
|
}
|
2005-12-12 20:59:55 +00:00
|
|
|
}
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ImmGetRegisterWordStyleA (IMM32.@)
|
|
|
|
*/
|
|
|
|
UINT WINAPI ImmGetRegisterWordStyleA(
|
|
|
|
HKL hKL, UINT nItem, LPSTYLEBUFA lpStyleBuf)
|
|
|
|
{
|
2010-03-07 11:27:14 +00:00
|
|
|
ImmHkl *immHkl = IMM_GetImmHkl(hKL);
|
|
|
|
TRACE("(%p, %d, %p):\n", hKL, nItem, lpStyleBuf);
|
|
|
|
if (immHkl->hIME && immHkl->pImeGetRegisterWordStyle)
|
|
|
|
{
|
|
|
|
if (!is_kbd_ime_unicode(immHkl))
|
|
|
|
return immHkl->pImeGetRegisterWordStyle(nItem,(LPSTYLEBUFW)lpStyleBuf);
|
|
|
|
else
|
|
|
|
{
|
|
|
|
STYLEBUFW sbw;
|
|
|
|
UINT rc;
|
|
|
|
|
|
|
|
rc = immHkl->pImeGetRegisterWordStyle(nItem,&sbw);
|
|
|
|
WideCharToMultiByte(CP_ACP, 0, sbw.szDescription, -1,
|
|
|
|
lpStyleBuf->szDescription, 32, NULL, NULL);
|
|
|
|
lpStyleBuf->dwStyle = sbw.dwStyle;
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
return 0;
|
2005-12-12 20:59:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ImmGetRegisterWordStyleW (IMM32.@)
|
|
|
|
*/
|
|
|
|
UINT WINAPI ImmGetRegisterWordStyleW(
|
|
|
|
HKL hKL, UINT nItem, LPSTYLEBUFW lpStyleBuf)
|
|
|
|
{
|
2010-03-07 11:27:14 +00:00
|
|
|
ImmHkl *immHkl = IMM_GetImmHkl(hKL);
|
|
|
|
TRACE("(%p, %d, %p):\n", hKL, nItem, lpStyleBuf);
|
|
|
|
if (immHkl->hIME && immHkl->pImeGetRegisterWordStyle)
|
|
|
|
{
|
|
|
|
if (is_kbd_ime_unicode(immHkl))
|
|
|
|
return immHkl->pImeGetRegisterWordStyle(nItem,lpStyleBuf);
|
|
|
|
else
|
|
|
|
{
|
|
|
|
STYLEBUFA sba;
|
|
|
|
UINT rc;
|
|
|
|
|
|
|
|
rc = immHkl->pImeGetRegisterWordStyle(nItem,(LPSTYLEBUFW)&sba);
|
|
|
|
MultiByteToWideChar(CP_ACP, 0, sba.szDescription, -1,
|
|
|
|
lpStyleBuf->szDescription, 32);
|
|
|
|
lpStyleBuf->dwStyle = sba.dwStyle;
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
return 0;
|
2005-12-12 20:59:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ImmGetStatusWindowPos (IMM32.@)
|
|
|
|
*/
|
|
|
|
BOOL WINAPI ImmGetStatusWindowPos(HIMC hIMC, LPPOINT lpptPos)
|
|
|
|
{
|
2014-09-28 18:27:58 +00:00
|
|
|
InputContextData *data = get_imc_data(hIMC);
|
2010-03-07 11:27:14 +00:00
|
|
|
|
|
|
|
TRACE("(%p, %p)\n", hIMC, lpptPos);
|
|
|
|
|
|
|
|
if (!data || !lpptPos)
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
*lpptPos = data->IMC.ptStatusWndPos;
|
|
|
|
|
|
|
|
return TRUE;
|
2005-12-12 20:59:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ImmGetVirtualKey (IMM32.@)
|
|
|
|
*/
|
|
|
|
UINT WINAPI ImmGetVirtualKey(HWND hWnd)
|
|
|
|
{
|
|
|
|
OSVERSIONINFOA version;
|
2010-03-07 11:27:14 +00:00
|
|
|
InputContextData *data = ImmGetContext( hWnd );
|
|
|
|
TRACE("%p\n", hWnd);
|
|
|
|
|
|
|
|
if ( data )
|
|
|
|
return data->lastVK;
|
|
|
|
|
2011-12-15 00:40:35 +00:00
|
|
|
version.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA);
|
2005-12-12 20:59:55 +00:00
|
|
|
GetVersionExA( &version );
|
|
|
|
switch(version.dwPlatformId)
|
|
|
|
{
|
|
|
|
case VER_PLATFORM_WIN32_WINDOWS:
|
|
|
|
return VK_PROCESSKEY;
|
|
|
|
case VER_PLATFORM_WIN32_NT:
|
|
|
|
return 0;
|
|
|
|
default:
|
2006-11-26 21:05:00 +00:00
|
|
|
FIXME("%d not supported\n",version.dwPlatformId);
|
2005-12-12 20:59:55 +00:00
|
|
|
return VK_PROCESSKEY;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ImmInstallIMEA (IMM32.@)
|
|
|
|
*/
|
|
|
|
HKL WINAPI ImmInstallIMEA(
|
|
|
|
LPCSTR lpszIMEFileName, LPCSTR lpszLayoutText)
|
|
|
|
{
|
2010-03-07 11:27:14 +00:00
|
|
|
LPWSTR lpszwIMEFileName;
|
|
|
|
LPWSTR lpszwLayoutText;
|
|
|
|
HKL hkl;
|
|
|
|
|
|
|
|
TRACE ("(%s, %s)\n", debugstr_a(lpszIMEFileName),
|
|
|
|
debugstr_a(lpszLayoutText));
|
|
|
|
|
|
|
|
lpszwIMEFileName = strdupAtoW(lpszIMEFileName);
|
|
|
|
lpszwLayoutText = strdupAtoW(lpszLayoutText);
|
|
|
|
|
|
|
|
hkl = ImmInstallIMEW(lpszwIMEFileName, lpszwLayoutText);
|
|
|
|
|
|
|
|
HeapFree(GetProcessHeap(),0,lpszwIMEFileName);
|
|
|
|
HeapFree(GetProcessHeap(),0,lpszwLayoutText);
|
|
|
|
return hkl;
|
2005-12-12 20:59:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ImmInstallIMEW (IMM32.@)
|
|
|
|
*/
|
|
|
|
HKL WINAPI ImmInstallIMEW(
|
|
|
|
LPCWSTR lpszIMEFileName, LPCWSTR lpszLayoutText)
|
|
|
|
{
|
2010-03-07 11:27:14 +00:00
|
|
|
INT lcid = GetUserDefaultLCID();
|
|
|
|
INT count;
|
|
|
|
HKL hkl;
|
|
|
|
DWORD rc;
|
|
|
|
HKEY hkey;
|
|
|
|
WCHAR regKey[sizeof(szImeRegFmt)/sizeof(WCHAR)+8];
|
|
|
|
|
|
|
|
TRACE ("(%s, %s):\n", debugstr_w(lpszIMEFileName),
|
|
|
|
debugstr_w(lpszLayoutText));
|
|
|
|
|
|
|
|
/* Start with 2. e001 will be blank and so default to the wine internal IME */
|
|
|
|
count = 2;
|
|
|
|
|
|
|
|
while (count < 0xfff)
|
|
|
|
{
|
|
|
|
DWORD disposition = 0;
|
|
|
|
|
|
|
|
hkl = (HKL)MAKELPARAM( lcid, 0xe000 | count );
|
|
|
|
wsprintfW( regKey, szImeRegFmt, (ULONG_PTR)hkl);
|
|
|
|
|
|
|
|
rc = RegCreateKeyExW(HKEY_LOCAL_MACHINE, regKey, 0, NULL, 0, KEY_WRITE, NULL, &hkey, &disposition);
|
|
|
|
if (rc == ERROR_SUCCESS && disposition == REG_CREATED_NEW_KEY)
|
|
|
|
break;
|
|
|
|
else if (rc == ERROR_SUCCESS)
|
|
|
|
RegCloseKey(hkey);
|
|
|
|
|
|
|
|
count++;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (count == 0xfff)
|
|
|
|
{
|
|
|
|
WARN("Unable to find slot to install IME\n");
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (rc == ERROR_SUCCESS)
|
|
|
|
{
|
Sync avifil, credui, crypt32, cryptdlg, cryptui, dnsapi, gdiplus, hhctrl, hnetcfg, iccvid, imaadp32, imm32, jscript, localspl, localui, mapi32, mciavi32, mcicda, mciqtz32, mciseq, mciwave, mshtml, msrle32, msvfw32, msvidc32, msxml3, oleacc, oleaut32 to Wine 1.2rc5 (Samuel Serapion, small changes by me)
Remove Esperanto and Walon languages from comctl32, comdlg32, mpr, msi, shlwapi, wininet
svn path=/trunk/; revision=47920
2010-07-01 11:09:47 +00:00
|
|
|
rc = RegSetValueExW(hkey, szImeFileW, 0, REG_SZ, (const BYTE*)lpszIMEFileName,
|
2010-03-07 11:27:14 +00:00
|
|
|
(lstrlenW(lpszIMEFileName) + 1) * sizeof(WCHAR));
|
|
|
|
if (rc == ERROR_SUCCESS)
|
Sync avifil, credui, crypt32, cryptdlg, cryptui, dnsapi, gdiplus, hhctrl, hnetcfg, iccvid, imaadp32, imm32, jscript, localspl, localui, mapi32, mciavi32, mcicda, mciqtz32, mciseq, mciwave, mshtml, msrle32, msvfw32, msvidc32, msxml3, oleacc, oleaut32 to Wine 1.2rc5 (Samuel Serapion, small changes by me)
Remove Esperanto and Walon languages from comctl32, comdlg32, mpr, msi, shlwapi, wininet
svn path=/trunk/; revision=47920
2010-07-01 11:09:47 +00:00
|
|
|
rc = RegSetValueExW(hkey, szLayoutTextW, 0, REG_SZ, (const BYTE*)lpszLayoutText,
|
2010-03-07 11:27:14 +00:00
|
|
|
(lstrlenW(lpszLayoutText) + 1) * sizeof(WCHAR));
|
|
|
|
RegCloseKey(hkey);
|
|
|
|
return hkl;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
WARN("Unable to set IME registry values\n");
|
|
|
|
return 0;
|
|
|
|
}
|
2005-12-12 20:59:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ImmIsIME (IMM32.@)
|
|
|
|
*/
|
|
|
|
BOOL WINAPI ImmIsIME(HKL hKL)
|
|
|
|
{
|
2010-03-07 11:27:14 +00:00
|
|
|
ImmHkl *ptr;
|
|
|
|
TRACE("(%p):\n", hKL);
|
|
|
|
ptr = IMM_GetImmHkl(hKL);
|
|
|
|
return (ptr && ptr->hIME);
|
2005-12-12 20:59:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ImmIsUIMessageA (IMM32.@)
|
|
|
|
*/
|
|
|
|
BOOL WINAPI ImmIsUIMessageA(
|
|
|
|
HWND hWndIME, UINT msg, WPARAM wParam, LPARAM lParam)
|
|
|
|
{
|
2007-09-14 08:03:04 +00:00
|
|
|
TRACE("(%p, %x, %ld, %ld)\n", hWndIME, msg, wParam, lParam);
|
2005-12-12 20:59:55 +00:00
|
|
|
if ((msg >= WM_IME_STARTCOMPOSITION && msg <= WM_IME_KEYLAST) ||
|
2011-12-15 00:40:35 +00:00
|
|
|
(msg == WM_IME_SETCONTEXT) ||
|
|
|
|
(msg == WM_IME_NOTIFY) ||
|
|
|
|
(msg == WM_IME_COMPOSITIONFULL) ||
|
|
|
|
(msg == WM_IME_SELECT) ||
|
2017-12-08 03:14:21 +00:00
|
|
|
(msg == 0x287 /* FIXME: WM_IME_SYSTEM */))
|
2011-12-15 00:40:35 +00:00
|
|
|
{
|
|
|
|
if (hWndIME)
|
|
|
|
SendMessageA(hWndIME, msg, wParam, lParam);
|
2005-12-12 20:59:55 +00:00
|
|
|
|
2017-12-08 03:14:21 +00:00
|
|
|
return TRUE;
|
2005-12-12 20:59:55 +00:00
|
|
|
}
|
2017-12-08 03:14:21 +00:00
|
|
|
return FALSE;
|
2005-12-12 20:59:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ImmIsUIMessageW (IMM32.@)
|
|
|
|
*/
|
|
|
|
BOOL WINAPI ImmIsUIMessageW(
|
|
|
|
HWND hWndIME, UINT msg, WPARAM wParam, LPARAM lParam)
|
|
|
|
{
|
2011-12-15 00:40:35 +00:00
|
|
|
TRACE("(%p, %x, %ld, %ld)\n", hWndIME, msg, wParam, lParam);
|
2005-12-12 20:59:55 +00:00
|
|
|
if ((msg >= WM_IME_STARTCOMPOSITION && msg <= WM_IME_KEYLAST) ||
|
2011-12-15 00:40:35 +00:00
|
|
|
(msg == WM_IME_SETCONTEXT) ||
|
|
|
|
(msg == WM_IME_NOTIFY) ||
|
|
|
|
(msg == WM_IME_COMPOSITIONFULL) ||
|
|
|
|
(msg == WM_IME_SELECT) ||
|
2017-12-08 03:14:21 +00:00
|
|
|
(msg == 0x287 /* FIXME: WM_IME_SYSTEM */))
|
2011-12-15 00:40:35 +00:00
|
|
|
{
|
|
|
|
if (hWndIME)
|
|
|
|
SendMessageW(hWndIME, msg, wParam, lParam);
|
|
|
|
|
2017-12-08 03:14:21 +00:00
|
|
|
return TRUE;
|
2011-12-15 00:40:35 +00:00
|
|
|
}
|
2017-12-08 03:14:21 +00:00
|
|
|
return FALSE;
|
2005-12-12 20:59:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ImmNotifyIME (IMM32.@)
|
|
|
|
*/
|
|
|
|
BOOL WINAPI ImmNotifyIME(
|
|
|
|
HIMC hIMC, DWORD dwAction, DWORD dwIndex, DWORD dwValue)
|
|
|
|
{
|
2014-09-28 18:27:58 +00:00
|
|
|
InputContextData *data = get_imc_data(hIMC);
|
2006-04-16 17:04:45 +00:00
|
|
|
|
2006-11-26 21:05:00 +00:00
|
|
|
TRACE("(%p, %d, %d, %d)\n",
|
2005-12-12 20:59:55 +00:00
|
|
|
hIMC, dwAction, dwIndex, dwValue);
|
|
|
|
|
2014-09-28 18:27:58 +00:00
|
|
|
if (hIMC == NULL)
|
|
|
|
{
|
|
|
|
SetLastError(ERROR_SUCCESS);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2010-03-07 11:27:14 +00:00
|
|
|
if (!data || ! data->immKbd->pNotifyIME)
|
2014-09-28 18:27:58 +00:00
|
|
|
{
|
2010-03-07 11:27:14 +00:00
|
|
|
return FALSE;
|
2014-09-28 18:27:58 +00:00
|
|
|
}
|
2007-09-14 08:03:04 +00:00
|
|
|
|
2010-03-07 11:27:14 +00:00
|
|
|
return data->immKbd->pNotifyIME(hIMC,dwAction,dwIndex,dwValue);
|
2005-12-12 20:59:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ImmRegisterWordA (IMM32.@)
|
|
|
|
*/
|
|
|
|
BOOL WINAPI ImmRegisterWordA(
|
|
|
|
HKL hKL, LPCSTR lpszReading, DWORD dwStyle, LPCSTR lpszRegister)
|
|
|
|
{
|
2010-03-07 11:27:14 +00:00
|
|
|
ImmHkl *immHkl = IMM_GetImmHkl(hKL);
|
|
|
|
TRACE("(%p, %s, %d, %s):\n", hKL, debugstr_a(lpszReading), dwStyle,
|
|
|
|
debugstr_a(lpszRegister));
|
|
|
|
if (immHkl->hIME && immHkl->pImeRegisterWord)
|
|
|
|
{
|
|
|
|
if (!is_kbd_ime_unicode(immHkl))
|
|
|
|
return immHkl->pImeRegisterWord((LPCWSTR)lpszReading,dwStyle,
|
|
|
|
(LPCWSTR)lpszRegister);
|
|
|
|
else
|
|
|
|
{
|
|
|
|
LPWSTR lpszwReading = strdupAtoW(lpszReading);
|
|
|
|
LPWSTR lpszwRegister = strdupAtoW(lpszRegister);
|
|
|
|
BOOL rc;
|
|
|
|
|
|
|
|
rc = immHkl->pImeRegisterWord(lpszwReading,dwStyle,lpszwRegister);
|
|
|
|
HeapFree(GetProcessHeap(),0,lpszwReading);
|
|
|
|
HeapFree(GetProcessHeap(),0,lpszwRegister);
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
return FALSE;
|
2005-12-12 20:59:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ImmRegisterWordW (IMM32.@)
|
|
|
|
*/
|
|
|
|
BOOL WINAPI ImmRegisterWordW(
|
|
|
|
HKL hKL, LPCWSTR lpszReading, DWORD dwStyle, LPCWSTR lpszRegister)
|
|
|
|
{
|
2010-03-07 11:27:14 +00:00
|
|
|
ImmHkl *immHkl = IMM_GetImmHkl(hKL);
|
|
|
|
TRACE("(%p, %s, %d, %s):\n", hKL, debugstr_w(lpszReading), dwStyle,
|
|
|
|
debugstr_w(lpszRegister));
|
|
|
|
if (immHkl->hIME && immHkl->pImeRegisterWord)
|
|
|
|
{
|
|
|
|
if (is_kbd_ime_unicode(immHkl))
|
|
|
|
return immHkl->pImeRegisterWord(lpszReading,dwStyle,lpszRegister);
|
|
|
|
else
|
|
|
|
{
|
|
|
|
LPSTR lpszaReading = strdupWtoA(lpszReading);
|
|
|
|
LPSTR lpszaRegister = strdupWtoA(lpszRegister);
|
|
|
|
BOOL rc;
|
|
|
|
|
|
|
|
rc = immHkl->pImeRegisterWord((LPCWSTR)lpszaReading,dwStyle,
|
|
|
|
(LPCWSTR)lpszaRegister);
|
|
|
|
HeapFree(GetProcessHeap(),0,lpszaReading);
|
|
|
|
HeapFree(GetProcessHeap(),0,lpszaRegister);
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
return FALSE;
|
2005-12-12 20:59:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
2008-05-08 16:03:10 +00:00
|
|
|
* ImmReleaseContext (IMM32.@)
|
|
|
|
*/
|
|
|
|
BOOL WINAPI ImmReleaseContext(HWND hWnd, HIMC hIMC)
|
2005-12-12 20:59:55 +00:00
|
|
|
{
|
2014-09-28 18:27:58 +00:00
|
|
|
static BOOL shown = FALSE;
|
2010-03-07 11:27:14 +00:00
|
|
|
|
|
|
|
if (!shown) {
|
|
|
|
FIXME("(%p, %p): stub\n", hWnd, hIMC);
|
2014-09-28 18:27:58 +00:00
|
|
|
shown = TRUE;
|
2010-03-07 11:27:14 +00:00
|
|
|
}
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ImmRequestMessageA(IMM32.@)
|
|
|
|
*/
|
|
|
|
LRESULT WINAPI ImmRequestMessageA(HIMC hIMC, WPARAM wParam, LPARAM lParam)
|
|
|
|
{
|
2014-09-28 18:27:58 +00:00
|
|
|
InputContextData *data = get_imc_data(hIMC);
|
2010-03-07 11:27:14 +00:00
|
|
|
|
|
|
|
TRACE("%p %ld %ld\n", hIMC, wParam, wParam);
|
|
|
|
|
2017-12-08 03:14:21 +00:00
|
|
|
if (data) return SendMessageA(data->IMC.hWnd, WM_IME_REQUEST, wParam, lParam);
|
2010-03-07 11:27:14 +00:00
|
|
|
|
2017-12-08 03:14:21 +00:00
|
|
|
SetLastError(ERROR_INVALID_HANDLE);
|
|
|
|
return 0;
|
2010-03-07 11:27:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ImmRequestMessageW(IMM32.@)
|
|
|
|
*/
|
|
|
|
LRESULT WINAPI ImmRequestMessageW(HIMC hIMC, WPARAM wParam, LPARAM lParam)
|
|
|
|
{
|
2014-09-28 18:27:58 +00:00
|
|
|
InputContextData *data = get_imc_data(hIMC);
|
2008-05-06 09:16:21 +00:00
|
|
|
|
2010-03-07 11:27:14 +00:00
|
|
|
TRACE("%p %ld %ld\n", hIMC, wParam, wParam);
|
|
|
|
|
2017-12-08 03:14:21 +00:00
|
|
|
if (data) return SendMessageW(data->IMC.hWnd, WM_IME_REQUEST, wParam, lParam);
|
2010-03-07 11:27:14 +00:00
|
|
|
|
2017-12-08 03:14:21 +00:00
|
|
|
SetLastError(ERROR_INVALID_HANDLE);
|
|
|
|
return 0;
|
2005-12-12 20:59:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ImmSetCandidateWindow (IMM32.@)
|
|
|
|
*/
|
|
|
|
BOOL WINAPI ImmSetCandidateWindow(
|
|
|
|
HIMC hIMC, LPCANDIDATEFORM lpCandidate)
|
|
|
|
{
|
2014-09-28 18:27:58 +00:00
|
|
|
InputContextData *data = get_imc_data(hIMC);
|
2010-03-07 11:27:14 +00:00
|
|
|
|
|
|
|
TRACE("(%p, %p)\n", hIMC, lpCandidate);
|
|
|
|
|
|
|
|
if (!data || !lpCandidate)
|
|
|
|
return FALSE;
|
|
|
|
|
2017-12-08 03:14:21 +00:00
|
|
|
if (IMM_IsCrossThreadAccess(NULL, hIMC))
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
TRACE("\t%x, %x, %s, %s\n",
|
|
|
|
lpCandidate->dwIndex, lpCandidate->dwStyle,
|
|
|
|
wine_dbgstr_point(&lpCandidate->ptCurrentPos),
|
|
|
|
wine_dbgstr_rect(&lpCandidate->rcArea));
|
2010-03-07 11:27:14 +00:00
|
|
|
|
|
|
|
if ( lpCandidate->dwIndex >= (sizeof(data->IMC.cfCandForm) / sizeof(CANDIDATEFORM)) )
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
data->IMC.cfCandForm[lpCandidate->dwIndex] = *lpCandidate;
|
|
|
|
ImmNotifyIME(hIMC, NI_CONTEXTUPDATED, 0, IMC_SETCANDIDATEPOS);
|
|
|
|
ImmInternalSendIMENotify(data, IMN_SETCANDIDATEPOS, 1 << lpCandidate->dwIndex);
|
|
|
|
|
|
|
|
return TRUE;
|
2005-12-12 20:59:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ImmSetCompositionFontA (IMM32.@)
|
|
|
|
*/
|
|
|
|
BOOL WINAPI ImmSetCompositionFontA(HIMC hIMC, LPLOGFONTA lplf)
|
|
|
|
{
|
2014-09-28 18:27:58 +00:00
|
|
|
InputContextData *data = get_imc_data(hIMC);
|
2005-12-12 20:59:55 +00:00
|
|
|
TRACE("(%p, %p)\n", hIMC, lplf);
|
|
|
|
|
2010-03-07 11:27:14 +00:00
|
|
|
if (!data || !lplf)
|
2014-09-28 18:27:58 +00:00
|
|
|
{
|
|
|
|
SetLastError(ERROR_INVALID_HANDLE);
|
2005-12-12 20:59:55 +00:00
|
|
|
return FALSE;
|
2014-09-28 18:27:58 +00:00
|
|
|
}
|
2005-12-12 20:59:55 +00:00
|
|
|
|
2017-12-08 03:14:21 +00:00
|
|
|
if (IMM_IsCrossThreadAccess(NULL, hIMC))
|
|
|
|
return FALSE;
|
|
|
|
|
2007-09-14 08:03:04 +00:00
|
|
|
memcpy(&data->IMC.lfFont.W,lplf,sizeof(LOGFONTA));
|
|
|
|
MultiByteToWideChar(CP_ACP, 0, lplf->lfFaceName, -1, data->IMC.lfFont.W.lfFaceName,
|
2005-12-12 20:59:55 +00:00
|
|
|
LF_FACESIZE);
|
2010-03-07 11:27:14 +00:00
|
|
|
ImmNotifyIME(hIMC, NI_CONTEXTUPDATED, 0, IMC_SETCOMPOSITIONFONT);
|
2008-04-04 13:20:27 +00:00
|
|
|
ImmInternalSendIMENotify(data, IMN_SETCOMPOSITIONFONT, 0);
|
2005-12-12 20:59:55 +00:00
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ImmSetCompositionFontW (IMM32.@)
|
|
|
|
*/
|
|
|
|
BOOL WINAPI ImmSetCompositionFontW(HIMC hIMC, LPLOGFONTW lplf)
|
|
|
|
{
|
2014-09-28 18:27:58 +00:00
|
|
|
InputContextData *data = get_imc_data(hIMC);
|
2005-12-12 20:59:55 +00:00
|
|
|
TRACE("(%p, %p)\n", hIMC, lplf);
|
|
|
|
|
2010-03-07 11:27:14 +00:00
|
|
|
if (!data || !lplf)
|
2014-09-28 18:27:58 +00:00
|
|
|
{
|
|
|
|
SetLastError(ERROR_INVALID_HANDLE);
|
2005-12-12 20:59:55 +00:00
|
|
|
return FALSE;
|
2014-09-28 18:27:58 +00:00
|
|
|
}
|
2005-12-12 20:59:55 +00:00
|
|
|
|
2017-12-08 03:14:21 +00:00
|
|
|
if (IMM_IsCrossThreadAccess(NULL, hIMC))
|
|
|
|
return FALSE;
|
|
|
|
|
2008-04-04 13:20:27 +00:00
|
|
|
data->IMC.lfFont.W = *lplf;
|
2010-03-07 11:27:14 +00:00
|
|
|
ImmNotifyIME(hIMC, NI_CONTEXTUPDATED, 0, IMC_SETCOMPOSITIONFONT);
|
2008-04-04 13:20:27 +00:00
|
|
|
ImmInternalSendIMENotify(data, IMN_SETCOMPOSITIONFONT, 0);
|
2005-12-12 20:59:55 +00:00
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ImmSetCompositionStringA (IMM32.@)
|
|
|
|
*/
|
|
|
|
BOOL WINAPI ImmSetCompositionStringA(
|
|
|
|
HIMC hIMC, DWORD dwIndex,
|
|
|
|
LPCVOID lpComp, DWORD dwCompLen,
|
|
|
|
LPCVOID lpRead, DWORD dwReadLen)
|
|
|
|
{
|
|
|
|
DWORD comp_len;
|
|
|
|
DWORD read_len;
|
|
|
|
WCHAR *CompBuffer = NULL;
|
|
|
|
WCHAR *ReadBuffer = NULL;
|
|
|
|
BOOL rc;
|
2014-09-28 18:27:58 +00:00
|
|
|
InputContextData *data = get_imc_data(hIMC);
|
2005-12-12 20:59:55 +00:00
|
|
|
|
2010-03-07 11:27:14 +00:00
|
|
|
TRACE("(%p, %d, %p, %d, %p, %d):\n",
|
2005-12-12 20:59:55 +00:00
|
|
|
hIMC, dwIndex, lpComp, dwCompLen, lpRead, dwReadLen);
|
|
|
|
|
2010-03-07 11:27:14 +00:00
|
|
|
if (!data)
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
if (!(dwIndex == SCS_SETSTR ||
|
|
|
|
dwIndex == SCS_CHANGEATTR ||
|
|
|
|
dwIndex == SCS_CHANGECLAUSE ||
|
|
|
|
dwIndex == SCS_SETRECONVERTSTRING ||
|
|
|
|
dwIndex == SCS_QUERYRECONVERTSTRING))
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
if (!is_himc_ime_unicode(data))
|
|
|
|
return data->immKbd->pImeSetCompositionString(hIMC, dwIndex, lpComp,
|
|
|
|
dwCompLen, lpRead, dwReadLen);
|
|
|
|
|
2005-12-12 20:59:55 +00:00
|
|
|
comp_len = MultiByteToWideChar(CP_ACP, 0, lpComp, dwCompLen, NULL, 0);
|
|
|
|
if (comp_len)
|
|
|
|
{
|
|
|
|
CompBuffer = HeapAlloc(GetProcessHeap(),0,comp_len * sizeof(WCHAR));
|
|
|
|
MultiByteToWideChar(CP_ACP, 0, lpComp, dwCompLen, CompBuffer, comp_len);
|
|
|
|
}
|
|
|
|
|
|
|
|
read_len = MultiByteToWideChar(CP_ACP, 0, lpRead, dwReadLen, NULL, 0);
|
|
|
|
if (read_len)
|
|
|
|
{
|
|
|
|
ReadBuffer = HeapAlloc(GetProcessHeap(),0,read_len * sizeof(WCHAR));
|
|
|
|
MultiByteToWideChar(CP_ACP, 0, lpRead, dwReadLen, ReadBuffer, read_len);
|
|
|
|
}
|
|
|
|
|
|
|
|
rc = ImmSetCompositionStringW(hIMC, dwIndex, CompBuffer, comp_len,
|
|
|
|
ReadBuffer, read_len);
|
|
|
|
|
|
|
|
HeapFree(GetProcessHeap(), 0, CompBuffer);
|
|
|
|
HeapFree(GetProcessHeap(), 0, ReadBuffer);
|
|
|
|
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ImmSetCompositionStringW (IMM32.@)
|
|
|
|
*/
|
|
|
|
BOOL WINAPI ImmSetCompositionStringW(
|
|
|
|
HIMC hIMC, DWORD dwIndex,
|
|
|
|
LPCVOID lpComp, DWORD dwCompLen,
|
|
|
|
LPCVOID lpRead, DWORD dwReadLen)
|
|
|
|
{
|
2010-03-07 11:27:14 +00:00
|
|
|
DWORD comp_len;
|
|
|
|
DWORD read_len;
|
|
|
|
CHAR *CompBuffer = NULL;
|
|
|
|
CHAR *ReadBuffer = NULL;
|
|
|
|
BOOL rc;
|
2014-09-28 18:27:58 +00:00
|
|
|
InputContextData *data = get_imc_data(hIMC);
|
2005-12-12 20:59:55 +00:00
|
|
|
|
2010-03-07 11:27:14 +00:00
|
|
|
TRACE("(%p, %d, %p, %d, %p, %d):\n",
|
|
|
|
hIMC, dwIndex, lpComp, dwCompLen, lpRead, dwReadLen);
|
2005-12-12 20:59:55 +00:00
|
|
|
|
2010-03-07 11:27:14 +00:00
|
|
|
if (!data)
|
|
|
|
return FALSE;
|
2005-12-12 20:59:55 +00:00
|
|
|
|
2010-03-07 11:27:14 +00:00
|
|
|
if (!(dwIndex == SCS_SETSTR ||
|
|
|
|
dwIndex == SCS_CHANGEATTR ||
|
|
|
|
dwIndex == SCS_CHANGECLAUSE ||
|
|
|
|
dwIndex == SCS_SETRECONVERTSTRING ||
|
|
|
|
dwIndex == SCS_QUERYRECONVERTSTRING))
|
|
|
|
return FALSE;
|
2008-05-08 16:03:10 +00:00
|
|
|
|
2010-03-07 11:27:14 +00:00
|
|
|
if (is_himc_ime_unicode(data))
|
|
|
|
return data->immKbd->pImeSetCompositionString(hIMC, dwIndex, lpComp,
|
|
|
|
dwCompLen, lpRead, dwReadLen);
|
2008-05-08 16:03:10 +00:00
|
|
|
|
2010-03-07 11:27:14 +00:00
|
|
|
comp_len = WideCharToMultiByte(CP_ACP, 0, lpComp, dwCompLen, NULL, 0, NULL,
|
|
|
|
NULL);
|
|
|
|
if (comp_len)
|
2008-05-06 09:16:21 +00:00
|
|
|
{
|
2010-03-07 11:27:14 +00:00
|
|
|
CompBuffer = HeapAlloc(GetProcessHeap(),0,comp_len);
|
|
|
|
WideCharToMultiByte(CP_ACP, 0, lpComp, dwCompLen, CompBuffer, comp_len,
|
|
|
|
NULL, NULL);
|
|
|
|
}
|
2008-05-08 16:03:10 +00:00
|
|
|
|
2010-03-07 11:27:14 +00:00
|
|
|
read_len = WideCharToMultiByte(CP_ACP, 0, lpRead, dwReadLen, NULL, 0, NULL,
|
|
|
|
NULL);
|
|
|
|
if (read_len)
|
|
|
|
{
|
|
|
|
ReadBuffer = HeapAlloc(GetProcessHeap(),0,read_len);
|
|
|
|
WideCharToMultiByte(CP_ACP, 0, lpRead, dwReadLen, ReadBuffer, read_len,
|
|
|
|
NULL, NULL);
|
2005-12-12 20:59:55 +00:00
|
|
|
}
|
|
|
|
|
2010-03-07 11:27:14 +00:00
|
|
|
rc = ImmSetCompositionStringA(hIMC, dwIndex, CompBuffer, comp_len,
|
|
|
|
ReadBuffer, read_len);
|
2005-12-12 20:59:55 +00:00
|
|
|
|
2010-03-07 11:27:14 +00:00
|
|
|
HeapFree(GetProcessHeap(), 0, CompBuffer);
|
|
|
|
HeapFree(GetProcessHeap(), 0, ReadBuffer);
|
2005-12-12 20:59:55 +00:00
|
|
|
|
2010-03-07 11:27:14 +00:00
|
|
|
return rc;
|
2005-12-12 20:59:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ImmSetCompositionWindow (IMM32.@)
|
|
|
|
*/
|
|
|
|
BOOL WINAPI ImmSetCompositionWindow(
|
|
|
|
HIMC hIMC, LPCOMPOSITIONFORM lpCompForm)
|
|
|
|
{
|
|
|
|
BOOL reshow = FALSE;
|
2014-09-28 18:27:58 +00:00
|
|
|
InputContextData *data = get_imc_data(hIMC);
|
2005-12-12 20:59:55 +00:00
|
|
|
|
|
|
|
TRACE("(%p, %p)\n", hIMC, lpCompForm);
|
2017-12-08 03:14:21 +00:00
|
|
|
if (lpCompForm)
|
|
|
|
TRACE("\t%x, %s, %s\n", lpCompForm->dwStyle,
|
|
|
|
wine_dbgstr_point(&lpCompForm->ptCurrentPos),
|
|
|
|
wine_dbgstr_rect(&lpCompForm->rcArea));
|
2005-12-12 20:59:55 +00:00
|
|
|
|
|
|
|
if (!data)
|
2014-09-28 18:27:58 +00:00
|
|
|
{
|
|
|
|
SetLastError(ERROR_INVALID_HANDLE);
|
2005-12-12 20:59:55 +00:00
|
|
|
return FALSE;
|
2014-09-28 18:27:58 +00:00
|
|
|
}
|
2005-12-12 20:59:55 +00:00
|
|
|
|
2017-12-08 03:14:21 +00:00
|
|
|
if (IMM_IsCrossThreadAccess(NULL, hIMC))
|
|
|
|
return FALSE;
|
|
|
|
|
2008-04-04 13:20:27 +00:00
|
|
|
data->IMC.cfCompForm = *lpCompForm;
|
2005-12-12 20:59:55 +00:00
|
|
|
|
2013-02-03 20:58:12 +00:00
|
|
|
if (IsWindowVisible(data->immKbd->UIWnd))
|
2005-12-12 20:59:55 +00:00
|
|
|
{
|
|
|
|
reshow = TRUE;
|
2013-02-03 20:58:12 +00:00
|
|
|
ShowWindow(data->immKbd->UIWnd,SW_HIDE);
|
2005-12-12 20:59:55 +00:00
|
|
|
}
|
|
|
|
|
2006-04-16 17:04:45 +00:00
|
|
|
/* FIXME: this is a partial stub */
|
2005-12-12 20:59:55 +00:00
|
|
|
|
|
|
|
if (reshow)
|
2013-02-03 20:58:12 +00:00
|
|
|
ShowWindow(data->immKbd->UIWnd,SW_SHOWNOACTIVATE);
|
2005-12-12 20:59:55 +00:00
|
|
|
|
2008-04-04 13:20:27 +00:00
|
|
|
ImmInternalSendIMENotify(data, IMN_SETCOMPOSITIONWINDOW, 0);
|
2005-12-12 20:59:55 +00:00
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ImmSetConversionStatus (IMM32.@)
|
|
|
|
*/
|
|
|
|
BOOL WINAPI ImmSetConversionStatus(
|
|
|
|
HIMC hIMC, DWORD fdwConversion, DWORD fdwSentence)
|
|
|
|
{
|
2010-03-07 11:27:14 +00:00
|
|
|
DWORD oldConversion, oldSentence;
|
2014-09-28 18:27:58 +00:00
|
|
|
InputContextData *data = get_imc_data(hIMC);
|
2008-05-06 09:16:21 +00:00
|
|
|
|
2010-03-07 11:27:14 +00:00
|
|
|
TRACE("%p %d %d\n", hIMC, fdwConversion, fdwSentence);
|
|
|
|
|
|
|
|
if (!data)
|
2014-09-28 18:27:58 +00:00
|
|
|
{
|
|
|
|
SetLastError(ERROR_INVALID_HANDLE);
|
2010-03-07 11:27:14 +00:00
|
|
|
return FALSE;
|
2014-09-28 18:27:58 +00:00
|
|
|
}
|
2010-03-07 11:27:14 +00:00
|
|
|
|
2017-12-08 03:14:21 +00:00
|
|
|
if (IMM_IsCrossThreadAccess(NULL, hIMC))
|
|
|
|
return FALSE;
|
|
|
|
|
2010-03-07 11:27:14 +00:00
|
|
|
if ( fdwConversion != data->IMC.fdwConversion )
|
|
|
|
{
|
|
|
|
oldConversion = data->IMC.fdwConversion;
|
|
|
|
data->IMC.fdwConversion = fdwConversion;
|
|
|
|
ImmNotifyIME(hIMC, NI_CONTEXTUPDATED, oldConversion, IMC_SETCONVERSIONMODE);
|
|
|
|
ImmInternalSendIMENotify(data, IMN_SETCONVERSIONMODE, 0);
|
|
|
|
}
|
|
|
|
if ( fdwSentence != data->IMC.fdwSentence )
|
|
|
|
{
|
|
|
|
oldSentence = data->IMC.fdwSentence;
|
|
|
|
data->IMC.fdwSentence = fdwSentence;
|
|
|
|
ImmNotifyIME(hIMC, NI_CONTEXTUPDATED, oldSentence, IMC_SETSENTENCEMODE);
|
|
|
|
ImmInternalSendIMENotify(data, IMN_SETSENTENCEMODE, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
return TRUE;
|
2005-12-12 20:59:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ImmSetOpenStatus (IMM32.@)
|
|
|
|
*/
|
|
|
|
BOOL WINAPI ImmSetOpenStatus(HIMC hIMC, BOOL fOpen)
|
|
|
|
{
|
2014-09-28 18:27:58 +00:00
|
|
|
InputContextData *data = get_imc_data(hIMC);
|
2006-04-16 17:04:45 +00:00
|
|
|
|
|
|
|
TRACE("%p %d\n", hIMC, fOpen);
|
2005-12-12 20:59:55 +00:00
|
|
|
|
2008-05-08 16:03:10 +00:00
|
|
|
if (!data)
|
2014-09-28 18:27:58 +00:00
|
|
|
{
|
|
|
|
SetLastError(ERROR_INVALID_HANDLE);
|
2008-05-08 16:03:10 +00:00
|
|
|
return FALSE;
|
2014-09-28 18:27:58 +00:00
|
|
|
}
|
2008-05-08 16:03:10 +00:00
|
|
|
|
2017-12-08 03:14:21 +00:00
|
|
|
if (IMM_IsCrossThreadAccess(NULL, hIMC))
|
|
|
|
return FALSE;
|
|
|
|
|
2013-02-03 20:58:12 +00:00
|
|
|
if (data->immKbd->UIWnd == NULL)
|
2008-05-06 09:16:21 +00:00
|
|
|
{
|
2010-03-07 11:27:14 +00:00
|
|
|
/* create the ime window */
|
2013-02-03 20:58:12 +00:00
|
|
|
data->immKbd->UIWnd = CreateWindowExW( WS_EX_TOOLWINDOW,
|
2010-03-07 11:27:14 +00:00
|
|
|
data->immKbd->imeClassName, NULL, WS_POPUP, 0, 0, 1, 1, 0,
|
|
|
|
0, data->immKbd->hIME, 0);
|
2013-02-03 20:58:12 +00:00
|
|
|
SetWindowLongPtrW(data->immKbd->UIWnd, IMMGWL_IMC, (LONG_PTR)data);
|
2010-03-07 11:27:14 +00:00
|
|
|
}
|
2013-02-03 20:58:12 +00:00
|
|
|
else if (fOpen)
|
|
|
|
SetWindowLongPtrW(data->immKbd->UIWnd, IMMGWL_IMC, (LONG_PTR)data);
|
2005-12-12 20:59:55 +00:00
|
|
|
|
2010-03-07 11:27:14 +00:00
|
|
|
if (!fOpen != !data->IMC.fOpen)
|
|
|
|
{
|
|
|
|
data->IMC.fOpen = fOpen;
|
|
|
|
ImmNotifyIME( hIMC, NI_CONTEXTUPDATED, 0, IMC_SETOPENSTATUS);
|
|
|
|
ImmInternalSendIMENotify(data, IMN_SETOPENSTATUS, 0);
|
|
|
|
}
|
2005-12-12 20:59:55 +00:00
|
|
|
|
2010-03-07 11:27:14 +00:00
|
|
|
return TRUE;
|
|
|
|
}
|
2005-12-12 20:59:55 +00:00
|
|
|
|
2010-03-07 11:27:14 +00:00
|
|
|
/***********************************************************************
|
|
|
|
* ImmSetStatusWindowPos (IMM32.@)
|
|
|
|
*/
|
|
|
|
BOOL WINAPI ImmSetStatusWindowPos(HIMC hIMC, LPPOINT lpptPos)
|
|
|
|
{
|
2014-09-28 18:27:58 +00:00
|
|
|
InputContextData *data = get_imc_data(hIMC);
|
2010-03-07 11:27:14 +00:00
|
|
|
|
|
|
|
TRACE("(%p, %p)\n", hIMC, lpptPos);
|
2008-05-06 09:16:21 +00:00
|
|
|
|
2010-03-07 11:27:14 +00:00
|
|
|
if (!data || !lpptPos)
|
2014-09-28 18:27:58 +00:00
|
|
|
{
|
|
|
|
SetLastError(ERROR_INVALID_HANDLE);
|
2005-12-12 20:59:55 +00:00
|
|
|
return FALSE;
|
2014-09-28 18:27:58 +00:00
|
|
|
}
|
2010-03-07 11:27:14 +00:00
|
|
|
|
2017-12-08 03:14:21 +00:00
|
|
|
if (IMM_IsCrossThreadAccess(NULL, hIMC))
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
TRACE("\t%s\n", wine_dbgstr_point(lpptPos));
|
2010-03-07 11:27:14 +00:00
|
|
|
|
|
|
|
data->IMC.ptStatusWndPos = *lpptPos;
|
|
|
|
ImmNotifyIME( hIMC, NI_CONTEXTUPDATED, 0, IMC_SETSTATUSWINDOWPOS);
|
|
|
|
ImmInternalSendIMENotify(data, IMN_SETSTATUSWINDOWPOS, 0);
|
|
|
|
|
2005-12-12 20:59:55 +00:00
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
2010-03-07 11:27:14 +00:00
|
|
|
* ImmCreateSoftKeyboard(IMM32.@)
|
2008-05-06 09:16:21 +00:00
|
|
|
*/
|
2010-03-07 11:27:14 +00:00
|
|
|
HWND WINAPI ImmCreateSoftKeyboard(UINT uType, UINT hOwner, int x, int y)
|
2008-05-06 09:16:21 +00:00
|
|
|
{
|
2010-03-07 11:27:14 +00:00
|
|
|
FIXME("(%d, %d, %d, %d): stub\n", uType, hOwner, x, y);
|
|
|
|
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ImmDestroySoftKeyboard(IMM32.@)
|
|
|
|
*/
|
|
|
|
BOOL WINAPI ImmDestroySoftKeyboard(HWND hSoftWnd)
|
|
|
|
{
|
|
|
|
FIXME("(%p): stub\n", hSoftWnd);
|
|
|
|
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ImmShowSoftKeyboard(IMM32.@)
|
|
|
|
*/
|
|
|
|
BOOL WINAPI ImmShowSoftKeyboard(HWND hSoftWnd, int nCmdShow)
|
|
|
|
{
|
|
|
|
FIXME("(%p, %d): stub\n", hSoftWnd, nCmdShow);
|
|
|
|
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
|
|
|
return FALSE;
|
2005-12-12 20:59:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ImmSimulateHotKey (IMM32.@)
|
|
|
|
*/
|
|
|
|
BOOL WINAPI ImmSimulateHotKey(HWND hWnd, DWORD dwHotKeyID)
|
|
|
|
{
|
2006-11-26 21:05:00 +00:00
|
|
|
FIXME("(%p, %d): stub\n", hWnd, dwHotKeyID);
|
2005-12-12 20:59:55 +00:00
|
|
|
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ImmUnregisterWordA (IMM32.@)
|
|
|
|
*/
|
|
|
|
BOOL WINAPI ImmUnregisterWordA(
|
|
|
|
HKL hKL, LPCSTR lpszReading, DWORD dwStyle, LPCSTR lpszUnregister)
|
|
|
|
{
|
2010-03-07 11:27:14 +00:00
|
|
|
ImmHkl *immHkl = IMM_GetImmHkl(hKL);
|
|
|
|
TRACE("(%p, %s, %d, %s):\n", hKL, debugstr_a(lpszReading), dwStyle,
|
|
|
|
debugstr_a(lpszUnregister));
|
|
|
|
if (immHkl->hIME && immHkl->pImeUnregisterWord)
|
|
|
|
{
|
|
|
|
if (!is_kbd_ime_unicode(immHkl))
|
|
|
|
return immHkl->pImeUnregisterWord((LPCWSTR)lpszReading,dwStyle,
|
|
|
|
(LPCWSTR)lpszUnregister);
|
|
|
|
else
|
|
|
|
{
|
|
|
|
LPWSTR lpszwReading = strdupAtoW(lpszReading);
|
|
|
|
LPWSTR lpszwUnregister = strdupAtoW(lpszUnregister);
|
|
|
|
BOOL rc;
|
|
|
|
|
|
|
|
rc = immHkl->pImeUnregisterWord(lpszwReading,dwStyle,lpszwUnregister);
|
|
|
|
HeapFree(GetProcessHeap(),0,lpszwReading);
|
|
|
|
HeapFree(GetProcessHeap(),0,lpszwUnregister);
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
return FALSE;
|
2005-12-12 20:59:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ImmUnregisterWordW (IMM32.@)
|
|
|
|
*/
|
|
|
|
BOOL WINAPI ImmUnregisterWordW(
|
|
|
|
HKL hKL, LPCWSTR lpszReading, DWORD dwStyle, LPCWSTR lpszUnregister)
|
|
|
|
{
|
2010-03-07 11:27:14 +00:00
|
|
|
ImmHkl *immHkl = IMM_GetImmHkl(hKL);
|
|
|
|
TRACE("(%p, %s, %d, %s):\n", hKL, debugstr_w(lpszReading), dwStyle,
|
|
|
|
debugstr_w(lpszUnregister));
|
|
|
|
if (immHkl->hIME && immHkl->pImeUnregisterWord)
|
|
|
|
{
|
|
|
|
if (is_kbd_ime_unicode(immHkl))
|
|
|
|
return immHkl->pImeUnregisterWord(lpszReading,dwStyle,lpszUnregister);
|
|
|
|
else
|
|
|
|
{
|
|
|
|
LPSTR lpszaReading = strdupWtoA(lpszReading);
|
|
|
|
LPSTR lpszaUnregister = strdupWtoA(lpszUnregister);
|
|
|
|
BOOL rc;
|
|
|
|
|
|
|
|
rc = immHkl->pImeUnregisterWord((LPCWSTR)lpszaReading,dwStyle,
|
|
|
|
(LPCWSTR)lpszaUnregister);
|
|
|
|
HeapFree(GetProcessHeap(),0,lpszaReading);
|
|
|
|
HeapFree(GetProcessHeap(),0,lpszaUnregister);
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
return FALSE;
|
2005-12-12 20:59:55 +00:00
|
|
|
}
|
|
|
|
|
2007-03-14 14:34:47 +00:00
|
|
|
/***********************************************************************
|
|
|
|
* ImmGetImeMenuItemsA (IMM32.@)
|
|
|
|
*/
|
|
|
|
DWORD WINAPI ImmGetImeMenuItemsA( HIMC hIMC, DWORD dwFlags, DWORD dwType,
|
|
|
|
LPIMEMENUITEMINFOA lpImeParentMenu, LPIMEMENUITEMINFOA lpImeMenu,
|
|
|
|
DWORD dwSize)
|
|
|
|
{
|
2014-09-28 18:27:58 +00:00
|
|
|
InputContextData *data = get_imc_data(hIMC);
|
2010-03-07 11:27:14 +00:00
|
|
|
TRACE("(%p, %i, %i, %p, %p, %i):\n", hIMC, dwFlags, dwType,
|
|
|
|
lpImeParentMenu, lpImeMenu, dwSize);
|
2014-09-28 18:27:58 +00:00
|
|
|
|
|
|
|
if (!data)
|
|
|
|
{
|
|
|
|
SetLastError(ERROR_INVALID_HANDLE);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2010-03-07 11:27:14 +00:00
|
|
|
if (data->immKbd->hIME && data->immKbd->pImeGetImeMenuItems)
|
|
|
|
{
|
|
|
|
if (!is_himc_ime_unicode(data) || (!lpImeParentMenu && !lpImeMenu))
|
|
|
|
return data->immKbd->pImeGetImeMenuItems(hIMC, dwFlags, dwType,
|
|
|
|
(IMEMENUITEMINFOW*)lpImeParentMenu,
|
|
|
|
(IMEMENUITEMINFOW*)lpImeMenu, dwSize);
|
|
|
|
else
|
|
|
|
{
|
|
|
|
IMEMENUITEMINFOW lpImeParentMenuW;
|
|
|
|
IMEMENUITEMINFOW *lpImeMenuW, *parent = NULL;
|
|
|
|
DWORD rc;
|
|
|
|
|
|
|
|
if (lpImeParentMenu)
|
|
|
|
parent = &lpImeParentMenuW;
|
|
|
|
if (lpImeMenu)
|
|
|
|
{
|
|
|
|
int count = dwSize / sizeof(LPIMEMENUITEMINFOA);
|
|
|
|
dwSize = count * sizeof(IMEMENUITEMINFOW);
|
|
|
|
lpImeMenuW = HeapAlloc(GetProcessHeap(), 0, dwSize);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
lpImeMenuW = NULL;
|
|
|
|
|
|
|
|
rc = data->immKbd->pImeGetImeMenuItems(hIMC, dwFlags, dwType,
|
|
|
|
parent, lpImeMenuW, dwSize);
|
|
|
|
|
|
|
|
if (lpImeParentMenu)
|
|
|
|
{
|
|
|
|
memcpy(lpImeParentMenu,&lpImeParentMenuW,sizeof(IMEMENUITEMINFOA));
|
|
|
|
lpImeParentMenu->hbmpItem = lpImeParentMenuW.hbmpItem;
|
|
|
|
WideCharToMultiByte(CP_ACP, 0, lpImeParentMenuW.szString,
|
|
|
|
-1, lpImeParentMenu->szString, IMEMENUITEM_STRING_SIZE,
|
|
|
|
NULL, NULL);
|
|
|
|
}
|
|
|
|
if (lpImeMenu && rc)
|
|
|
|
{
|
|
|
|
unsigned int i;
|
|
|
|
for (i = 0; i < rc; i++)
|
|
|
|
{
|
|
|
|
memcpy(&lpImeMenu[i],&lpImeMenuW[1],sizeof(IMEMENUITEMINFOA));
|
|
|
|
lpImeMenu[i].hbmpItem = lpImeMenuW[i].hbmpItem;
|
|
|
|
WideCharToMultiByte(CP_ACP, 0, lpImeMenuW[i].szString,
|
|
|
|
-1, lpImeMenu[i].szString, IMEMENUITEM_STRING_SIZE,
|
|
|
|
NULL, NULL);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
HeapFree(GetProcessHeap(),0,lpImeMenuW);
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
return 0;
|
2007-03-14 14:34:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ImmGetImeMenuItemsW (IMM32.@)
|
|
|
|
*/
|
|
|
|
DWORD WINAPI ImmGetImeMenuItemsW( HIMC hIMC, DWORD dwFlags, DWORD dwType,
|
|
|
|
LPIMEMENUITEMINFOW lpImeParentMenu, LPIMEMENUITEMINFOW lpImeMenu,
|
|
|
|
DWORD dwSize)
|
|
|
|
{
|
2014-09-28 18:27:58 +00:00
|
|
|
InputContextData *data = get_imc_data(hIMC);
|
2010-03-07 11:27:14 +00:00
|
|
|
TRACE("(%p, %i, %i, %p, %p, %i):\n", hIMC, dwFlags, dwType,
|
|
|
|
lpImeParentMenu, lpImeMenu, dwSize);
|
2014-09-28 18:27:58 +00:00
|
|
|
|
|
|
|
if (!data)
|
|
|
|
{
|
|
|
|
SetLastError(ERROR_INVALID_HANDLE);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2010-03-07 11:27:14 +00:00
|
|
|
if (data->immKbd->hIME && data->immKbd->pImeGetImeMenuItems)
|
|
|
|
{
|
|
|
|
if (is_himc_ime_unicode(data) || (!lpImeParentMenu && !lpImeMenu))
|
|
|
|
return data->immKbd->pImeGetImeMenuItems(hIMC, dwFlags, dwType,
|
|
|
|
lpImeParentMenu, lpImeMenu, dwSize);
|
|
|
|
else
|
|
|
|
{
|
|
|
|
IMEMENUITEMINFOA lpImeParentMenuA;
|
|
|
|
IMEMENUITEMINFOA *lpImeMenuA, *parent = NULL;
|
|
|
|
DWORD rc;
|
|
|
|
|
|
|
|
if (lpImeParentMenu)
|
|
|
|
parent = &lpImeParentMenuA;
|
|
|
|
if (lpImeMenu)
|
|
|
|
{
|
|
|
|
int count = dwSize / sizeof(LPIMEMENUITEMINFOW);
|
|
|
|
dwSize = count * sizeof(IMEMENUITEMINFOA);
|
|
|
|
lpImeMenuA = HeapAlloc(GetProcessHeap(), 0, dwSize);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
lpImeMenuA = NULL;
|
|
|
|
|
|
|
|
rc = data->immKbd->pImeGetImeMenuItems(hIMC, dwFlags, dwType,
|
|
|
|
(IMEMENUITEMINFOW*)parent,
|
|
|
|
(IMEMENUITEMINFOW*)lpImeMenuA, dwSize);
|
|
|
|
|
|
|
|
if (lpImeParentMenu)
|
|
|
|
{
|
|
|
|
memcpy(lpImeParentMenu,&lpImeParentMenuA,sizeof(IMEMENUITEMINFOA));
|
|
|
|
lpImeParentMenu->hbmpItem = lpImeParentMenuA.hbmpItem;
|
|
|
|
MultiByteToWideChar(CP_ACP, 0, lpImeParentMenuA.szString,
|
|
|
|
-1, lpImeParentMenu->szString, IMEMENUITEM_STRING_SIZE);
|
|
|
|
}
|
|
|
|
if (lpImeMenu && rc)
|
|
|
|
{
|
|
|
|
unsigned int i;
|
|
|
|
for (i = 0; i < rc; i++)
|
|
|
|
{
|
|
|
|
memcpy(&lpImeMenu[i],&lpImeMenuA[1],sizeof(IMEMENUITEMINFOA));
|
|
|
|
lpImeMenu[i].hbmpItem = lpImeMenuA[i].hbmpItem;
|
|
|
|
MultiByteToWideChar(CP_ACP, 0, lpImeMenuA[i].szString,
|
|
|
|
-1, lpImeMenu[i].szString, IMEMENUITEM_STRING_SIZE);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
HeapFree(GetProcessHeap(),0,lpImeMenuA);
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
return 0;
|
2007-03-14 14:34:47 +00:00
|
|
|
}
|
2005-12-12 20:59:55 +00:00
|
|
|
|
2007-09-14 08:03:04 +00:00
|
|
|
/***********************************************************************
|
|
|
|
* ImmLockIMC(IMM32.@)
|
|
|
|
*/
|
|
|
|
LPINPUTCONTEXT WINAPI ImmLockIMC(HIMC hIMC)
|
|
|
|
{
|
2014-09-28 18:27:58 +00:00
|
|
|
InputContextData *data = get_imc_data(hIMC);
|
2007-09-14 08:03:04 +00:00
|
|
|
|
|
|
|
if (!data)
|
|
|
|
return NULL;
|
|
|
|
data->dwLock++;
|
|
|
|
return &data->IMC;
|
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ImmUnlockIMC(IMM32.@)
|
|
|
|
*/
|
|
|
|
BOOL WINAPI ImmUnlockIMC(HIMC hIMC)
|
|
|
|
{
|
2014-09-28 18:27:58 +00:00
|
|
|
InputContextData *data = get_imc_data(hIMC);
|
|
|
|
|
|
|
|
if (!data)
|
|
|
|
return FALSE;
|
2013-12-01 15:57:34 +00:00
|
|
|
if (data->dwLock)
|
|
|
|
data->dwLock--;
|
|
|
|
return TRUE;
|
2007-09-14 08:03:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ImmGetIMCLockCount(IMM32.@)
|
|
|
|
*/
|
|
|
|
DWORD WINAPI ImmGetIMCLockCount(HIMC hIMC)
|
|
|
|
{
|
2014-09-28 18:27:58 +00:00
|
|
|
InputContextData *data = get_imc_data(hIMC);
|
|
|
|
if (!data)
|
|
|
|
return 0;
|
2007-09-14 08:03:04 +00:00
|
|
|
return data->dwLock;
|
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ImmCreateIMCC(IMM32.@)
|
|
|
|
*/
|
|
|
|
HIMCC WINAPI ImmCreateIMCC(DWORD size)
|
|
|
|
{
|
2013-12-01 15:57:34 +00:00
|
|
|
return GlobalAlloc(GMEM_ZEROINIT | GMEM_MOVEABLE, size);
|
2007-09-14 08:03:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ImmDestroyIMCC(IMM32.@)
|
|
|
|
*/
|
|
|
|
HIMCC WINAPI ImmDestroyIMCC(HIMCC block)
|
|
|
|
{
|
2013-12-01 15:57:34 +00:00
|
|
|
return GlobalFree(block);
|
2007-09-14 08:03:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ImmLockIMCC(IMM32.@)
|
|
|
|
*/
|
|
|
|
LPVOID WINAPI ImmLockIMCC(HIMCC imcc)
|
|
|
|
{
|
2013-12-01 15:57:34 +00:00
|
|
|
return GlobalLock(imcc);
|
2007-09-14 08:03:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ImmUnlockIMCC(IMM32.@)
|
|
|
|
*/
|
|
|
|
BOOL WINAPI ImmUnlockIMCC(HIMCC imcc)
|
|
|
|
{
|
2013-12-01 15:57:34 +00:00
|
|
|
return GlobalUnlock(imcc);
|
2007-09-14 08:03:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ImmGetIMCCLockCount(IMM32.@)
|
|
|
|
*/
|
|
|
|
DWORD WINAPI ImmGetIMCCLockCount(HIMCC imcc)
|
|
|
|
{
|
2013-12-01 15:57:34 +00:00
|
|
|
return GlobalFlags(imcc) & GMEM_LOCKCOUNT;
|
2007-09-14 08:03:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ImmReSizeIMCC(IMM32.@)
|
|
|
|
*/
|
|
|
|
HIMCC WINAPI ImmReSizeIMCC(HIMCC imcc, DWORD size)
|
|
|
|
{
|
2013-12-01 15:57:34 +00:00
|
|
|
return GlobalReAlloc(imcc, size, GMEM_ZEROINIT | GMEM_MOVEABLE);
|
2007-09-14 08:03:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ImmGetIMCCSize(IMM32.@)
|
|
|
|
*/
|
|
|
|
DWORD WINAPI ImmGetIMCCSize(HIMCC imcc)
|
|
|
|
{
|
2013-12-01 15:57:34 +00:00
|
|
|
return GlobalSize(imcc);
|
2007-09-14 08:03:04 +00:00
|
|
|
}
|
|
|
|
|
2008-04-04 13:20:27 +00:00
|
|
|
/***********************************************************************
|
|
|
|
* ImmGenerateMessage(IMM32.@)
|
|
|
|
*/
|
|
|
|
BOOL WINAPI ImmGenerateMessage(HIMC hIMC)
|
|
|
|
{
|
2014-09-28 18:27:58 +00:00
|
|
|
InputContextData *data = get_imc_data(hIMC);
|
|
|
|
|
|
|
|
if (!data)
|
|
|
|
{
|
|
|
|
SetLastError(ERROR_INVALID_HANDLE);
|
|
|
|
return FALSE;
|
|
|
|
}
|
2008-04-04 13:20:27 +00:00
|
|
|
|
|
|
|
TRACE("%i messages queued\n",data->IMC.dwNumMsgBuf);
|
|
|
|
if (data->IMC.dwNumMsgBuf > 0)
|
|
|
|
{
|
|
|
|
LPTRANSMSG lpTransMsg;
|
2017-12-08 03:14:21 +00:00
|
|
|
HIMCC hMsgBuf;
|
|
|
|
DWORD i, dwNumMsgBuf;
|
2008-04-04 13:20:27 +00:00
|
|
|
|
2017-12-08 03:14:21 +00:00
|
|
|
/* We are going to detach our hMsgBuff so that if processing messages
|
|
|
|
generates new messages they go into a new buffer */
|
|
|
|
hMsgBuf = data->IMC.hMsgBuf;
|
|
|
|
dwNumMsgBuf = data->IMC.dwNumMsgBuf;
|
2008-04-04 13:20:27 +00:00
|
|
|
|
2017-12-08 03:14:21 +00:00
|
|
|
data->IMC.hMsgBuf = ImmCreateIMCC(0);
|
2008-04-04 13:20:27 +00:00
|
|
|
data->IMC.dwNumMsgBuf = 0;
|
2017-12-08 03:14:21 +00:00
|
|
|
|
|
|
|
lpTransMsg = ImmLockIMCC(hMsgBuf);
|
|
|
|
for (i = 0; i < dwNumMsgBuf; i++)
|
|
|
|
ImmInternalSendIMEMessage(data, lpTransMsg[i].message, lpTransMsg[i].wParam, lpTransMsg[i].lParam);
|
|
|
|
|
|
|
|
ImmUnlockIMCC(hMsgBuf);
|
|
|
|
ImmDestroyIMCC(hMsgBuf);
|
2008-04-04 13:20:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2010-03-07 11:27:14 +00:00
|
|
|
/***********************************************************************
|
|
|
|
* ImmTranslateMessage(IMM32.@)
|
|
|
|
* ( Undocumented, call internally and from user32.dll )
|
|
|
|
*/
|
|
|
|
BOOL WINAPI ImmTranslateMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lKeyData)
|
2005-12-12 20:59:55 +00:00
|
|
|
{
|
2010-03-07 11:27:14 +00:00
|
|
|
InputContextData *data;
|
|
|
|
HIMC imc = ImmGetContext(hwnd);
|
|
|
|
BYTE state[256];
|
|
|
|
UINT scancode;
|
|
|
|
LPVOID list = 0;
|
|
|
|
UINT msg_count;
|
|
|
|
UINT uVirtKey;
|
|
|
|
static const DWORD list_count = 10;
|
2007-09-14 08:03:04 +00:00
|
|
|
|
2010-03-07 11:27:14 +00:00
|
|
|
TRACE("%p %x %x %x\n",hwnd, msg, (UINT)wParam, (UINT)lKeyData);
|
2007-09-14 08:03:04 +00:00
|
|
|
|
2010-03-07 11:27:14 +00:00
|
|
|
if (imc)
|
|
|
|
data = imc;
|
|
|
|
else
|
|
|
|
return FALSE;
|
2008-05-08 16:03:10 +00:00
|
|
|
|
2010-03-07 11:27:14 +00:00
|
|
|
if (!data->immKbd->hIME || !data->immKbd->pImeToAsciiEx)
|
|
|
|
return FALSE;
|
2008-05-08 16:03:10 +00:00
|
|
|
|
2010-03-07 11:27:14 +00:00
|
|
|
GetKeyboardState(state);
|
|
|
|
scancode = lKeyData >> 0x10 & 0xff;
|
2007-09-14 08:03:04 +00:00
|
|
|
|
2010-03-07 11:27:14 +00:00
|
|
|
list = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, list_count * sizeof(TRANSMSG) + sizeof(DWORD));
|
|
|
|
((DWORD*)list)[0] = list_count;
|
2008-05-08 16:03:10 +00:00
|
|
|
|
2010-03-07 11:27:14 +00:00
|
|
|
if (data->immKbd->imeInfo.fdwProperty & IME_PROP_KBD_CHAR_FIRST)
|
|
|
|
{
|
|
|
|
WCHAR chr;
|
2008-05-08 16:03:10 +00:00
|
|
|
|
2010-03-07 11:27:14 +00:00
|
|
|
if (!is_himc_ime_unicode(data))
|
|
|
|
ToAscii(data->lastVK, scancode, state, &chr, 0);
|
|
|
|
else
|
|
|
|
ToUnicodeEx(data->lastVK, scancode, state, &chr, 1, 0, GetKeyboardLayout(0));
|
|
|
|
uVirtKey = MAKELONG(data->lastVK,chr);
|
2008-05-06 09:16:21 +00:00
|
|
|
}
|
2010-03-07 11:27:14 +00:00
|
|
|
else
|
|
|
|
uVirtKey = data->lastVK;
|
2007-09-14 08:03:04 +00:00
|
|
|
|
2010-03-07 11:27:14 +00:00
|
|
|
msg_count = data->immKbd->pImeToAsciiEx(uVirtKey, scancode, state, list, 0, imc);
|
|
|
|
TRACE("%i messages generated\n",msg_count);
|
|
|
|
if (msg_count && msg_count <= list_count)
|
|
|
|
{
|
|
|
|
UINT i;
|
|
|
|
LPTRANSMSG msgs = (LPTRANSMSG)((LPBYTE)list + sizeof(DWORD));
|
2008-05-08 16:03:10 +00:00
|
|
|
|
2010-03-07 11:27:14 +00:00
|
|
|
for (i = 0; i < msg_count; i++)
|
|
|
|
ImmInternalPostIMEMessage(data, msgs[i].message, msgs[i].wParam, msgs[i].lParam);
|
|
|
|
}
|
|
|
|
else if (msg_count > list_count)
|
|
|
|
ImmGenerateMessage(imc);
|
2008-05-08 16:03:10 +00:00
|
|
|
|
2010-03-07 11:27:14 +00:00
|
|
|
HeapFree(GetProcessHeap(),0,list);
|
2007-09-14 08:03:04 +00:00
|
|
|
|
2010-03-07 11:27:14 +00:00
|
|
|
data->lastVK = VK_PROCESSKEY;
|
2007-09-14 08:03:04 +00:00
|
|
|
|
2010-03-07 11:27:14 +00:00
|
|
|
return (msg_count > 0);
|
2005-12-12 20:59:55 +00:00
|
|
|
}
|
|
|
|
|
2010-03-07 11:27:14 +00:00
|
|
|
/***********************************************************************
|
|
|
|
* ImmProcessKey(IMM32.@)
|
|
|
|
* ( Undocumented, called from user32.dll )
|
|
|
|
*/
|
|
|
|
BOOL WINAPI ImmProcessKey(HWND hwnd, HKL hKL, UINT vKey, LPARAM lKeyData, DWORD unknown)
|
2005-12-12 20:59:55 +00:00
|
|
|
{
|
2010-03-07 11:27:14 +00:00
|
|
|
InputContextData *data;
|
|
|
|
HIMC imc = ImmGetContext(hwnd);
|
|
|
|
BYTE state[256];
|
2005-12-12 20:59:55 +00:00
|
|
|
|
2010-03-07 11:27:14 +00:00
|
|
|
TRACE("%p %p %x %x %x\n",hwnd, hKL, vKey, (UINT)lKeyData, unknown);
|
2005-12-12 20:59:55 +00:00
|
|
|
|
2010-03-07 11:27:14 +00:00
|
|
|
if (imc)
|
|
|
|
data = imc;
|
|
|
|
else
|
|
|
|
return FALSE;
|
2005-12-12 20:59:55 +00:00
|
|
|
|
2017-12-08 03:14:21 +00:00
|
|
|
/* Make sure we are inputting to the correct keyboard */
|
|
|
|
if (data->immKbd->hkl != hKL)
|
|
|
|
{
|
|
|
|
ImmHkl *new_hkl = IMM_GetImmHkl(hKL);
|
|
|
|
if (new_hkl)
|
|
|
|
{
|
|
|
|
data->immKbd->pImeSelect(imc, FALSE);
|
|
|
|
data->immKbd->uSelected--;
|
|
|
|
data->immKbd = new_hkl;
|
|
|
|
data->immKbd->pImeSelect(imc, TRUE);
|
|
|
|
data->immKbd->uSelected++;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2010-03-07 11:27:14 +00:00
|
|
|
if (!data->immKbd->hIME || !data->immKbd->pImeProcessKey)
|
|
|
|
return FALSE;
|
2008-05-08 16:03:10 +00:00
|
|
|
|
2010-03-07 11:27:14 +00:00
|
|
|
GetKeyboardState(state);
|
|
|
|
if (data->immKbd->pImeProcessKey(imc, vKey, lKeyData, state))
|
2008-05-08 16:03:10 +00:00
|
|
|
{
|
2010-03-07 11:27:14 +00:00
|
|
|
data->lastVK = vKey;
|
|
|
|
return TRUE;
|
2008-05-08 16:03:10 +00:00
|
|
|
}
|
2005-12-12 20:59:55 +00:00
|
|
|
|
2010-03-07 11:27:14 +00:00
|
|
|
data->lastVK = VK_PROCESSKEY;
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ImmDisableTextFrameService(IMM32.@)
|
|
|
|
*/
|
|
|
|
BOOL WINAPI ImmDisableTextFrameService(DWORD idThread)
|
|
|
|
{
|
|
|
|
FIXME("Stub\n");
|
|
|
|
return FALSE;
|
2005-12-12 20:59:55 +00:00
|
|
|
}
|
2011-12-15 00:40:35 +00:00
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ImmEnumInputContext(IMM32.@)
|
|
|
|
*/
|
|
|
|
|
|
|
|
BOOL WINAPI ImmEnumInputContext(DWORD idThread, IMCENUMPROC lpfn, LPARAM lParam)
|
|
|
|
{
|
|
|
|
FIXME("Stub\n");
|
|
|
|
return FALSE;
|
|
|
|
}
|
2012-03-15 21:42:01 +00:00
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ImmGetHotKey(IMM32.@)
|
|
|
|
*/
|
|
|
|
|
|
|
|
BOOL WINAPI ImmGetHotKey(DWORD hotkey, UINT *modifiers, UINT *key, HKL hkl)
|
|
|
|
{
|
|
|
|
FIXME("%x, %p, %p, %p: stub\n", hotkey, modifiers, key, hkl);
|
|
|
|
return FALSE;
|
|
|
|
}
|