diff --git a/dll/win32/imm32/CMakeLists.txt b/dll/win32/imm32/CMakeLists.txt index abf2dadc97f..97b7ea2f889 100644 --- a/dll/win32/imm32/CMakeLists.txt +++ b/dll/win32/imm32/CMakeLists.txt @@ -14,6 +14,7 @@ list(APPEND SOURCE guideline.c ime.c imemenu.c + imepro.c imm.c keymsg.c regword.c diff --git a/dll/win32/imm32/imepro.c b/dll/win32/imm32/imepro.c new file mode 100644 index 00000000000..e5f3609de2b --- /dev/null +++ b/dll/win32/imm32/imepro.c @@ -0,0 +1,138 @@ +/* + * PROJECT: ReactOS IMM32 + * LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later) + * PURPOSE: Implementing ImmIMP* functions + * COPYRIGHT: Copyright 2020-2025 Katayama Hirofumi MZ + */ + +#include "precomp.h" + +WINE_DEFAULT_DEBUG_CHANNEL(imm); + +/* + * An IMEPROA/IMEPROW structure is an IME program information. + * The ImmIMP* functions just treat these information. + */ + +static VOID +Imm32ConvertImeProWideToAnsi(_In_ const IMEPROW *pProW, _Out_ PIMEPROA pProA) +{ + pProA->hWnd = pProW->hWnd; + pProA->InstDate = pProW->InstDate; + pProA->wVersion = pProW->wVersion; + + WideCharToMultiByte(CP_ACP, 0, pProW->szDescription, -1, + (PSTR)pProA->szDescription, _countof(pProA->szDescription), NULL, NULL); + pProA->szDescription[_countof(pProA->szDescription) - 1] = ANSI_NULL; /* Avoid buffer overrun */ + + WideCharToMultiByte(CP_ACP, 0, pProW->szName, -1, + (PSTR)pProA->szName, _countof(pProA->szName), NULL, NULL); + pProA->szName[_countof(pProA->szName) - 1] = ANSI_NULL; /* Avoid buffer overrun */ + + pProA->szOptions[0] = ANSI_NULL; +} + +static BOOL +Imm32IMPGetIME(_In_ HKL hKL, _Out_ PIMEPROW pProW) +{ + IMEINFOEX ImeInfoEx; + if (!ImmGetImeInfoEx(&ImeInfoEx, ImeInfoExKeyboardLayout, &hKL)) + return FALSE; + + pProW->hWnd = NULL; + ZeroMemory(&pProW->InstDate, sizeof(pProW->InstDate)); + pProW->wVersion = ImeInfoEx.dwImeWinVersion; + + StringCchCopyNW(pProW->szDescription, _countof(pProW->szDescription), + ImeInfoEx.wszImeDescription, _countof(ImeInfoEx.wszImeDescription)); + StringCchCopyNW(pProW->szName, _countof(pProW->szName), + ImeInfoEx.wszImeFile, _countof(ImeInfoEx.wszImeFile)); + pProW->szOptions[0] = UNICODE_NULL; + + return TRUE; +} + +/*********************************************************************** + * ImmIMPGetIMEA(IMM32.@) + */ +BOOL WINAPI +ImmIMPGetIMEA(_In_opt_ HWND hWnd, _Out_ LPIMEPROA pImePro) +{ + UNREFERENCED_PARAMETER(hWnd); + + TRACE("(%p, %p)\n", hWnd, pImePro); + + if (!Imm32IsSystemJapaneseOrKorean()) + { + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; + } + + IMEPROW ImeProW; + HKL hKL = GetKeyboardLayout(0); + if (!Imm32IMPGetIME(hKL, &ImeProW)) + return FALSE; + + Imm32ConvertImeProWideToAnsi(&ImeProW, pImePro); + return TRUE; +} + +/*********************************************************************** + * ImmIMPGetIMEW(IMM32.@) + */ +BOOL WINAPI +ImmIMPGetIMEW(_In_opt_ HWND hWnd, _Out_ LPIMEPROW pImePro) +{ + UNREFERENCED_PARAMETER(hWnd); + + TRACE("(%p, %p)\n", hWnd, pImePro); + + if (!Imm32IsSystemJapaneseOrKorean()) + { + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; + } + + HKL hKL = GetKeyboardLayout(0); + return Imm32IMPGetIME(hKL, pImePro); +} + +/*********************************************************************** + * ImmIMPQueryIMEA(IMM32.@) + */ +BOOL WINAPI ImmIMPQueryIMEA(LPIMEPROA pImePro) +{ + FIXME("(%p)\n", pImePro); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; +} + +/*********************************************************************** + * ImmIMPQueryIMEW(IMM32.@) + */ +BOOL WINAPI ImmIMPQueryIMEW(LPIMEPROW pImePro) +{ + FIXME("(%p)\n", pImePro); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; +} + +/*********************************************************************** + * ImmIMPSetIMEA(IMM32.@) + */ +BOOL WINAPI ImmIMPSetIMEA(HWND hWnd, LPIMEPROA pImePro) +{ + FIXME("(%p, %p)\n", hWnd, pImePro); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; +} + +/*********************************************************************** + * ImmIMPSetIMEW(IMM32.@) + */ +BOOL WINAPI ImmIMPSetIMEW(HWND hWnd, LPIMEPROW pImePro) +{ + FIXME("(%p, %p)\n", hWnd, pImePro); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; +} diff --git a/dll/win32/imm32/precomp.h b/dll/win32/imm32/precomp.h index d2fee083e09..615c7f6a40a 100644 --- a/dll/win32/imm32/precomp.h +++ b/dll/win32/imm32/precomp.h @@ -120,10 +120,10 @@ LONG APIENTRY IchAnsiFromWide(LONG cchWide, LPCWSTR pchWide, UINT uCodePage); PIMEDPI APIENTRY Imm32FindOrLoadImeDpi(HKL hKL); LPINPUTCONTEXT APIENTRY Imm32InternalLockIMC(HIMC hIMC, BOOL fSelect); BOOL APIENTRY Imm32ReleaseIME(HKL hKL); -BOOL APIENTRY Imm32IsSystemJapaneseOrKorean(VOID); +BOOL Imm32IsSystemJapaneseOrKorean(VOID); BOOL APIENTRY Imm32IsCrossThreadAccess(HIMC hIMC); BOOL APIENTRY Imm32IsCrossProcessAccess(HWND hWnd); -BOOL WINAPI Imm32IsImcAnsi(HIMC hIMC); +BOOL Imm32IsImcAnsi(HIMC hIMC); #define ImeDpi_IsUnicode(pImeDpi) ((pImeDpi)->ImeInfo.fdwProperty & IME_PROP_UNICODE) @@ -168,9 +168,6 @@ HKL APIENTRY Imm32AssignNewLayout(UINT cKLs, const REG_IME *pLayouts, WORD wLang BOOL APIENTRY Imm32CopyImeFile(LPWSTR pszOldFile, LPCWSTR pszNewFile); PTHREADINFO FASTCALL Imm32CurrentPti(VOID); -HBITMAP Imm32LoadBitmapFromBytes(const BYTE *pb); -BOOL Imm32StoreBitmapToBytes(HBITMAP hbm, LPBYTE pbData, DWORD cbDataMax); - HRESULT CtfImmTIMCreateInputContext(_In_ HIMC hIMC); HRESULT CtfImmTIMDestroyInputContext(_In_ HIMC hIMC); HRESULT CtfImmCoInitialize(VOID); diff --git a/dll/win32/imm32/utils.c b/dll/win32/imm32/utils.c index c3ebb2f4d6a..00f77d26d67 100644 --- a/dll/win32/imm32/utils.c +++ b/dll/win32/imm32/utils.c @@ -65,8 +65,7 @@ Imm32UIntToStr(DWORD dwValue, ULONG nBase, LPWSTR pszBuff, USHORT cchBuff) return S_OK; } -/* Win: CheckCountry */ -BOOL APIENTRY Imm32IsSystemJapaneseOrKorean(VOID) +BOOL Imm32IsSystemJapaneseOrKorean(VOID) { LCID lcid = GetSystemDefaultLCID(); LANGID LangID = LANGIDFROMLCID(lcid); @@ -79,141 +78,7 @@ BOOL APIENTRY Imm32IsSystemJapaneseOrKorean(VOID) return TRUE; } -typedef struct tagBITMAPCOREINFO256 -{ - BITMAPCOREHEADER bmciHeader; - RGBTRIPLE bmciColors[256]; -} BITMAPCOREINFO256, *PBITMAPCOREINFO256; - -HBITMAP Imm32LoadBitmapFromBytes(const BYTE *pb) -{ - HBITMAP hbm = NULL; - const BITMAPCOREINFO256 *pbmci; - LPVOID pvBits; - DWORD ib, cbBytes, cColors; - BITMAP bm; - - cbBytes = *(const DWORD *)pb; - if (cbBytes == 0) - return NULL; - - pb += sizeof(DWORD); - ib = sizeof(DWORD); - - pbmci = (const BITMAPCOREINFO256 *)pb; - hbm = CreateDIBSection(NULL, (LPBITMAPINFO)pbmci, DIB_RGB_COLORS, &pvBits, NULL, 0); - if (!hbm || !GetObject(hbm, sizeof(BITMAP), &bm)) - { - ERR("Invalid bitmap\n"); - return NULL; - } - - switch (pbmci->bmciHeader.bcBitCount) - { - case 1: cColors = 2; break; - case 4: cColors = 16; break; - case 8: cColors = 256; break; - case 24: case 32: - cColors = 0; - break; - default: - ERR("Invalid bitmap\n"); - DeleteObject(hbm); - return NULL; - } - - ib += sizeof(BITMAPCOREHEADER); - pb += sizeof(BITMAPCOREHEADER); - - ib += cColors * sizeof(RGBTRIPLE); - pb += cColors * sizeof(RGBTRIPLE); - - ib += bm.bmWidthBytes * bm.bmHeight; - if (ib > cbBytes) - { - ERR("Invalid bitmap\n"); - DeleteObject(hbm); - return NULL; - } - RtlCopyMemory(pvBits, pb, bm.bmWidthBytes * bm.bmHeight); - - return hbm; -} - -BOOL Imm32StoreBitmapToBytes(HBITMAP hbm, LPBYTE pbData, DWORD cbDataMax) -{ - HDC hDC; - BITMAP bm; - DWORD cbBytes, cColors; - BITMAPCOREINFO256 bmci; - BOOL ret; - LPBYTE pb = pbData; - - *(LPDWORD)pb = 0; - - if (!GetObject(hbm, sizeof(BITMAP), &bm)) - { - ERR("Invalid bitmap\n"); - return FALSE; - } - - ZeroMemory(&bmci, sizeof(bmci)); - bmci.bmciHeader.bcSize = sizeof(BITMAPCOREHEADER); - bmci.bmciHeader.bcWidth = bm.bmWidth; - bmci.bmciHeader.bcHeight = bm.bmHeight; - bmci.bmciHeader.bcPlanes = 1; - bmci.bmciHeader.bcBitCount = bm.bmBitsPixel; - - switch (bm.bmBitsPixel) - { - case 1: cColors = 2; break; - case 4: cColors = 16; break; - case 8: cColors = 256; break; - case 24: case 32: - cColors = 0; - break; - default: - ERR("Invalid bitmap\n"); - return FALSE; - } - - cbBytes = sizeof(DWORD); - cbBytes += sizeof(BITMAPCOREHEADER); - cbBytes += cColors * sizeof(RGBTRIPLE); - cbBytes += bm.bmWidthBytes * bm.bmHeight; - if (cbBytes > cbDataMax) - { - ERR("Too small\n"); - return FALSE; - } - - hDC = CreateCompatibleDC(NULL); - - ret = GetDIBits(hDC, hbm, 0, bm.bmHeight, NULL, (LPBITMAPINFO)&bmci, DIB_RGB_COLORS); - - if (ret) - { - *(LPDWORD)pb = cbBytes; - pb += sizeof(DWORD); - - RtlCopyMemory(pb, &bmci.bmciHeader, sizeof(BITMAPCOREHEADER)); - pb += sizeof(BITMAPCOREHEADER); - - RtlCopyMemory(pb, &bmci.bmciColors, cColors * sizeof(RGBTRIPLE)); - pb += cColors * sizeof(RGBTRIPLE); - - ret = GetDIBits(hDC, hbm, 0, bm.bmHeight, pb, (LPBITMAPINFO)&bmci, DIB_RGB_COLORS); - if (!ret) - *(LPDWORD)pbData = 0; - } - - DeleteDC(hDC); - - return ret; -} - -// Win: IsAnsiIMC -BOOL WINAPI Imm32IsImcAnsi(HIMC hIMC) +BOOL Imm32IsImcAnsi(HIMC hIMC) { BOOL ret; PCLIENTIMC pClientImc = ImmLockClientImc(hIMC); @@ -1228,57 +1093,3 @@ DWORD WINAPI ImmGetIMCLockCount(HIMC hIMC) ImmUnlockClientImc(pClientImc); return ret; } - -/*********************************************************************** - * ImmIMPGetIMEA(IMM32.@) - */ -BOOL WINAPI ImmIMPGetIMEA(HWND hWnd, LPIMEPROA pImePro) -{ - FIXME("(%p, %p)\n", hWnd, pImePro); - return FALSE; -} - -/*********************************************************************** - * ImmIMPGetIMEW(IMM32.@) - */ -BOOL WINAPI ImmIMPGetIMEW(HWND hWnd, LPIMEPROW pImePro) -{ - FIXME("(%p, %p)\n", hWnd, pImePro); - return FALSE; -} - -/*********************************************************************** - * ImmIMPQueryIMEA(IMM32.@) - */ -BOOL WINAPI ImmIMPQueryIMEA(LPIMEPROA pImePro) -{ - FIXME("(%p)\n", pImePro); - return FALSE; -} - -/*********************************************************************** - * ImmIMPQueryIMEW(IMM32.@) - */ -BOOL WINAPI ImmIMPQueryIMEW(LPIMEPROW pImePro) -{ - FIXME("(%p)\n", pImePro); - return FALSE; -} - -/*********************************************************************** - * ImmIMPSetIMEA(IMM32.@) - */ -BOOL WINAPI ImmIMPSetIMEA(HWND hWnd, LPIMEPROA pImePro) -{ - FIXME("(%p, %p)\n", hWnd, pImePro); - return FALSE; -} - -/*********************************************************************** - * ImmIMPSetIMEW(IMM32.@) - */ -BOOL WINAPI ImmIMPSetIMEW(HWND hWnd, LPIMEPROW pImePro) -{ - FIXME("(%p, %p)\n", hWnd, pImePro); - return FALSE; -} diff --git a/sdk/include/reactos/imm32_undoc.h b/sdk/include/reactos/imm32_undoc.h index a1cfe4ce02c..71be9852f47 100644 --- a/sdk/include/reactos/imm32_undoc.h +++ b/sdk/include/reactos/imm32_undoc.h @@ -12,6 +12,7 @@ extern "C" { #endif #include +#include /* For IMEPROA/W */ #define IME_MASK (0xE0000000UL) #define SUBST_MASK (0xD0000000UL) @@ -230,6 +231,9 @@ BOOL WINAPI ImmLoadIME(_In_ HKL hKL); DWORD WINAPI ImmProcessKey(_In_ HWND, _In_ HKL, _In_ UINT, _In_ LPARAM, _In_ DWORD); 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); + HRESULT WINAPI CtfAImmActivate(_Out_opt_ HINSTANCE *phinstCtfIme); HRESULT WINAPI CtfAImmDeactivate(_In_ BOOL bDestroy); BOOL WINAPI CtfAImmIsIME(_In_ HKL hKL); @@ -254,6 +258,12 @@ CtfImmDispatchDefImeMessage( _In_ WPARAM wParam, _In_ LPARAM lParam); +#ifdef UNICODE + #define ImmIMPGetIME ImmIMPGetIMEW +#else + #define ImmIMPGetIME ImmIMPGetIMEA +#endif + #ifdef __cplusplus } // extern "C" #endif