xref: /reactos/sdk/lib/cicero/cicimc.h (revision 0c2cdcae)
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