[IMM32][SDK] Support ImmIMPQueryIMEA/W and ImmIMPSetIMEA/W (#8033)

Implementing missing features...
These functions are given for IME
program handling.
JIRA issue: CORE-19268
- Implement ImmIMPQueryIMEA
  and ImmIMPQueryIMEW functions.
- Implement ImmIMPSetIMEA and
  ImmIMPSetIMEW functions.
- Add prototypes to <imm32_undoc.h>.
This commit is contained in:
Katayama Hirofumi MZ 2025-05-27 20:10:25 +09:00 committed by GitHub
parent 3df71d678d
commit 17577d2581
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 227 additions and 19 deletions

View file

@ -233,6 +233,10 @@ LRESULT WINAPI ImmPutImeMenuItemsIntoMappedFile(_In_ HIMC hIMC);
BOOL WINAPI ImmIMPGetIMEA(_In_opt_ HWND hWnd, _Out_ LPIMEPROA pImePro);
BOOL WINAPI ImmIMPGetIMEW(_In_opt_ HWND hWnd, _Out_ LPIMEPROW pImePro);
BOOL WINAPI ImmIMPQueryIMEA(_Inout_ LPIMEPROA pImePro);
BOOL WINAPI ImmIMPQueryIMEW(_Inout_ LPIMEPROW pImePro);
BOOL WINAPI ImmIMPSetIMEA(_In_opt_ HWND hWnd, _Inout_ LPIMEPROA pImePro);
BOOL WINAPI ImmIMPSetIMEW(_In_opt_ HWND hWnd, _Inout_ LPIMEPROW pImePro);
HRESULT WINAPI CtfAImmActivate(_Out_opt_ HINSTANCE *phinstCtfIme);
HRESULT WINAPI CtfAImmDeactivate(_In_ BOOL bDestroy);
@ -260,8 +264,12 @@ CtfImmDispatchDefImeMessage(
#ifdef UNICODE
#define ImmIMPGetIME ImmIMPGetIMEW
#define ImmIMPQueryIME ImmIMPQueryIMEW
#define ImmIMPSetIME ImmIMPSetIMEW
#else
#define ImmIMPGetIME ImmIMPGetIMEA
#define ImmIMPQueryIME ImmIMPQueryIMEA
#define ImmIMPSetIME ImmIMPSetIMEA
#endif
#ifdef __cplusplus

View file

@ -15,8 +15,13 @@ WINE_DEFAULT_DEBUG_CHANNEL(imm);
*/
static VOID
Imm32ConvertImeProWideToAnsi(_In_ const IMEPROW *pProW, _Out_ PIMEPROA pProA)
Imm32ConvertImeProWideToAnsi(
_In_ const IMEPROW *pProW,
_Out_ PIMEPROA pProA)
{
ASSERT(pProW);
ASSERT(pProA);
pProA->hWnd = pProW->hWnd;
pProA->InstDate = pProW->InstDate;
pProA->wVersion = pProW->wVersion;
@ -33,8 +38,12 @@ Imm32ConvertImeProWideToAnsi(_In_ const IMEPROW *pProW, _Out_ PIMEPROA pProA)
}
static BOOL
Imm32IMPGetIME(_In_ HKL hKL, _Out_ PIMEPROW pProW)
Imm32IMPGetIME(
_In_ HKL hKL,
_Out_ PIMEPROW pProW)
{
ASSERT(pProW);
IMEINFOEX ImeInfoEx;
if (!ImmGetImeInfoEx(&ImeInfoEx, ImeInfoExKeyboardLayout, &hKL))
return FALSE;
@ -56,12 +65,16 @@ Imm32IMPGetIME(_In_ HKL hKL, _Out_ PIMEPROW pProW)
* ImmIMPGetIMEA(IMM32.@)
*/
BOOL WINAPI
ImmIMPGetIMEA(_In_opt_ HWND hWnd, _Out_ LPIMEPROA pImePro)
ImmIMPGetIMEA(
_In_opt_ HWND hWnd,
_Out_ LPIMEPROA pImePro)
{
UNREFERENCED_PARAMETER(hWnd);
TRACE("(%p, %p)\n", hWnd, pImePro);
ASSERT(pImePro);
if (!Imm32IsSystemJapaneseOrKorean())
{
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
@ -81,12 +94,16 @@ ImmIMPGetIMEA(_In_opt_ HWND hWnd, _Out_ LPIMEPROA pImePro)
* ImmIMPGetIMEW(IMM32.@)
*/
BOOL WINAPI
ImmIMPGetIMEW(_In_opt_ HWND hWnd, _Out_ LPIMEPROW pImePro)
ImmIMPGetIMEW(
_In_opt_ HWND hWnd,
_Out_ LPIMEPROW pImePro)
{
UNREFERENCED_PARAMETER(hWnd);
TRACE("(%p, %p)\n", hWnd, pImePro);
ASSERT(pImePro);
if (!Imm32IsSystemJapaneseOrKorean())
{
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
@ -100,39 +117,222 @@ ImmIMPGetIMEW(_In_opt_ HWND hWnd, _Out_ LPIMEPROW pImePro)
/***********************************************************************
* ImmIMPQueryIMEA(IMM32.@)
*/
BOOL WINAPI ImmIMPQueryIMEA(LPIMEPROA pImePro)
BOOL WINAPI
ImmIMPQueryIMEA(_Inout_ LPIMEPROA pImePro)
{
FIXME("(%p)\n", pImePro);
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
TRACE("(%p)\n", pImePro);
ASSERT(pImePro);
if (!Imm32IsSystemJapaneseOrKorean())
{
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
}
IMEPROW ProW;
if (pImePro->szName[0])
{
/* pImePro->szName is BYTE[], so we need type cast */
if (!MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, (PSTR)pImePro->szName, -1,
ProW.szName, _countof(ProW.szName)))
{
ERR("szName: %s\n", debugstr_a((PSTR)pImePro->szName));
return FALSE;
}
ProW.szName[_countof(ProW.szName) - 1] = UNICODE_NULL; /* Avoid buffer overrun */
}
else
{
ProW.szName[0] = UNICODE_NULL;
}
if (!ImmIMPQueryIMEW(&ProW))
return FALSE;
Imm32ConvertImeProWideToAnsi(&ProW, pImePro);
return TRUE;
}
/***********************************************************************
* ImmIMPQueryIMEW(IMM32.@)
*/
BOOL WINAPI ImmIMPQueryIMEW(LPIMEPROW pImePro)
BOOL WINAPI
ImmIMPQueryIMEW(_Inout_ LPIMEPROW pImePro)
{
FIXME("(%p)\n", pImePro);
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
TRACE("(%p)\n", pImePro);
ASSERT(pImePro);
if (!Imm32IsSystemJapaneseOrKorean())
{
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
}
INT nLayouts = GetKeyboardLayoutList(0, NULL);
if (nLayouts <= 0)
{
ERR("nLayouts: %d\n", nLayouts);
return FALSE;
}
HKL *phKLs = ImmLocalAlloc(0, nLayouts * sizeof(HKL));
if (!phKLs)
{
ERR("Out of memory\n");
return FALSE;
}
if (GetKeyboardLayoutList(nLayouts, phKLs) != nLayouts)
{
ERR("KL count mismatch\n");
ImmLocalFree(phKLs);
return FALSE;
}
BOOL result = FALSE;
if (pImePro->szName[0])
{
IMEINFOEX ImeInfoEx;
if (ImmGetImeInfoEx(&ImeInfoEx, ImeInfoExImeFileName, pImePro->szName))
{
for (INT iKL = 0; iKL < nLayouts; ++iKL)
{
if (phKLs[iKL] == ImeInfoEx.hkl)
{
result = Imm32IMPGetIME(phKLs[iKL], pImePro);
break;
}
}
}
}
else
{
for (INT iKL = 0; iKL < nLayouts; ++iKL)
{
result = Imm32IMPGetIME(phKLs[iKL], pImePro);
if (result)
break;
}
}
ImmLocalFree(phKLs);
return result;
}
/***********************************************************************
* ImmIMPSetIMEA(IMM32.@)
*/
BOOL WINAPI ImmIMPSetIMEA(HWND hWnd, LPIMEPROA pImePro)
BOOL WINAPI
ImmIMPSetIMEA(
_In_opt_ HWND hWnd,
_Inout_ LPIMEPROA pImePro)
{
FIXME("(%p, %p)\n", hWnd, pImePro);
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
TRACE("(%p, %p)\n", hWnd, pImePro);
ASSERT(pImePro);
IMEPROW ProW;
if (!Imm32IsSystemJapaneseOrKorean())
{
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
}
if (pImePro->szName[0])
{
/* pImePro->szName is BYTE[], so we need type cast */
if (!MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, (PSTR)pImePro->szName, -1,
ProW.szName, _countof(ProW.szName)))
{
ERR("szName: %s\n", debugstr_a((PSTR)pImePro->szName));
return FALSE;
}
ProW.szName[_countof(ProW.szName) - 1] = UNICODE_NULL; /* Avoid buffer overrun */
}
else
{
ProW.szName[0] = UNICODE_NULL;
}
return ImmIMPSetIMEW(hWnd, &ProW);
}
/***********************************************************************
* ImmIMPSetIMEW(IMM32.@)
*/
BOOL WINAPI ImmIMPSetIMEW(HWND hWnd, LPIMEPROW pImePro)
BOOL WINAPI
ImmIMPSetIMEW(
_In_opt_ HWND hWnd,
_Inout_ LPIMEPROW pImePro)
{
FIXME("(%p, %p)\n", hWnd, pImePro);
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
UNREFERENCED_PARAMETER(hWnd);
TRACE("(%p, %p)\n", hWnd, pImePro);
ASSERT(pImePro);
if (!Imm32IsSystemJapaneseOrKorean())
{
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
}
HKL hTargetKL = NULL;
if (pImePro->szName[0])
{
IMEINFOEX ImeInfoEx;
if (!ImmGetImeInfoEx(&ImeInfoEx, ImeInfoExImeFileName, pImePro->szName))
return FALSE;
hTargetKL = ImeInfoEx.hkl;
}
else
{
INT nLayouts = GetKeyboardLayoutList(0, NULL);
if (nLayouts <= 0)
{
ERR("nLayouts: %d\n", nLayouts);
return FALSE;
}
HKL *phKLs = ImmLocalAlloc(0, nLayouts * sizeof(HKL));
if (!phKLs)
{
ERR("Out of memory\n");
return FALSE;
}
if (GetKeyboardLayoutList(nLayouts, phKLs) == nLayouts)
{
for (INT iKL = 0; iKL < nLayouts; ++iKL)
{
if (!ImmIsIME(phKLs[iKL]))
{
hTargetKL = phKLs[iKL];
break;
}
}
}
else
{
ERR("KL count mismatch\n");
}
ImmLocalFree(phKLs);
}
if (hTargetKL && GetKeyboardLayout(0) != hTargetKL)
{
HWND hwndFocus = GetFocus();
if (hwndFocus)
{
PostMessageW(hwndFocus, WM_INPUTLANGCHANGEREQUEST, INPUTLANGCHANGE_SYSCHARSET,
(LPARAM)hTargetKL);
return TRUE;
}
}
return FALSE;
}