diff --git a/dll/ime/msctfime/CMakeLists.txt b/dll/ime/msctfime/CMakeLists.txt index 10f18eab2d0..3dea866e674 100644 --- a/dll/ime/msctfime/CMakeLists.txt +++ b/dll/ime/msctfime/CMakeLists.txt @@ -17,5 +17,5 @@ add_library(msctfime MODULE set_module_type(msctfime win32dll UNICODE) set_target_properties(msctfime PROPERTIES SUFFIX ".ime") target_link_libraries(msctfime wine uuid) -add_importlibs(msctfime user32 gdi32 advapi32 comctl32 msvcrt kernel32 ntdll) +add_importlibs(msctfime imm32 user32 gdi32 advapi32 comctl32 msvcrt kernel32 ntdll) add_cd_file(TARGET msctfime DESTINATION reactos/system32 FOR all) diff --git a/dll/ime/msctfime/msctfime.cpp b/dll/ime/msctfime/msctfime.cpp index 8bf27f62d61..2b6404f4819 100644 --- a/dll/ime/msctfime/msctfime.cpp +++ b/dll/ime/msctfime/msctfime.cpp @@ -766,14 +766,29 @@ CtfImeGetGuidAtom( return E_FAIL; } +/*********************************************************************** + * CtfImeIsGuidMapEnable (MSCTFIME.@) + * + * @implemented + */ EXTERN_C BOOL WINAPI CtfImeIsGuidMapEnable( _In_ HIMC hIMC) { - FIXME("stub:(%p)\n", hIMC); - return FALSE; -} + TRACE("(%p)\n", hIMC); + BOOL ret = FALSE; + HRESULT hr; + IMCLock imcLock(hIMC); + + hr = imcLock.m_hr; + if (!imcLock) + hr = E_FAIL; + if (SUCCEEDED(hr)) + ret = !!(imcLock.m_pIC->fdwInit & INIT_GUIDMAP); + + return ret; +} /*********************************************************************** * CtfImeCreateThreadMgr (MSCTFIME.@) diff --git a/dll/ime/msctfime/msctfime.h b/dll/ime/msctfime/msctfime.h index 9e492902348..987ccf46d76 100644 --- a/dll/ime/msctfime/msctfime.h +++ b/dll/ime/msctfime/msctfime.h @@ -23,6 +23,7 @@ #include #include #include +#include #include diff --git a/sdk/include/ddk/immdev.h b/sdk/include/ddk/immdev.h index 5fb513da443..5dfb82f3763 100644 --- a/sdk/include/ddk/immdev.h +++ b/sdk/include/ddk/immdev.h @@ -159,6 +159,7 @@ typedef struct INPUTCONTEXTDX #define INIT_LOGFONT 0x00000008 #define INIT_COMPFORM 0x00000010 #define INIT_SOFTKBDPOS 0x00000020 +#define INIT_GUIDMAP 0x00000040 // bits for INPUTCONTEXTDX.dwChange #define INPUTCONTEXTDX_CHANGE_OPEN 0x1 diff --git a/sdk/include/reactos/cicero/imclock.h b/sdk/include/reactos/cicero/imclock.h new file mode 100644 index 00000000000..0a2ff2368a8 --- /dev/null +++ b/sdk/include/reactos/cicero/imclock.h @@ -0,0 +1,145 @@ +/* + * PROJECT: ReactOS Cicero + * LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later) + * PURPOSE: Locking and Unlocking IMC and IMCC handles + * COPYRIGHT: Copyright 2023 Katayama Hirofumi MZ + */ + +#pragma once + +// class _IMCCLock; +// class InternalIMCCLock; +// class _IMCLock; +// class IMCLock; + +template +class _IMCCLock +{ +public: + T_DATA *m_pIMCC; + HIMCC m_hIMCC; + HRESULT m_hr; + + _IMCCLock(HIMCC hIMCC) + { + m_pIMCC = NULL; + m_hr = S_OK; + m_hIMCC = hIMCC; + } +}; + +template +class InternalIMCCLock : public _IMCCLock +{ +public: + InternalIMCCLock(HIMCC hIMCC) : _IMCCLock(hIMCC) + { + if (hIMCC) + _LockIMCC(this->m_hIMCC, &this->m_pIMCC); + } + ~InternalIMCCLock() + { + if (this->m_pIMCC) + _UnlockIMCC(this->m_hIMCC); + } + operator T_DATA*() const + { + return this->m_pIMCC; + } + +protected: + HRESULT _LockIMCC(HIMCC hIMCC, T_DATA **pptr) + { + if (!hIMCC) + return E_INVALIDARG; + *pptr = (T_DATA*)::ImmLockIMCC(hIMCC); + return (*pptr ? S_OK : E_FAIL); + } + HRESULT _UnlockIMCC(HIMCC hIMCC) + { + if (!::ImmUnlockIMCC(hIMCC)) + return (::GetLastError() ? E_FAIL : S_OK); + return S_OK; + } +}; + +class _IMCLock +{ +public: + LPINPUTCONTEXTDX m_pIC; + HIMC m_hIMC; + HRESULT m_hr; + DWORD m_dw3; + + _IMCLock(HIMC hIMC) + { + m_pIC = NULL; + m_hIMC = hIMC; + m_hr = S_OK; + m_dw3 = 0; + } + + BOOL Invalid() const + { + return (!m_pIC || m_hr != S_OK); + } +}; + +class IMCLock : public _IMCLock +{ +public: + IMCLock(HIMC hIMC) : _IMCLock(hIMC) + { + m_hr = _LockIMC(hIMC, &m_pIC); + } + ~IMCLock() + { + if (m_pIC) + _UnlockIMC(m_hIMC); + } + + void InitContext() + { + if (!(m_pIC->fdwInit & INIT_COMPFORM)) + m_pIC->cfCompForm.dwStyle = 0; + for (UINT i = 0; i < 4; ++i) + m_pIC->cfCandForm[i].dwStyle = 0; + } + + BOOL ValidCompositionString() + { + if (ImmGetIMCCSize(m_pIC->hCompStr) < sizeof(COMPOSITIONSTRING)) + return FALSE; + + InternalIMCCLock imccLock(m_pIC->hCompStr); + if (!imccLock) + return FALSE; + + return imccLock.m_pIMCC->dwCompStrLen > 0; + } + + BOOL UseVerticalCompWindow() const + { + return m_pIC->cfCompForm.dwStyle && ((m_pIC->lfFont.A.lfEscapement / 900) % 4 == 3); + } + + operator INPUTCONTEXTDX*() const + { + return m_pIC; + } + +protected: + HRESULT _LockIMC(HIMC hIMC, LPINPUTCONTEXTDX *ppIC) + { + if (!hIMC) + return E_INVALIDARG; + + LPINPUTCONTEXTDX pIC = (LPINPUTCONTEXTDX)ImmLockIMC(hIMC); + *ppIC = pIC; + return (pIC ? S_OK : E_FAIL); + } + HRESULT _UnlockIMC(HIMC hIMC) + { + return ::ImmUnlockIMC(hIMC) ? S_OK : E_FAIL; + } +};