https://git.reactos.org/?p=reactos.git;a=commitdiff;h=6d100d5b291ca1048ad24…
commit 6d100d5b291ca1048ad24accee603c718de6cce2
Author: Katayama Hirofumi MZ <katayama.hirofumi.mz(a)gmail.com>
AuthorDate: Tue Dec 19 15:23:12 2023 +0900
Commit: GitHub <noreply(a)github.com>
CommitDate: Tue Dec 19 15:23:12 2023 +0900
[MSCTFIME][SDK] Implement CtfImeIsGuidMapEnable (#6195)
- Add link to imm32.dll.
- Add <cicero/imclock.h>.
- Add INIT_GUIDMAP constant to <immdev.h>.
- Implement CtfImeIsGuidMapEnable by using them.
CORE-19360
---
dll/ime/msctfime/CMakeLists.txt | 2 +-
dll/ime/msctfime/msctfime.cpp | 21 ++++-
dll/ime/msctfime/msctfime.h | 1 +
sdk/include/ddk/immdev.h | 1 +
sdk/include/reactos/cicero/imclock.h | 145 +++++++++++++++++++++++++++++++++++
5 files changed, 166 insertions(+), 4 deletions(-)
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 <cicero/cicbase.h>
#include <cicero/osinfo.h>
#include <cicero/CModulePath.h>
+#include <cicero/imclock.h>
#include <wine/debug.h>
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
<katayama.hirofumi.mz(a)gmail.com>
+ */
+
+#pragma once
+
+// class _IMCCLock<T_DATA>;
+// class InternalIMCCLock<T_DATA>;
+// class _IMCLock;
+// class IMCLock;
+
+template <typename T_DATA>
+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 <typename T_DATA>
+class InternalIMCCLock : public _IMCCLock<T_DATA>
+{
+public:
+ InternalIMCCLock(HIMCC hIMCC) : _IMCCLock<T_DATA>(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<COMPOSITIONSTRING> 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;
+ }
+};