[IMM32][SDK][NTUSER][IMM32_WINETEST] Add CtfImmGenerateMessage (#6037)

Implementing advanced text service...

- Add CtfImmGenerateMessage function.
- Modify imm32.spec.
- Move TRANSMSG, TRANSMSGLIST etc. in
  win32ss/include/ntuser.h to <immdev.h>.
- Move win32ss/include/imetable.h to
  sdk/include/reactos/imetable.h.
- Move dll/win32/imm32/CtfImeTable.h to
  sdk/include/reactos/CtfImeTable.h.
- Fix build failure of imm32_winetest due
  to TRANSMSG redefinition.

CORE-19268
This commit is contained in:
Katayama Hirofumi MZ 2023-11-25 22:46:00 +09:00 committed by GitHub
parent 6783061894
commit 3b2fdc56bd
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 201 additions and 109 deletions

View file

@ -134,7 +134,7 @@ VOID Imm32TF_InvalidAssemblyListCacheIfExist(VOID)
* new-style and high-level input method. * new-style and high-level input method.
* *
* The CTF IME file is a DLL file that the software developer distributes. * The CTF IME file is a DLL file that the software developer distributes.
* The export functions of the CTF IME file are defined in "CtfImeTable.h" of * The export functions of the CTF IME file are defined in <CtfImeTable.h> of
* this folder. * this folder.
*/ */
@ -148,13 +148,13 @@ HINSTANCE g_hCtfIme = NULL;
#undef DEFINE_CTF_IME_FN #undef DEFINE_CTF_IME_FN
#define DEFINE_CTF_IME_FN(func_name, ret_type, params) \ #define DEFINE_CTF_IME_FN(func_name, ret_type, params) \
typedef ret_type (WINAPI *FN_##func_name)params; typedef ret_type (WINAPI *FN_##func_name)params;
#include "CtfImeTable.h" #include <CtfImeTable.h>
/* Define the global variables (g_pfn...) for CTF IME functions */ /* Define the global variables (g_pfn...) for CTF IME functions */
#undef DEFINE_CTF_IME_FN #undef DEFINE_CTF_IME_FN
#define DEFINE_CTF_IME_FN(func_name, ret_type, params) \ #define DEFINE_CTF_IME_FN(func_name, ret_type, params) \
FN_##func_name g_pfn##func_name = NULL; FN_##func_name g_pfn##func_name = NULL;
#include "CtfImeTable.h" #include <CtfImeTable.h>
/* The macro that gets the variable name from the CTF IME function name */ /* The macro that gets the variable name from the CTF IME function name */
#define CTF_IME_FN(func_name) g_pfn##func_name #define CTF_IME_FN(func_name) g_pfn##func_name
@ -256,7 +256,7 @@ Imm32LoadCtfIme(VOID)
bSuccess = FALSE; /* Failed */ \ bSuccess = FALSE; /* Failed */ \
break; \ break; \
} }
#include "CtfImeTable.h" #include <CtfImeTable.h>
} while (0); } while (0);
/* Unload the CTF IME if failed */ /* Unload the CTF IME if failed */
@ -265,7 +265,7 @@ Imm32LoadCtfIme(VOID)
/* Set NULL to the function pointers */ /* Set NULL to the function pointers */
#undef DEFINE_CTF_IME_FN #undef DEFINE_CTF_IME_FN
#define DEFINE_CTF_IME_FN(func_name, ret_type, params) CTF_IME_FN(func_name) = NULL; #define DEFINE_CTF_IME_FN(func_name, ret_type, params) CTF_IME_FN(func_name) = NULL;
#include "CtfImeTable.h" #include <CtfImeTable.h>
if (g_hCtfIme) if (g_hCtfIme)
{ {
@ -493,6 +493,94 @@ CtfImmTIMActivate(_In_ HKL hKL)
return E_NOTIMPL; return E_NOTIMPL;
} }
/***********************************************************************
* CtfImmGenerateMessage(IMM32.@)
*/
BOOL WINAPI
CtfImmGenerateMessage(
_In_ HIMC hIMC,
_In_ BOOL bSend)
{
DWORD_PTR dwImeThreadId, dwCurrentThreadId;
PCLIENTIMC pClientImc;
BOOL bUnicode;
LPINPUTCONTEXT pIC;
DWORD iMsg, dwNumMsgBuf;
LPTRANSMSG pOldTransMsg, pNewTransMsg;
SIZE_T cbTransMsg;
TRACE("(%p, %d)\n", hIMC, bSend);
dwImeThreadId = NtUserQueryInputContext(hIMC, QIC_INPUTTHREADID);
dwCurrentThreadId = GetCurrentThreadId();
if (dwImeThreadId != dwCurrentThreadId)
{
ERR("%p vs %p\n", dwImeThreadId, dwCurrentThreadId);
return FALSE;
}
pClientImc = ImmLockClientImc(hIMC);
if (IS_NULL_UNEXPECTEDLY(pClientImc))
return FALSE;
bUnicode = !!(pClientImc->dwFlags & CLIENTIMC_WIDE);
ImmUnlockClientImc(pClientImc);
pIC = (LPINPUTCONTEXT)ImmLockIMC(hIMC);
if (IS_NULL_UNEXPECTEDLY(pIC))
return FALSE;
dwNumMsgBuf = pIC->dwNumMsgBuf;
pOldTransMsg = (LPTRANSMSG)ImmLockIMCC(pIC->hMsgBuf);
if (IS_NULL_UNEXPECTEDLY(pOldTransMsg))
{
pIC->dwNumMsgBuf = 0;
ImmUnlockIMC(hIMC);
return TRUE;
}
cbTransMsg = sizeof(TRANSMSG) * dwNumMsgBuf;
pNewTransMsg = (PTRANSMSG)ImmLocalAlloc(0, cbTransMsg);
if (IS_NULL_UNEXPECTEDLY(pNewTransMsg))
{
ImmUnlockIMCC(pIC->hMsgBuf);
pIC->dwNumMsgBuf = 0;
ImmUnlockIMC(hIMC);
return TRUE;
}
RtlCopyMemory(pNewTransMsg, pOldTransMsg, cbTransMsg);
for (iMsg = 0; iMsg < dwNumMsgBuf; ++iMsg)
{
HWND hWnd = pIC->hWnd;
UINT uMsg = pNewTransMsg[iMsg].message;
WPARAM wParam = pNewTransMsg[iMsg].wParam;
LPARAM lParam = pNewTransMsg[iMsg].lParam;
if (bSend)
{
if (bUnicode)
SendMessageW(hWnd, uMsg, wParam, lParam);
else
SendMessageA(hWnd, uMsg, wParam, lParam);
}
else
{
if (bUnicode)
PostMessageW(hWnd, uMsg, wParam, lParam);
else
PostMessageA(hWnd, uMsg, wParam, lParam);
}
}
ImmLocalFree(pNewTransMsg);
ImmUnlockIMCC(pIC->hMsgBuf);
pIC->dwNumMsgBuf = 0; /* Processed */
ImmUnlockIMC(hIMC);
return TRUE;
}
/*********************************************************************** /***********************************************************************
* CtfImmHideToolbarWnd(IMM32.@) * CtfImmHideToolbarWnd(IMM32.@)
* *

View file

@ -191,7 +191,7 @@ BOOL APIENTRY Imm32InquireIme(PIMEDPI pImeDpi)
FIXME("%s: Why stub called?\n", #name); \ FIXME("%s: Why stub called?\n", #name); \
return (type)0; \ return (type)0; \
} }
#include "imetable.h" #include <imetable.h>
#undef DEFINE_IME_ENTRY #undef DEFINE_IME_ENTRY
// Win: LoadIME // Win: LoadIME
@ -214,7 +214,7 @@ BOOL APIENTRY Imm32LoadIME(PIMEINFOEX pImeInfoEx, PIMEDPI pImeDpi)
/* Populate the table by stub IME functions */ /* Populate the table by stub IME functions */
#define DEFINE_IME_ENTRY(type, name, params, optional) pImeDpi->name = Stub##name; #define DEFINE_IME_ENTRY(type, name, params, optional) pImeDpi->name = Stub##name;
#include "imetable.h" #include <imetable.h>
#undef DEFINE_IME_ENTRY #undef DEFINE_IME_ENTRY
/* Populate the table by real IME functions */ /* Populate the table by real IME functions */
@ -227,7 +227,7 @@ BOOL APIENTRY Imm32LoadIME(PIMEINFOEX pImeInfoEx, PIMEDPI pImeDpi)
goto Failed; \ goto Failed; \
} \ } \
} while (0); } while (0);
#include "imetable.h" #include <imetable.h>
#undef DEFINE_IME_ENTRY #undef DEFINE_IME_ENTRY
if (Imm32InquireIme(pImeDpi)) if (Imm32InquireIme(pImeDpi))

View file

@ -2,6 +2,7 @@
@ stdcall CtfAImmDeactivate(long) @ stdcall CtfAImmDeactivate(long)
@ stdcall CtfAImmIsIME(ptr) @ stdcall CtfAImmIsIME(ptr)
@ stdcall CtfImmDispatchDefImeMessage(ptr long ptr ptr) @ stdcall CtfImmDispatchDefImeMessage(ptr long ptr ptr)
@ stdcall CtfImmGenerateMessage(ptr long)
@ stdcall CtfImmGetGuidAtom(ptr long ptr) @ stdcall CtfImmGetGuidAtom(ptr long ptr)
@ stdcall CtfImmHideToolbarWnd() @ stdcall CtfImmHideToolbarWnd()
@ stdcall CtfImmIsCiceroEnabled() @ stdcall CtfImmIsCiceroEnabled()

View file

@ -61,11 +61,13 @@ typedef struct
} u; } u;
} TEST_INPUT; } TEST_INPUT;
#ifndef __REACTOS__
typedef struct _tagTRANSMSG { typedef struct _tagTRANSMSG {
UINT message; UINT message;
WPARAM wParam; WPARAM wParam;
LPARAM lParam; LPARAM lParam;
} TRANSMSG, *LPTRANSMSG; } TRANSMSG, *LPTRANSMSG;
#endif
static UINT (WINAPI *pSendInput) (UINT, INPUT*, size_t); static UINT (WINAPI *pSendInput) (UINT, INPUT*, size_t);

View file

@ -238,6 +238,107 @@ typedef struct IME_STATE
C_ASSERT(sizeof(IME_STATE) == 0x18); C_ASSERT(sizeof(IME_STATE) == 0x18);
#endif #endif
typedef struct _tagTRANSMSG
{
UINT message;
WPARAM wParam;
LPARAM lParam;
} TRANSMSG, *PTRANSMSG, *LPTRANSMSG;
typedef struct _tagTRANSMSGLIST
{
UINT uMsgCount;
TRANSMSG TransMsg[ANYSIZE_ARRAY];
} TRANSMSGLIST, *PTRANSMSGLIST, *LPTRANSMSGLIST;
#define DEFINE_IME_ENTRY(type, name, params, extended) typedef type (WINAPI *FN_##name) params;
#include <imetable.h>
#undef DEFINE_IME_ENTRY
typedef struct IMEDPI
{
struct IMEDPI *pNext;
HINSTANCE hInst;
HKL hKL;
IMEINFO ImeInfo;
UINT uCodePage;
WCHAR szUIClass[16];
DWORD cLockObj;
DWORD dwFlags;
#define DEFINE_IME_ENTRY(type, name, params, extended) FN_##name name;
#include <imetable.h>
#undef DEFINE_IME_ENTRY
} IMEDPI, *PIMEDPI;
#ifndef _WIN64
C_ASSERT(offsetof(IMEDPI, pNext) == 0x0);
C_ASSERT(offsetof(IMEDPI, hInst) == 0x4);
C_ASSERT(offsetof(IMEDPI, hKL) == 0x8);
C_ASSERT(offsetof(IMEDPI, ImeInfo) == 0xc);
C_ASSERT(offsetof(IMEDPI, uCodePage) == 0x28);
C_ASSERT(offsetof(IMEDPI, szUIClass) == 0x2c);
C_ASSERT(offsetof(IMEDPI, cLockObj) == 0x4c);
C_ASSERT(offsetof(IMEDPI, dwFlags) == 0x50);
C_ASSERT(offsetof(IMEDPI, ImeInquire) == 0x54);
C_ASSERT(offsetof(IMEDPI, ImeConversionList) == 0x58);
C_ASSERT(offsetof(IMEDPI, ImeRegisterWord) == 0x5c);
C_ASSERT(offsetof(IMEDPI, ImeUnregisterWord) == 0x60);
C_ASSERT(offsetof(IMEDPI, ImeGetRegisterWordStyle) == 0x64);
C_ASSERT(offsetof(IMEDPI, ImeEnumRegisterWord) == 0x68);
C_ASSERT(offsetof(IMEDPI, ImeConfigure) == 0x6c);
C_ASSERT(offsetof(IMEDPI, ImeDestroy) == 0x70);
C_ASSERT(offsetof(IMEDPI, ImeEscape) == 0x74);
C_ASSERT(offsetof(IMEDPI, ImeProcessKey) == 0x78);
C_ASSERT(offsetof(IMEDPI, ImeSelect) == 0x7c);
C_ASSERT(offsetof(IMEDPI, ImeSetActiveContext) == 0x80);
C_ASSERT(offsetof(IMEDPI, ImeToAsciiEx) == 0x84);
C_ASSERT(offsetof(IMEDPI, NotifyIME) == 0x88);
C_ASSERT(offsetof(IMEDPI, ImeSetCompositionString) == 0x8c);
C_ASSERT(offsetof(IMEDPI, ImeGetImeMenuItems) == 0x90);
C_ASSERT(offsetof(IMEDPI, CtfImeInquireExW) == 0x94);
C_ASSERT(offsetof(IMEDPI, CtfImeSelectEx) == 0x98);
C_ASSERT(offsetof(IMEDPI, CtfImeEscapeEx) == 0x9c);
C_ASSERT(offsetof(IMEDPI, CtfImeGetGuidAtom) == 0xa0);
C_ASSERT(offsetof(IMEDPI, CtfImeIsGuidMapEnable) == 0xa4);
C_ASSERT(sizeof(IMEDPI) == 0xa8);
#endif
/* flags for IMEDPI.dwFlags */
#define IMEDPI_FLAG_UNLOADED 0x1
#define IMEDPI_FLAG_LOCKED 0x2
/* unconfirmed */
typedef struct tagCLIENTIMC
{
HANDLE hInputContext; /* LocalAlloc'ed LHND */
LONG cLockObj;
DWORD dwFlags;
DWORD dwCompatFlags;
RTL_CRITICAL_SECTION cs;
UINT uCodePage;
HKL hKL;
BOOL bUnknown4;
} CLIENTIMC, *PCLIENTIMC;
#ifndef _WIN64
C_ASSERT(offsetof(CLIENTIMC, hInputContext) == 0x0);
C_ASSERT(offsetof(CLIENTIMC, cLockObj) == 0x4);
C_ASSERT(offsetof(CLIENTIMC, dwFlags) == 0x8);
C_ASSERT(offsetof(CLIENTIMC, dwCompatFlags) == 0xc);
C_ASSERT(offsetof(CLIENTIMC, cs) == 0x10);
C_ASSERT(offsetof(CLIENTIMC, uCodePage) == 0x28);
C_ASSERT(offsetof(CLIENTIMC, hKL) == 0x2c);
C_ASSERT(sizeof(CLIENTIMC) == 0x34);
#endif
/* flags for CLIENTIMC */
#define CLIENTIMC_WIDE 0x1
#define CLIENTIMC_ACTIVE 0x2
#define CLIENTIMC_UNKNOWN4 0x20
#define CLIENTIMC_DESTROY 0x40
#define CLIENTIMC_DISABLEIME 0x80
#define CLIENTIMC_UNKNOWN2 0x100
#ifdef __cplusplus #ifdef __cplusplus
} // extern "C" } // extern "C"
#endif #endif

View file

@ -29,6 +29,7 @@ BOOL WINAPI CtfImmIsCiceroStartedInThread(VOID);
VOID WINAPI CtfImmSetAppCompatFlags(_In_ DWORD dwFlags); VOID WINAPI CtfImmSetAppCompatFlags(_In_ DWORD dwFlags);
DWORD WINAPI CtfImmHideToolbarWnd(VOID); DWORD WINAPI CtfImmHideToolbarWnd(VOID);
VOID WINAPI CtfImmRestoreToolbarWnd(_In_ LPVOID pUnused, _In_ DWORD dwShowFlags); VOID WINAPI CtfImmRestoreToolbarWnd(_In_ LPVOID pUnused, _In_ DWORD dwShowFlags);
BOOL WINAPI CtfImmGenerateMessage(_In_ HIMC hIMC, _In_ BOOL bSend);
LRESULT WINAPI LRESULT WINAPI
CtfImmDispatchDefImeMessage( CtfImmDispatchDefImeMessage(

View file

@ -1261,107 +1261,6 @@ typedef struct _IMEWND
PIMEUI pimeui; PIMEUI pimeui;
} IMEWND, *PIMEWND; } IMEWND, *PIMEWND;
typedef struct tagTRANSMSG
{
UINT message;
WPARAM wParam;
LPARAM lParam;
} TRANSMSG, *PTRANSMSG, *LPTRANSMSG;
typedef struct tagTRANSMSGLIST
{
UINT uMsgCount;
TRANSMSG TransMsg[ANYSIZE_ARRAY];
} TRANSMSGLIST, *PTRANSMSGLIST, *LPTRANSMSGLIST;
#define DEFINE_IME_ENTRY(type, name, params, extended) typedef type (WINAPI *FN_##name) params;
#include "imetable.h"
#undef DEFINE_IME_ENTRY
typedef struct IMEDPI
{
struct IMEDPI *pNext;
HINSTANCE hInst;
HKL hKL;
IMEINFO ImeInfo;
UINT uCodePage;
WCHAR szUIClass[16];
DWORD cLockObj;
DWORD dwFlags;
#define DEFINE_IME_ENTRY(type, name, params, extended) FN_##name name;
#include "imetable.h"
#undef DEFINE_IME_ENTRY
} IMEDPI, *PIMEDPI;
#ifndef _WIN64
C_ASSERT(offsetof(IMEDPI, pNext) == 0x0);
C_ASSERT(offsetof(IMEDPI, hInst) == 0x4);
C_ASSERT(offsetof(IMEDPI, hKL) == 0x8);
C_ASSERT(offsetof(IMEDPI, ImeInfo) == 0xc);
C_ASSERT(offsetof(IMEDPI, uCodePage) == 0x28);
C_ASSERT(offsetof(IMEDPI, szUIClass) == 0x2c);
C_ASSERT(offsetof(IMEDPI, cLockObj) == 0x4c);
C_ASSERT(offsetof(IMEDPI, dwFlags) == 0x50);
C_ASSERT(offsetof(IMEDPI, ImeInquire) == 0x54);
C_ASSERT(offsetof(IMEDPI, ImeConversionList) == 0x58);
C_ASSERT(offsetof(IMEDPI, ImeRegisterWord) == 0x5c);
C_ASSERT(offsetof(IMEDPI, ImeUnregisterWord) == 0x60);
C_ASSERT(offsetof(IMEDPI, ImeGetRegisterWordStyle) == 0x64);
C_ASSERT(offsetof(IMEDPI, ImeEnumRegisterWord) == 0x68);
C_ASSERT(offsetof(IMEDPI, ImeConfigure) == 0x6c);
C_ASSERT(offsetof(IMEDPI, ImeDestroy) == 0x70);
C_ASSERT(offsetof(IMEDPI, ImeEscape) == 0x74);
C_ASSERT(offsetof(IMEDPI, ImeProcessKey) == 0x78);
C_ASSERT(offsetof(IMEDPI, ImeSelect) == 0x7c);
C_ASSERT(offsetof(IMEDPI, ImeSetActiveContext) == 0x80);
C_ASSERT(offsetof(IMEDPI, ImeToAsciiEx) == 0x84);
C_ASSERT(offsetof(IMEDPI, NotifyIME) == 0x88);
C_ASSERT(offsetof(IMEDPI, ImeSetCompositionString) == 0x8c);
C_ASSERT(offsetof(IMEDPI, ImeGetImeMenuItems) == 0x90);
C_ASSERT(offsetof(IMEDPI, CtfImeInquireExW) == 0x94);
C_ASSERT(offsetof(IMEDPI, CtfImeSelectEx) == 0x98);
C_ASSERT(offsetof(IMEDPI, CtfImeEscapeEx) == 0x9c);
C_ASSERT(offsetof(IMEDPI, CtfImeGetGuidAtom) == 0xa0);
C_ASSERT(offsetof(IMEDPI, CtfImeIsGuidMapEnable) == 0xa4);
C_ASSERT(sizeof(IMEDPI) == 0xa8);
#endif
/* flags for IMEDPI.dwFlags */
#define IMEDPI_FLAG_UNLOADED 0x1
#define IMEDPI_FLAG_LOCKED 0x2
/* unconfirmed */
typedef struct tagCLIENTIMC
{
HANDLE hInputContext; /* LocalAlloc'ed LHND */
LONG cLockObj;
DWORD dwFlags;
DWORD dwCompatFlags;
RTL_CRITICAL_SECTION cs;
UINT uCodePage;
HKL hKL;
BOOL bUnknown4;
} CLIENTIMC, *PCLIENTIMC;
#ifndef _WIN64
C_ASSERT(offsetof(CLIENTIMC, hInputContext) == 0x0);
C_ASSERT(offsetof(CLIENTIMC, cLockObj) == 0x4);
C_ASSERT(offsetof(CLIENTIMC, dwFlags) == 0x8);
C_ASSERT(offsetof(CLIENTIMC, dwCompatFlags) == 0xc);
C_ASSERT(offsetof(CLIENTIMC, cs) == 0x10);
C_ASSERT(offsetof(CLIENTIMC, uCodePage) == 0x28);
C_ASSERT(offsetof(CLIENTIMC, hKL) == 0x2c);
C_ASSERT(sizeof(CLIENTIMC) == 0x34);
#endif
/* flags for CLIENTIMC */
#define CLIENTIMC_WIDE 0x1
#define CLIENTIMC_ACTIVE 0x2
#define CLIENTIMC_UNKNOWN4 0x20
#define CLIENTIMC_DESTROY 0x40
#define CLIENTIMC_DISABLEIME 0x80
#define CLIENTIMC_UNKNOWN2 0x100
DWORD DWORD
NTAPI NTAPI
NtUserAssociateInputContext(HWND hWnd, HIMC hIMC, DWORD dwFlags); NtUserAssociateInputContext(HWND hWnd, HIMC hIMC, DWORD dwFlags);