1 /* 2 * PROJECT: ReactOS Cicero 3 * LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later) 4 * PURPOSE: Locking and Unlocking IMC and IMCC handles 5 * COPYRIGHT: Copyright 2023 Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com> 6 */ 7 8 #pragma once 9 10 // struct CTFIMECONTEXT; 11 // class CIC_IMCC_LOCK<T_DATA>; 12 // class CicIMCCLock<T_DATA>; 13 // class CIC_IMC_LOCK; 14 // class CicIMCLock; 15 16 class CicInputContext; 17 18 typedef struct tagCTFIMECONTEXT 19 { 20 CicInputContext *m_pCicIC; 21 DWORD m_dwCicFlags; 22 } CTFIMECONTEXT, *PCTFIMECONTEXT; 23 24 template <typename T_DATA> 25 class CIC_IMCC_LOCK 26 { 27 protected: 28 T_DATA *m_pIMCC; 29 30 public: 31 HIMCC m_hIMCC; 32 HRESULT m_hr; 33 34 CIC_IMCC_LOCK(HIMCC hIMCC) 35 { 36 m_pIMCC = NULL; 37 m_hr = S_OK; 38 m_hIMCC = hIMCC; 39 } 40 }; 41 42 template <typename T_DATA> 43 class CicIMCCLock : public CIC_IMCC_LOCK<T_DATA> 44 { 45 public: 46 CicIMCCLock(HIMCC hIMCC) : CIC_IMCC_LOCK<T_DATA>(hIMCC) 47 { 48 this->m_hr = _LockIMCC(this->m_hIMCC, &this->m_pIMCC); 49 } 50 ~CicIMCCLock() 51 { 52 unlock(); 53 } 54 55 void unlock() 56 { 57 if (this->m_pIMCC) 58 { 59 _UnlockIMCC(this->m_hIMCC); 60 this->m_pIMCC = NULL; 61 } 62 } 63 64 operator T_DATA*() const 65 { 66 return this->m_pIMCC; 67 } 68 T_DATA& get() const 69 { 70 return *this->m_pIMCC; 71 } 72 73 protected: 74 HRESULT _LockIMCC(HIMCC hIMCC, T_DATA **pptr) 75 { 76 if (!hIMCC) 77 return E_INVALIDARG; 78 *pptr = (T_DATA*)::ImmLockIMCC(hIMCC); 79 return (*pptr ? S_OK : E_FAIL); 80 } 81 HRESULT _UnlockIMCC(HIMCC hIMCC) 82 { 83 if (!::ImmUnlockIMCC(hIMCC)) 84 return (::GetLastError() ? E_FAIL : S_OK); 85 return S_OK; 86 } 87 }; 88 89 class CIC_IMC_LOCK 90 { 91 protected: 92 LPINPUTCONTEXTDX m_pIC; 93 94 public: 95 HIMC m_hIMC; 96 HRESULT m_hr; 97 DWORD m_dw3; 98 99 CIC_IMC_LOCK(HIMC hIMC) 100 { 101 m_pIC = NULL; 102 m_hIMC = hIMC; 103 m_hr = S_OK; 104 m_dw3 = 0; 105 } 106 107 BOOL Invalid() const 108 { 109 return (!m_pIC || m_hr != S_OK); 110 } 111 }; 112 113 class CicIMCLock : public CIC_IMC_LOCK 114 { 115 public: 116 CicIMCLock(HIMC hIMC) : CIC_IMC_LOCK(hIMC) 117 { 118 m_hr = _LockIMC(hIMC, &m_pIC); 119 } 120 ~CicIMCLock() 121 { 122 unlock(); 123 } 124 125 void unlock() 126 { 127 if (m_pIC) 128 { 129 _UnlockIMC(m_hIMC); 130 m_pIC = NULL; 131 } 132 } 133 134 void InitContext() 135 { 136 if (!(m_pIC->fdwInit & INIT_COMPFORM)) 137 m_pIC->cfCompForm.dwStyle = 0; 138 for (UINT i = 0; i < 4; ++i) 139 m_pIC->cfCandForm[i].dwStyle = 0; 140 } 141 142 BOOL ValidCompositionString() 143 { 144 if (ImmGetIMCCSize(m_pIC->hCompStr) < sizeof(COMPOSITIONSTRING)) 145 return FALSE; 146 147 CicIMCCLock<COMPOSITIONSTRING> imccLock(m_pIC->hCompStr); 148 if (!imccLock) 149 return FALSE; 150 151 return imccLock.get().dwCompStrLen > 0; 152 } 153 154 BOOL ClearCand(); 155 156 BOOL UseVerticalCompWindow() const 157 { 158 return m_pIC->cfCompForm.dwStyle && ((m_pIC->lfFont.A.lfEscapement / 900) % 4 == 3); 159 } 160 161 operator INPUTCONTEXTDX*() const 162 { 163 return m_pIC; 164 } 165 INPUTCONTEXTDX& get() const 166 { 167 return *m_pIC; 168 } 169 170 protected: 171 HRESULT _LockIMC(HIMC hIMC, LPINPUTCONTEXTDX *ppIC) 172 { 173 if (!hIMC) 174 return E_INVALIDARG; 175 176 LPINPUTCONTEXTDX pIC = (LPINPUTCONTEXTDX)ImmLockIMC(hIMC); 177 *ppIC = pIC; 178 return (pIC ? S_OK : E_FAIL); 179 } 180 HRESULT _UnlockIMC(HIMC hIMC) 181 { 182 return ::ImmUnlockIMC(hIMC) ? S_OK : E_FAIL; 183 } 184 }; 185