CRITICAL_SECTION g_csLock;
CDispAttrPropCache *g_pPropCache = NULL;
-DEFINE_GUID(GUID_COMPARTMENT_CTFIME_DIMFLAGS, 0xA94C5FD2, 0xC471, 0x4031, 0x95, 0x46, 0x70, 0x9C, 0x17, 0x30, 0x0C, 0xB9);
-DEFINE_GUID(GUID_COMPARTMENT_CTFIME_CICINPUTCONTEXT, 0x85A688F7, 0x6DC8, 0x4F17, 0xA8, 0x3A, 0xB1, 0x1C, 0x09, 0xCD, 0xD7, 0xBF);
-
EXTERN_C void __cxa_pure_virtual(void)
{
ERR("__cxa_pure_virtual\n");
}
-UINT WM_MSIME_SERVICE = 0;
-UINT WM_MSIME_UIREADY = 0;
-UINT WM_MSIME_RECONVERTREQUEST = 0;
-UINT WM_MSIME_RECONVERT = 0;
-UINT WM_MSIME_DOCUMENTFEED = 0;
-UINT WM_MSIME_QUERYPOSITION = 0;
-UINT WM_MSIME_MODEBIAS = 0;
-UINT WM_MSIME_SHOWIMEPAD = 0;
-UINT WM_MSIME_MOUSE = 0;
-UINT WM_MSIME_KEYMAP = 0;
-
-/// @implemented
-BOOL IsMsImeMessage(_In_ UINT uMsg)
-{
- return (uMsg == WM_MSIME_SERVICE ||
- uMsg == WM_MSIME_UIREADY ||
- uMsg == WM_MSIME_RECONVERTREQUEST ||
- uMsg == WM_MSIME_RECONVERT ||
- uMsg == WM_MSIME_DOCUMENTFEED ||
- uMsg == WM_MSIME_QUERYPOSITION ||
- uMsg == WM_MSIME_MODEBIAS ||
- uMsg == WM_MSIME_SHOWIMEPAD ||
- uMsg == WM_MSIME_MOUSE ||
- uMsg == WM_MSIME_KEYMAP);
-}
-
-/// @implemented
-BOOL RegisterMSIMEMessage(VOID)
-{
- // Using ANSI (A) version here can reduce binary size.
- WM_MSIME_SERVICE = RegisterWindowMessageA("MSIMEService");
- WM_MSIME_UIREADY = RegisterWindowMessageA("MSIMEUIReady");
- WM_MSIME_RECONVERTREQUEST = RegisterWindowMessageA("MSIMEReconvertRequest");
- WM_MSIME_RECONVERT = RegisterWindowMessageA("MSIMEReconvert");
- WM_MSIME_DOCUMENTFEED = RegisterWindowMessageA("MSIMEDocumentFeed");
- WM_MSIME_QUERYPOSITION = RegisterWindowMessageA("MSIMEQueryPosition");
- WM_MSIME_MODEBIAS = RegisterWindowMessageA("MSIMEModeBias");
- WM_MSIME_SHOWIMEPAD = RegisterWindowMessageA("MSIMEShowImePad");
- WM_MSIME_MOUSE = RegisterWindowMessageA("MSIMEMouseOperation");
- WM_MSIME_KEYMAP = RegisterWindowMessageA("MSIMEKeyMap");
- return (WM_MSIME_SERVICE &&
- WM_MSIME_UIREADY &&
- WM_MSIME_RECONVERTREQUEST &&
- WM_MSIME_RECONVERT &&
- WM_MSIME_DOCUMENTFEED &&
- WM_MSIME_QUERYPOSITION &&
- WM_MSIME_MODEBIAS &&
- WM_MSIME_SHOWIMEPAD &&
- WM_MSIME_MOUSE &&
- WM_MSIME_KEYMAP);
-}
-
-typedef BOOLEAN (WINAPI *FN_DllShutDownInProgress)(VOID);
+typedef BOOLEAN (WINAPI *FN_DllShutdownInProgress)(VOID);
/// This function calls ntdll!RtlDllShutdownInProgress.
/// It can detect the system is shutting down or not.
/// @implemented
-EXTERN_C BOOLEAN WINAPI
-DllShutDownInProgress(VOID)
+EXTERN_C BOOLEAN WINAPI DllShutdownInProgress(VOID)
{
HMODULE hNTDLL;
- static FN_DllShutDownInProgress s_fnDllShutDownInProgress = NULL;
+ static FN_DllShutdownInProgress s_fnDllShutdownInProgress = NULL;
- if (s_fnDllShutDownInProgress)
- return s_fnDllShutDownInProgress();
+ if (s_fnDllShutdownInProgress)
+ return s_fnDllShutdownInProgress();
hNTDLL = cicGetSystemModuleHandle(L"ntdll.dll", FALSE);
- s_fnDllShutDownInProgress =
- (FN_DllShutDownInProgress)GetProcAddress(hNTDLL, "RtlDllShutdownInProgress");
- if (!s_fnDllShutDownInProgress)
+ s_fnDllShutdownInProgress =
+ (FN_DllShutdownInProgress)GetProcAddress(hNTDLL, "RtlDllShutdownInProgress");
+ if (!s_fnDllShutdownInProgress)
return FALSE;
- return s_fnDllShutDownInProgress();
+ return s_fnDllShutdownInProgress();
}
/// This function checks if the current user logon session is interactive.
}
::LeaveCriticalSection(&g_csLock);
- return hr;
-}
-
-HIMC GetActiveContext(VOID)
-{
- HWND hwndFocus = ::GetFocus();
- if (!hwndFocus)
- hwndFocus = ::GetActiveWindow();
- return ::ImmGetContext(hwndFocus);
-}
-
-/// @implemented
-HRESULT UninitDisplayAttrbuteLib(PCIC_LIBTHREAD pLibThread)
-{
- if (!pLibThread)
- return E_FAIL;
-
- if (pLibThread->m_pDisplayAttrMgr)
- {
- pLibThread->m_pDisplayAttrMgr->Release();
- pLibThread->m_pDisplayAttrMgr = NULL;
- }
-
- return S_OK;
-}
-
-/// Gets the charset from a language ID.
-/// @implemented
-BYTE GetCharsetFromLangId(_In_ DWORD dwValue)
-{
- CHARSETINFO info;
- if (!::TranslateCharsetInfo((DWORD*)(DWORD_PTR)dwValue, &info, TCI_SRCLOCALE))
- return 0;
- return info.ciCharset;
-}
-
-/// Selects or unselects the input context.
-/// @implemented
-HRESULT
-InternalSelectEx(
- _In_ HIMC hIMC,
- _In_ BOOL fSelect,
- _In_ LANGID LangID)
-{
- CicIMCLock imcLock(hIMC);
- if (!imcLock)
- imcLock.m_hr = E_FAIL;
- if (FAILED(imcLock.m_hr))
- return imcLock.m_hr;
-
- if (PRIMARYLANGID(LangID) == LANG_CHINESE)
- {
- imcLock.get().cfCandForm[0].dwStyle = 0;
- imcLock.get().cfCandForm[0].dwIndex = (DWORD)-1;
- }
-
- if (!fSelect)
- {
- imcLock.get().fdwInit &= ~INIT_GUIDMAP;
- return imcLock.m_hr;
- }
-
- if (!imcLock.ClearCand())
- return imcLock.m_hr;
-
- // Populate conversion mode
- if (!(imcLock.get().fdwInit & INIT_CONVERSION))
- {
- DWORD dwConv = (imcLock.get().fdwConversion & IME_CMODE_SOFTKBD);
- if (LangID)
- {
- if (PRIMARYLANGID(LangID) == LANG_JAPANESE)
- {
- dwConv |= IME_CMODE_ROMAN | IME_CMODE_FULLSHAPE | IME_CMODE_NATIVE;
- }
- else if (PRIMARYLANGID(LangID) != LANG_KOREAN)
- {
- dwConv |= IME_CMODE_NATIVE;
- }
- }
- imcLock.get().fdwConversion |= dwConv;
- imcLock.get().fdwInit |= INIT_CONVERSION;
- }
-
- // Populate sentence mode
- imcLock.get().fdwSentence |= IME_SMODE_PHRASEPREDICT;
-
- // Populate LOGFONT
- if (!(imcLock.get().fdwInit & INIT_LOGFONT))
- {
- // Get logical font
- LOGFONTW lf;
- HDC hDC = ::GetDC(imcLock.get().hWnd);
- HGDIOBJ hFont = GetCurrentObject(hDC, OBJ_FONT);
- ::GetObjectW(hFont, sizeof(LOGFONTW), &lf);
- ::ReleaseDC(imcLock.get().hWnd, hDC);
-
- imcLock.get().lfFont.W = lf;
- imcLock.get().fdwInit |= INIT_LOGFONT;
- }
- imcLock.get().lfFont.W.lfCharSet = GetCharsetFromLangId(LangID);
-
- imcLock.InitContext();
-
- return imcLock.m_hr;
-}
-
-/***********************************************************************
- * Compartment
- */
-
-/// @implemented
-HRESULT
-GetCompartment(
- IUnknown *pUnknown,
- REFGUID rguid,
- ITfCompartment **ppComp,
- BOOL bThread)
-{
- *ppComp = NULL;
-
- ITfThreadMgr *pThreadMgr = NULL;
- ITfCompartmentMgr *pCompMgr = NULL;
-
- HRESULT hr;
- if (bThread)
- {
- hr = pUnknown->QueryInterface(IID_ITfThreadMgr, (void **)&pThreadMgr);
- if (FAILED(hr))
- return hr;
-
- hr = pThreadMgr->GetGlobalCompartment(&pCompMgr);
- }
- else
- {
- hr = pUnknown->QueryInterface(IID_ITfCompartmentMgr, (void **)&pCompMgr);
- }
-
- if (SUCCEEDED(hr))
- {
- hr = E_FAIL;
- if (pCompMgr)
- {
- hr = pCompMgr->GetCompartment(rguid, ppComp);
- pCompMgr->Release();
- }
- }
-
- if (pThreadMgr)
- pThreadMgr->Release();
-
- return hr;
-}
-
-/// @implemented
-HRESULT
-SetCompartmentDWORD(
- TfEditCookie cookie,
- IUnknown *pUnknown,
- REFGUID rguid,
- DWORD dwValue,
- BOOL bThread)
-{
- ITfCompartment *pComp = NULL;
- HRESULT hr = GetCompartment(pUnknown, rguid, &pComp, bThread);
- if (FAILED(hr))
- return hr;
-
- VARIANT vari;
- V_I4(&vari) = dwValue;
- V_VT(&vari) = VT_I4;
- hr = pComp->SetValue(cookie, &vari);
-
- pComp->Release();
- return hr;
-}
-
-/// @implemented
-HRESULT
-GetCompartmentDWORD(
- IUnknown *pUnknown,
- REFGUID rguid,
- LPDWORD pdwValue,
- BOOL bThread)
-{
- *pdwValue = 0;
-
- ITfCompartment *pComp = NULL;
- HRESULT hr = GetCompartment(pUnknown, rguid, &pComp, bThread);
- if (FAILED(hr))
- return hr;
-
- VARIANT vari;
- hr = pComp->GetValue(&vari);
- if (hr == S_OK)
- *pdwValue = V_I4(&vari);
-
- pComp->Release();
- return hr;
-}
-
-/// @implemented
-HRESULT
-SetCompartmentUnknown(
- TfEditCookie cookie,
- IUnknown *pUnknown,
- REFGUID rguid,
- IUnknown *punkValue)
-{
- ITfCompartment *pComp = NULL;
- HRESULT hr = GetCompartment(pUnknown, rguid, &pComp, FALSE);
- if (FAILED(hr))
- return hr;
-
- VARIANT vari;
- V_UNKNOWN(&vari) = punkValue;
- V_VT(&vari) = VT_UNKNOWN;
- hr = pComp->SetValue(cookie, &vari);
-
- pComp->Release();
- return hr;
-}
-
-/// @implemented
-HRESULT
-ClearCompartment(
- TfClientId tid,
- IUnknown *pUnknown,
- REFGUID rguid,
- BOOL bThread)
-{
- ITfCompartmentMgr *pCompMgr = NULL;
- ITfThreadMgr *pThreadMgr = NULL;
-
- HRESULT hr;
- if (bThread)
- {
- hr = pUnknown->QueryInterface(IID_ITfThreadMgr, (void **)&pThreadMgr);
- if (FAILED(hr))
- return hr;
-
- hr = pThreadMgr->GetGlobalCompartment(&pCompMgr);
- }
- else
- {
- hr = pUnknown->QueryInterface(IID_ITfCompartmentMgr, (void **)&pCompMgr);
- }
-
- if (SUCCEEDED(hr))
- {
- hr = E_FAIL;
- if (pCompMgr)
- {
- hr = pCompMgr->ClearCompartment(tid, rguid);
- pCompMgr->Release();
- }
- }
-
- if (pThreadMgr)
- pThreadMgr->Release();
-
- return hr;
-}
-
-typedef struct CESMAP
-{
- ITfCompartment *m_pComp;
- DWORD m_dwCookie;
-} CESMAP, *PCESMAP;
-
-typedef INT (CALLBACK *FN_EVENTSINK)(LPVOID, REFGUID);
-
-class CCompartmentEventSink : public ITfCompartmentEventSink
-{
- CicArray<CESMAP> m_array;
- LONG m_cRefs;
- FN_EVENTSINK m_fnEventSink;
- LPVOID m_pUserData;
-
-public:
- CCompartmentEventSink(FN_EVENTSINK fnEventSink, LPVOID pUserData);
- virtual ~CCompartmentEventSink();
-
- HRESULT _Advise(IUnknown *pUnknown, REFGUID rguid, BOOL bThread);
- HRESULT _Unadvise();
-
- // IUnknown interface
- STDMETHODIMP QueryInterface(REFIID riid, LPVOID* ppvObj) override;
- STDMETHODIMP_(ULONG) AddRef() override;
- STDMETHODIMP_(ULONG) Release() override;
-
- // ITfCompartmentEventSink interface
- STDMETHODIMP OnChange(REFGUID rguid) override;
-};
-
-/// @implemented
-CCompartmentEventSink::CCompartmentEventSink(FN_EVENTSINK fnEventSink, LPVOID pUserData)
- : m_array()
- , m_cRefs(1)
- , m_fnEventSink(fnEventSink)
- , m_pUserData(pUserData)
-{
-}
-
-/// @implemented
-CCompartmentEventSink::~CCompartmentEventSink()
-{
-}
-
-/// @implemented
-STDMETHODIMP CCompartmentEventSink::QueryInterface(REFIID riid, LPVOID* ppvObj)
-{
- if (IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, IID_ITfCompartmentEventSink))
- {
- *ppvObj = this;
- AddRef();
- return S_OK;
- }
-
- *ppvObj = NULL;
- return E_NOINTERFACE;
-}
-
-/// @implemented
-STDMETHODIMP_(ULONG) CCompartmentEventSink::AddRef()
-{
- return ::InterlockedIncrement(&m_cRefs);
-}
-
-/// @implemented
-STDMETHODIMP_(ULONG) CCompartmentEventSink::Release()
-{
- if (::InterlockedDecrement(&m_cRefs) == 0)
- {
- delete this;
- return 0;
- }
- return m_cRefs;
-}
-
-/// @implemented
-STDMETHODIMP CCompartmentEventSink::OnChange(REFGUID rguid)
-{
- return m_fnEventSink(m_pUserData, rguid);
-}
-
-/// @implemented
-HRESULT
-CCompartmentEventSink::_Advise(IUnknown *pUnknown, REFGUID rguid, BOOL bThread)
-{
- CESMAP *pCesMap = m_array.Append(1);
- if (!pCesMap)
- return E_OUTOFMEMORY;
-
- ITfSource *pSource = NULL;
-
- HRESULT hr = GetCompartment(pUnknown, rguid, &pCesMap->m_pComp, bThread);
- if (FAILED(hr))
- {
- hr = pCesMap->m_pComp->QueryInterface(IID_ITfSource, (void **)&pSource);
- if (FAILED(hr))
- {
- hr = pSource->AdviseSink(IID_ITfCompartmentEventSink, this, &pCesMap->m_dwCookie);
- if (FAILED(hr))
- {
- if (pCesMap->m_pComp)
- {
- pCesMap->m_pComp->Release();
- pCesMap->m_pComp = NULL;
- }
- m_array.Remove(m_array.size() - 1, 1);
- }
- else
- {
- hr = S_OK;
- }
- }
- }
-
- if (pSource)
- pSource->Release();
-
- return hr;
-}
-
-/// @implemented
-HRESULT CCompartmentEventSink::_Unadvise()
-{
- CESMAP *pCesMap = m_array.data();
- size_t cItems = m_array.size();
- if (!cItems)
- return S_OK;
-
- do
- {
- ITfSource *pSource = NULL;
- HRESULT hr = pCesMap->m_pComp->QueryInterface(IID_ITfSource, (void **)&pSource);
- if (SUCCEEDED(hr))
- pSource->UnadviseSink(pCesMap->m_dwCookie);
-
- if (pCesMap->m_pComp)
- {
- pCesMap->m_pComp->Release();
- pCesMap->m_pComp = NULL;
- }
-
- if (pSource)
- pSource->Release();
-
- ++pCesMap;
- --cItems;
- } while (cItems);
-
- return S_OK;
-}
-
-class CInputContextOwnerCallBack;
-class CInputContextOwner;
-
-typedef INT (CALLBACK *FN_ENDEDIT)(INT, LPVOID, LPVOID);
-typedef INT (CALLBACK *FN_LAYOUTCHANGE)(UINT nType, FN_ENDEDIT fnEndEdit, ITfContextView *pView);
-
-class CTextEventSink : public ITfTextEditSink, ITfTextLayoutSink
-{
-protected:
- LONG m_cRefs;
- IUnknown *m_pUnknown;
- DWORD m_dwEditSinkCookie;
- DWORD m_dwLayoutSinkCookie;
- union
- {
- UINT m_uFlags;
- FN_LAYOUTCHANGE m_fnLayoutChange;
- };
- FN_ENDEDIT m_fnEndEdit;
- LPVOID m_pCallbackPV;
-
-public:
- CTextEventSink(FN_ENDEDIT fnEndEdit, LPVOID pCallbackPV);
- virtual ~CTextEventSink();
-
- HRESULT _Advise(IUnknown *pUnknown, UINT uFlags);
- HRESULT _Unadvise();
-
- // IUnknown interface
- STDMETHODIMP QueryInterface(REFIID riid, LPVOID* ppvObj) override;
- STDMETHODIMP_(ULONG) AddRef() override;
- STDMETHODIMP_(ULONG) Release() override;
-
- // ITfTextEditSink interface
- STDMETHODIMP OnEndEdit(
- ITfContext *pic,
- TfEditCookie ecReadOnly,
- ITfEditRecord *pEditRecord) override;
-
- // ITfTextLayoutSink interface
- STDMETHODIMP
- OnLayoutChange(
- ITfContext *pContext,
- TfLayoutCode lcode,
- ITfContextView *pContextView) override;
-};
-
-/// @implemented
-CTextEventSink::CTextEventSink(FN_ENDEDIT fnEndEdit, LPVOID pCallbackPV)
-{
- m_cRefs = 1;
- m_pUnknown = NULL;
- m_dwEditSinkCookie = (DWORD)-1;
- m_dwLayoutSinkCookie = (DWORD)-1;
- m_fnLayoutChange = NULL;
- m_fnEndEdit = fnEndEdit;
- m_pCallbackPV = pCallbackPV;
-}
-
-/// @implemented
-CTextEventSink::~CTextEventSink()
-{
-}
-
-/// @implemented
-STDMETHODIMP CTextEventSink::QueryInterface(REFIID riid, LPVOID* ppvObj)
-{
- if (IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, IID_ITfTextEditSink))
- {
- *ppvObj = this;
- AddRef();
- return S_OK;
- }
- if (IsEqualIID(riid, IID_ITfTextLayoutSink))
- {
- *ppvObj = static_cast<ITfTextLayoutSink*>(this);
- AddRef();
- return S_OK;
- }
- return E_NOINTERFACE;
-}
-
-/// @implemented
-STDMETHODIMP_(ULONG) CTextEventSink::AddRef()
-{
- return ::InterlockedIncrement(&m_cRefs);
-}
-
-/// @implemented
-STDMETHODIMP_(ULONG) CTextEventSink::Release()
-{
- if (::InterlockedDecrement(&m_cRefs) == 0)
- {
- delete this;
- return 0;
- }
- return m_cRefs;
-}
-
-struct TEXT_EVENT_SINK_END_EDIT
-{
- TfEditCookie m_ecReadOnly;
- ITfEditRecord *m_pEditRecord;
- ITfContext *m_pContext;
-};
-
-/// @implemented
-STDMETHODIMP CTextEventSink::OnEndEdit(
- ITfContext *pic,
- TfEditCookie ecReadOnly,
- ITfEditRecord *pEditRecord)
-{
- TEXT_EVENT_SINK_END_EDIT Data = { ecReadOnly, pEditRecord, pic };
- return m_fnEndEdit(1, m_pCallbackPV, (LPVOID)&Data);
-}
-
-/// @implemented
-STDMETHODIMP CTextEventSink::OnLayoutChange(
- ITfContext *pContext,
- TfLayoutCode lcode,
- ITfContextView *pContextView)
-{
- switch (lcode)
- {
- case TF_LC_CREATE:
- return m_fnLayoutChange(3, m_fnEndEdit, pContextView);
- case TF_LC_CHANGE:
- return m_fnLayoutChange(2, m_fnEndEdit, pContextView);
- case TF_LC_DESTROY:
- return m_fnLayoutChange(4, m_fnEndEdit, pContextView);
- default:
- return E_INVALIDARG;
- }
-}
-
-/// @implemented
-HRESULT CTextEventSink::_Advise(IUnknown *pUnknown, UINT uFlags)
-{
- m_pUnknown = NULL;
- m_uFlags = uFlags;
-
- ITfSource *pSource = NULL;
- HRESULT hr = pUnknown->QueryInterface(IID_ITfSource, (void**)&pSource);
- if (SUCCEEDED(hr))
- {
- ITfTextEditSink *pSink = static_cast<ITfTextEditSink*>(this);
- if (uFlags & 1)
- hr = pSource->AdviseSink(IID_ITfTextEditSink, pSink, &m_dwEditSinkCookie);
- if (SUCCEEDED(hr) && (uFlags & 2))
- hr = pSource->AdviseSink(IID_ITfTextLayoutSink, pSink, &m_dwLayoutSinkCookie);
-
- if (SUCCEEDED(hr))
- {
- m_pUnknown = pUnknown;
- pUnknown->AddRef();
- }
- else
- {
- pSource->UnadviseSink(m_dwEditSinkCookie);
- }
- }
-
- if (pSource)
- pSource->Release();
-
- return hr;
-}
-
-/// @implemented
-HRESULT CTextEventSink::_Unadvise()
-{
- if (!m_pUnknown)
- return E_FAIL;
-
- ITfSource *pSource = NULL;
- HRESULT hr = m_pUnknown->QueryInterface(IID_ITfSource, (void**)&pSource);
- if (SUCCEEDED(hr))
- {
- if (m_uFlags & 1)
- hr = pSource->UnadviseSink(m_dwEditSinkCookie);
- if (m_uFlags & 2)
- hr = pSource->UnadviseSink(m_dwLayoutSinkCookie);
-
- pSource->Release();
- }
-
- m_pUnknown->Release();
- m_pUnknown = NULL;
-
- return E_NOTIMPL;
-}
-
-/***********************************************************************
- * CicInputContext
- *
- * The msctfime.ime's input context.
- */
-class CicInputContext
- : public ITfCleanupContextSink
- , public ITfContextOwnerCompositionSink
- , public ITfCompositionSink
-{
-public:
- LONG m_cRefs;
- HIMC m_hIMC;
- ITfDocumentMgr *m_pDocumentMgr;
- ITfContext *m_pContext;
- ITfContextOwnerServices *m_pContextOwnerServices;
- CInputContextOwnerCallBack *m_pICOwnerCallback;
- CTextEventSink *m_pTextEventSink;
- CCompartmentEventSink *m_pCompEventSink1;
- CCompartmentEventSink *m_pCompEventSink2;
- CInputContextOwner *m_pInputContextOwner;
- DWORD m_dwUnknown3[3];
- DWORD m_dwUnknown4[2];
- DWORD m_dwQueryPos;
- DWORD m_dwUnknown5;
- GUID m_guid;
- DWORD m_dwUnknown6[11];
- BOOL m_bSelecting;
- DWORD m_dwUnknown6_5;
- LONG m_cCompLocks;
- DWORD m_dwUnknown7[5];
- WORD m_cGuidAtoms;
- WORD m_padding;
- DWORD m_adwGuidAtoms[256];
- DWORD m_dwUnknown8[17];
- TfClientId m_clientId;
- DWORD m_dwUnknown9;
-
-public:
- CicInputContext(
- _In_ TfClientId cliendId,
- _Inout_ PCIC_LIBTHREAD pLibThread,
- _In_ HIMC hIMC);
- virtual ~CicInputContext() { }
-
- // IUnknown interface
- STDMETHODIMP QueryInterface(REFIID riid, LPVOID* ppvObj) override;
- STDMETHODIMP_(ULONG) AddRef() override;
- STDMETHODIMP_(ULONG) Release() override;
-
- // ITfCleanupContextSink interface
- STDMETHODIMP OnCleanupContext(_In_ TfEditCookie ecWrite, _Inout_ ITfContext *pic) override;
-
- // ITfContextOwnerCompositionSink interface
- STDMETHODIMP OnStartComposition(ITfCompositionView *pComposition, BOOL *pfOk) override;
- STDMETHODIMP OnUpdateComposition(ITfCompositionView *pComposition, ITfRange *pRangeNew) override;
- STDMETHODIMP OnEndComposition(ITfCompositionView *pComposition) override;
-
- // ITfCompositionSink interface
- STDMETHODIMP OnCompositionTerminated(TfEditCookie ecWrite, ITfComposition *pComposition) override;
-
- HRESULT
- GetGuidAtom(
- _Inout_ CicIMCLock& imcLock,
- _In_ BYTE iAtom,
- _Out_opt_ LPDWORD pdwGuidAtom);
-
- HRESULT CreateInputContext(_Inout_ ITfThreadMgr *pThreadMgr, _Inout_ CicIMCLock& imcLock);
- HRESULT DestroyInputContext();
-};
-
-/// @unimplemented
-CicInputContext::CicInputContext(
- _In_ TfClientId cliendId,
- _Inout_ PCIC_LIBTHREAD pLibThread,
- _In_ HIMC hIMC)
-{
- m_hIMC = hIMC;
- m_guid = GUID_NULL;
- m_dwQueryPos = 0;
- m_cRefs = 1;
-}
-
-/// @implemented
-STDMETHODIMP CicInputContext::QueryInterface(REFIID riid, LPVOID* ppvObj)
-{
- *ppvObj = NULL;
-
- if (IsEqualIID(riid, IID_ITfContextOwnerCompositionSink))
- {
- *ppvObj = static_cast<ITfContextOwnerCompositionSink*>(this);
- AddRef();
- return S_OK;
- }
- if (IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, IID_ITfCleanupContextSink))
- {
- *ppvObj = this;
- AddRef();
- return S_OK;
- }
-
- return E_NOINTERFACE;
-}
-
-/// @implemented
-STDMETHODIMP_(ULONG) CicInputContext::AddRef()
-{
- return ::InterlockedIncrement(&m_cRefs);
-}
-
-/// @implemented
-STDMETHODIMP_(ULONG) CicInputContext::Release()
-{
- if (::InterlockedDecrement(&m_cRefs) == 0)
- {
- delete this;
- return 0;
- }
- return m_cRefs;
-}
-
-/// @implemented
-STDMETHODIMP
-CicInputContext::OnStartComposition(
- ITfCompositionView *pComposition,
- BOOL *pfOk)
-{
- if ((m_cCompLocks <= 0) || m_dwUnknown6_5)
- {
- *pfOk = TRUE;
- ++m_cCompLocks;
- }
- else
- {
- *pfOk = FALSE;
- }
- return S_OK;
-}
-
-/// @implemented
-STDMETHODIMP
-CicInputContext::OnUpdateComposition(
- ITfCompositionView *pComposition,
- ITfRange *pRangeNew)
-{
- return S_OK;
-}
-
-/// @implemented
-STDMETHODIMP
-CicInputContext::OnEndComposition(
- ITfCompositionView *pComposition)
-{
- --m_cCompLocks;
- return S_OK;
-}
-
-/// @implemented
-HRESULT
-CicInputContext::GetGuidAtom(
- _Inout_ CicIMCLock& imcLock,
- _In_ BYTE iAtom,
- _Out_opt_ LPDWORD pdwGuidAtom)
-{
- CicIMCCLock<CTFIMECONTEXT> imeContext(imcLock.get().hCompStr);
- HRESULT hr = imeContext.m_hr;
- if (!imeContext)
- hr = E_FAIL;
- if (FAILED(hr))
- return hr;
-
- hr = E_FAIL;
- if (iAtom < m_cGuidAtoms)
- {
- *pdwGuidAtom = m_adwGuidAtoms[iAtom];
- hr = S_OK;
- }
-
- return hr;
-}
-
-/// @unimplemented
-HRESULT
-CicInputContext::CreateInputContext(
- _Inout_ ITfThreadMgr *pThreadMgr,
- _Inout_ CicIMCLock& imcLock)
-{
- //FIXME
- return E_NOTIMPL;
-}
-
-/// @unimplemented
-HRESULT
-CicInputContext::DestroyInputContext()
-{
- ITfSourceSingle *pSource = NULL;
-
- if (m_pContext && m_pContext->QueryInterface(IID_ITfSourceSingle, (void **)&pSource) == S_OK)
- pSource->UnadviseSingleSink(m_clientId, IID_ITfCleanupContextSink);
-
- //FIXME: m_dwUnknown5
-
- if (m_pTextEventSink)
- {
- m_pTextEventSink->_Unadvise();
- m_pTextEventSink->Release();
- m_pTextEventSink = NULL;
- }
-
- if (m_pCompEventSink2)
- {
- m_pCompEventSink2->_Unadvise();
- m_pCompEventSink2->Release();
- m_pCompEventSink2 = NULL;
- }
-
- if (m_pCompEventSink1)
- {
- m_pCompEventSink1->_Unadvise();
- m_pCompEventSink1->Release();
- m_pCompEventSink1 = NULL;
- }
-
- //FIXME: m_pInputContextOwner
-
- if (m_pDocumentMgr)
- m_pDocumentMgr->Pop(1);
-
- if (m_pContext)
- {
- ClearCompartment(m_clientId, m_pContext, GUID_COMPARTMENT_CTFIME_CICINPUTCONTEXT, 0);
- m_pContext->Release();
- m_pContext = NULL;
- }
-
- if (m_pContextOwnerServices)
- {
- m_pContextOwnerServices->Release();
- m_pContextOwnerServices = NULL;
- }
-
- // FIXME: m_pICOwnerCallback
-
- if (m_pDocumentMgr)
- {
- m_pDocumentMgr->Release();
- m_pDocumentMgr = NULL;
- }
-
- if (pSource)
- pSource->Release();
-
- return S_OK;
-}
-
-/// @implemented
-STDMETHODIMP
-CicInputContext::OnCompositionTerminated(TfEditCookie ecWrite, ITfComposition *pComposition)
-{
- return S_OK;
-}
-
-/// Retrieves the IME information.
-/// @implemented
-HRESULT
-Inquire(
- _Out_ LPIMEINFO lpIMEInfo,
- _Out_ LPWSTR lpszWndClass,
- _In_ DWORD dwSystemInfoFlags,
- _In_ HKL hKL)
-{
- if (!lpIMEInfo)
- return E_OUTOFMEMORY;
-
- StringCchCopyW(lpszWndClass, 64, L"MSCTFIME UI");
- lpIMEInfo->dwPrivateDataSize = 0;
-
- switch (LOWORD(hKL)) // Language ID
- {
- case MAKELANGID(LANG_JAPANESE, SUBLANG_DEFAULT): // Japanese
- {
- lpIMEInfo->fdwProperty = IME_PROP_COMPLETE_ON_UNSELECT | IME_PROP_SPECIAL_UI |
- IME_PROP_AT_CARET | IME_PROP_NEED_ALTKEY |
- IME_PROP_KBD_CHAR_FIRST;
- lpIMEInfo->fdwConversionCaps = IME_CMODE_FULLSHAPE | IME_CMODE_KATAKANA |
- IME_CMODE_NATIVE;
- lpIMEInfo->fdwSentenceCaps = IME_SMODE_CONVERSATION | IME_SMODE_PLAURALCLAUSE;
- lpIMEInfo->fdwSelectCaps = SELECT_CAP_SENTENCE | SELECT_CAP_CONVERSION;
- lpIMEInfo->fdwSCSCaps = SCS_CAP_SETRECONVERTSTRING | SCS_CAP_MAKEREAD |
- SCS_CAP_COMPSTR;
- lpIMEInfo->fdwUICaps = UI_CAP_ROT90;
- break;
- }
- case MAKELANGID(LANG_KOREAN, SUBLANG_DEFAULT): // Korean
- {
- lpIMEInfo->fdwProperty = IME_PROP_COMPLETE_ON_UNSELECT | IME_PROP_SPECIAL_UI |
- IME_PROP_AT_CARET | IME_PROP_NEED_ALTKEY |
- IME_PROP_KBD_CHAR_FIRST;
- lpIMEInfo->fdwConversionCaps = IME_CMODE_FULLSHAPE | IME_CMODE_NATIVE;
- lpIMEInfo->fdwSentenceCaps = 0;
- lpIMEInfo->fdwSCSCaps = SCS_CAP_SETRECONVERTSTRING | SCS_CAP_COMPSTR;
- lpIMEInfo->fdwSelectCaps = SELECT_CAP_CONVERSION;
- lpIMEInfo->fdwUICaps = UI_CAP_ROT90;
- break;
- }
- case MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED): // Simplified Chinese
- case MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_TRADITIONAL): // Traditional Chinese
- {
- lpIMEInfo->fdwProperty = IME_PROP_SPECIAL_UI | IME_PROP_AT_CARET |
- IME_PROP_NEED_ALTKEY | IME_PROP_KBD_CHAR_FIRST;
- lpIMEInfo->fdwConversionCaps = IME_CMODE_FULLSHAPE | IME_CMODE_NATIVE;
- lpIMEInfo->fdwSentenceCaps = SELECT_CAP_CONVERSION;
- lpIMEInfo->fdwSelectCaps = 0;
- lpIMEInfo->fdwSCSCaps = SCS_CAP_SETRECONVERTSTRING | SCS_CAP_MAKEREAD |
- SCS_CAP_COMPSTR;
- lpIMEInfo->fdwUICaps = UI_CAP_ROT90;
- break;
- }
- default: // Otherwise
- {
- lpIMEInfo->fdwProperty = IME_PROP_UNICODE | IME_PROP_AT_CARET;
- lpIMEInfo->fdwConversionCaps = 0;
- lpIMEInfo->fdwSentenceCaps = 0;
- lpIMEInfo->fdwSCSCaps = 0;
- lpIMEInfo->fdwUICaps = 0;
- lpIMEInfo->fdwSelectCaps = 0;
- break;
- }
- }
-
- return S_OK;
-}
-
-class TLS;
-
-typedef INT (CALLBACK *FN_INITDOCMGR)(UINT, ITfDocumentMgr *, ITfDocumentMgr *, LPVOID);
-typedef INT (CALLBACK *FN_PUSHPOP)(UINT, ITfContext *, LPVOID);
-
-class CThreadMgrEventSink : public ITfThreadMgrEventSink
-{
-protected:
- ITfThreadMgr *m_pThreadMgr;
- DWORD m_dwCookie;
- FN_INITDOCMGR m_fnInit;
- FN_PUSHPOP m_fnPushPop;
- DWORD m_dw;
- LPVOID m_pCallbackPV;
- LONG m_cRefs;
-
-public:
- CThreadMgrEventSink(
- _In_ FN_INITDOCMGR fnInit,
- _In_ FN_PUSHPOP fnPushPop = NULL,
- _Inout_ LPVOID pvCallbackPV = NULL);
- virtual ~CThreadMgrEventSink() { }
-
- void SetCallbackPV(_Inout_ LPVOID pv);
- HRESULT _Advise(ITfThreadMgr *pThreadMgr);
- HRESULT _Unadvise();
-
- // IUnknown interface
- STDMETHODIMP QueryInterface(REFIID riid, LPVOID* ppvObj) override;
- STDMETHODIMP_(ULONG) AddRef() override;
- STDMETHODIMP_(ULONG) Release() override;
-
- // ITfThreadMgrEventSink interface
- STDMETHODIMP OnInitDocumentMgr(ITfDocumentMgr *pdim) override;
- STDMETHODIMP OnUninitDocumentMgr(ITfDocumentMgr *pdim) override;
- STDMETHODIMP OnSetFocus(ITfDocumentMgr *pdimFocus, ITfDocumentMgr *pdimPrevFocus) override;
- STDMETHODIMP OnPushContext(ITfContext *pic) override;
- STDMETHODIMP OnPopContext(ITfContext *pic) override;
-
- static INT CALLBACK DIMCallback(
- UINT nCode,
- ITfDocumentMgr *pDocMgr1,
- ITfDocumentMgr *pDocMgr2,
- LPVOID pUserData);
-};
-
-/// @implemented
-CThreadMgrEventSink::CThreadMgrEventSink(
- _In_ FN_INITDOCMGR fnInit,
- _In_ FN_PUSHPOP fnPushPop,
- _Inout_ LPVOID pvCallbackPV)
-{
- m_fnInit = fnInit;
- m_fnPushPop = fnPushPop;
- m_pCallbackPV = pvCallbackPV;
- m_cRefs = 1;
-}
-
-/// @implemented
-STDMETHODIMP CThreadMgrEventSink::QueryInterface(REFIID riid, LPVOID* ppvObj)
-{
- if (IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, IID_ITfThreadMgrEventSink))
- {
- *ppvObj = this;
- AddRef();
- return S_OK;
- }
- *ppvObj = NULL;
- return E_NOINTERFACE;
-}
-
-/// @implemented
-STDMETHODIMP_(ULONG) CThreadMgrEventSink::AddRef()
-{
- return ::InterlockedIncrement(&m_cRefs);
-}
-
-/// @implemented
-STDMETHODIMP_(ULONG) CThreadMgrEventSink::Release()
-{
- if (::InterlockedDecrement(&m_cRefs) == 0)
- {
- delete this;
- return 0;
- }
- return m_cRefs;
-}
-
-INT CALLBACK
-CThreadMgrEventSink::DIMCallback(
- UINT nCode,
- ITfDocumentMgr *pDocMgr1,
- ITfDocumentMgr *pDocMgr2,
- LPVOID pUserData)
-{
- return E_NOTIMPL;
-}
-
-STDMETHODIMP CThreadMgrEventSink::OnInitDocumentMgr(ITfDocumentMgr *pdim)
-{
- if (!m_fnInit)
- return S_OK;
- return m_fnInit(0, pdim, NULL, m_pCallbackPV);
-}
-
-STDMETHODIMP CThreadMgrEventSink::OnUninitDocumentMgr(ITfDocumentMgr *pdim)
-{
- if (!m_fnInit)
- return S_OK;
- return m_fnInit(1, pdim, NULL, m_pCallbackPV);
-}
-
-STDMETHODIMP
-CThreadMgrEventSink::OnSetFocus(ITfDocumentMgr *pdimFocus, ITfDocumentMgr *pdimPrevFocus)
-{
- if (!m_fnInit)
- return S_OK;
- return m_fnInit(2, pdimFocus, pdimPrevFocus, m_pCallbackPV);
-}
-
-STDMETHODIMP CThreadMgrEventSink::OnPushContext(ITfContext *pic)
-{
- if (!m_fnPushPop)
- return S_OK;
- return m_fnPushPop(3, pic, m_pCallbackPV);
-}
-
-STDMETHODIMP CThreadMgrEventSink::OnPopContext(ITfContext *pic)
-{
- if (!m_fnPushPop)
- return S_OK;
- return m_fnPushPop(4, pic, m_pCallbackPV);
-}
-
-void CThreadMgrEventSink::SetCallbackPV(_Inout_ LPVOID pv)
-{
- if (!m_pCallbackPV)
- m_pCallbackPV = pv;
-}
-
-HRESULT CThreadMgrEventSink::_Advise(ITfThreadMgr *pThreadMgr)
-{
- m_pThreadMgr = NULL;
-
- HRESULT hr = E_FAIL;
- ITfSource *pSource = NULL;
- if (pThreadMgr->QueryInterface(IID_ITfSource, (void **)&pSource) == S_OK &&
- pSource->AdviseSink(IID_ITfThreadMgrEventSink, this, &m_dwCookie) == S_OK)
- {
- m_pThreadMgr = pThreadMgr;
- pThreadMgr->AddRef();
- hr = S_OK;
- }
-
- if (pSource)
- pSource->Release();
-
- return hr;
-}
-
-HRESULT CThreadMgrEventSink::_Unadvise()
-{
- HRESULT hr = E_FAIL;
- ITfSource *pSource = NULL;
-
- if (m_pThreadMgr)
- {
- if (m_pThreadMgr->QueryInterface(IID_ITfSource, (void **)&pSource) == S_OK &&
- pSource->UnadviseSink(m_dwCookie) == S_OK)
- {
- hr = S_OK;
- }
-
- if (pSource)
- pSource->Release();
- }
-
- if (m_pThreadMgr)
- {
- m_pThreadMgr->Release();
- m_pThreadMgr = NULL;
- }
-
- return hr;
-}
-
-class CFunctionProviderBase : public ITfFunctionProvider
-{
-protected:
- TfClientId m_clientId;
- GUID m_guid;
- BSTR m_bstr;
- LONG m_cRefs;
-
-public:
- CFunctionProviderBase(_In_ TfClientId clientId);
- virtual ~CFunctionProviderBase();
-
- // IUnknown interface
- STDMETHODIMP QueryInterface(_In_ REFIID riid, _Out_ LPVOID* ppvObj) override;
- STDMETHODIMP_(ULONG) AddRef() override;
- STDMETHODIMP_(ULONG) Release() override;
-
- // ITfFunctionProvider interface
- STDMETHODIMP GetType(_Out_ GUID *guid) override;
- STDMETHODIMP GetDescription(_Out_ BSTR *desc) override;
- //STDMETHODIMP GetFunction(_In_ REFGUID guid, _In_ REFIID riid, _Out_ IUnknown **func) = 0;
-
- BOOL Init(_In_ REFGUID rguid, _In_ LPCWSTR psz);
-};
-
-/// @implemented
-CFunctionProviderBase::CFunctionProviderBase(_In_ TfClientId clientId)
-{
- m_clientId = clientId;
- m_guid = GUID_NULL;
- m_bstr = NULL;
- m_cRefs = 1;
-}
-
-/// @implemented
-CFunctionProviderBase::~CFunctionProviderBase()
-{
- if (!RtlDllShutdownInProgress())
- ::SysFreeString(m_bstr);
-}
-
-/// @implemented
-BOOL
-CFunctionProviderBase::Init(
- _In_ REFGUID rguid,
- _In_ LPCWSTR psz)
-{
- m_bstr = ::SysAllocString(psz);
- m_guid = rguid;
- return (m_bstr != NULL);
-}
-
-class CFnDocFeed : public IAImmFnDocFeed
-{
- LONG m_cRefs;
-
-public:
- CFnDocFeed();
- virtual ~CFnDocFeed();
-
- // IUnknown interface
- STDMETHODIMP QueryInterface(_In_ REFIID riid, _Out_ LPVOID* ppvObj) override;
- STDMETHODIMP_(ULONG) AddRef() override;
- STDMETHODIMP_(ULONG) Release() override;
-
- // IAImmFnDocFeed interface
- STDMETHODIMP DocFeed() override;
- STDMETHODIMP ClearDocFeedBuffer() override;
- STDMETHODIMP StartReconvert() override;
- STDMETHODIMP StartUndoCompositionString() override;
-};
-
-CFnDocFeed::CFnDocFeed()
-{
- m_cRefs = 1;
-}
-
-CFnDocFeed::~CFnDocFeed()
-{
-}
-
-/// @implemented
-STDMETHODIMP CFnDocFeed::QueryInterface(_In_ REFIID riid, _Out_ LPVOID* ppvObj)
-{
- if (IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, IID_IAImmFnDocFeed))
- {
- *ppvObj = this;
- AddRef();
- return S_OK;
- }
- return E_NOINTERFACE;
-}
-
-/// @implemented
-STDMETHODIMP_(ULONG) CFnDocFeed::AddRef()
-{
- return ::InterlockedIncrement(&m_cRefs);
-}
-
-/// @implemented
-STDMETHODIMP_(ULONG) CFnDocFeed::Release()
-{
- if (::InterlockedDecrement(&m_cRefs) == 0)
- {
- delete this;
- return 0;
- }
- return m_cRefs;
-}
-
-/// @unimplemented
-STDMETHODIMP CFnDocFeed::DocFeed()
-{
- return E_NOTIMPL;
-}
-
-/// @unimplemented
-STDMETHODIMP CFnDocFeed::ClearDocFeedBuffer()
-{
- return E_NOTIMPL;
-}
-
-/// @unimplemented
-STDMETHODIMP CFnDocFeed::StartReconvert()
-{
- return E_NOTIMPL;
-}
-
-/// @unimplemented
-STDMETHODIMP CFnDocFeed::StartUndoCompositionString()
-{
- return E_NOTIMPL;
-}
-
-/// @implemented
-STDMETHODIMP
-CFunctionProviderBase::QueryInterface(
- _In_ REFIID riid,
- _Out_ LPVOID* ppvObj)
-{
- if (IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, IID_ITfFunctionProvider))
- {
- *ppvObj = this;
- AddRef();
- return S_OK;
- }
- return E_NOINTERFACE;
-}
-
-/// @implemented
-STDMETHODIMP_(ULONG) CFunctionProviderBase::AddRef()
-{
- return ::InterlockedIncrement(&m_cRefs);
-}
-
-/// @implemented
-STDMETHODIMP_(ULONG) CFunctionProviderBase::Release()
-{
- if (::InterlockedDecrement(&m_cRefs) == 0)
- {
- delete this;
- return 0;
- }
- return m_cRefs;
-}
-
-/// @implemented
-STDMETHODIMP CFunctionProviderBase::GetType(_Out_ GUID *guid)
-{
- *guid = m_guid;
- return S_OK;
-}
-
-/// @implemented
-STDMETHODIMP CFunctionProviderBase::GetDescription(_Out_ BSTR *desc)
-{
- *desc = ::SysAllocString(m_bstr);
- return (*desc ? S_OK : E_OUTOFMEMORY);
-}
-
-class CFunctionProvider : public CFunctionProviderBase
-{
-public:
- CFunctionProvider(_In_ TfClientId clientId);
-
- STDMETHODIMP GetFunction(_In_ REFGUID guid, _In_ REFIID riid, _Out_ IUnknown **func) override;
-};
-
-/// @implemented
-CFunctionProvider::CFunctionProvider(_In_ TfClientId clientId) : CFunctionProviderBase(clientId)
-{
- Init(CLSID_CAImmLayer, L"MSCTFIME::Function Provider");
-}
-
-/// @implemented
-STDMETHODIMP
-CFunctionProvider::GetFunction(
- _In_ REFGUID guid,
- _In_ REFIID riid,
- _Out_ IUnknown **func)
-{
- *func = NULL;
-
- if (IsEqualGUID(guid, GUID_NULL) &&
- IsEqualIID(riid, IID_IAImmFnDocFeed))
- {
- *func = new(cicNoThrow) CFnDocFeed();
- if (*func)
- return S_OK;
- }
-
- return E_NOINTERFACE;
-}
-
-/* FIXME */
-class CicBridge : public ITfSysHookSink
-{
-protected:
- LONG m_cRefs;
- BOOL m_bImmxInited;
- BOOL m_bUnknown1;
- BOOL m_bDeactivating;
- DWORD m_cActivateLocks;
- ITfKeystrokeMgr *m_pKeystrokeMgr;
- ITfDocumentMgr *m_pDocMgr;
- CThreadMgrEventSink *m_pThreadMgrEventSink;
- TfClientId m_cliendId;
- CIC_LIBTHREAD m_LibThread;
- BOOL m_bUnknown2;
-
- static BOOL CALLBACK EnumCreateInputContextCallback(HIMC hIMC, LPARAM lParam);
- static BOOL CALLBACK EnumDestroyInputContextCallback(HIMC hIMC, LPARAM lParam);
-
-public:
- CicBridge();
- virtual ~CicBridge();
-
- // IUnknown interface
- STDMETHODIMP QueryInterface(REFIID riid, LPVOID* ppvObj) override;
- STDMETHODIMP_(ULONG) AddRef() override;
- STDMETHODIMP_(ULONG) Release() override;
-
- // ITfSysHookSink interface
- STDMETHODIMP OnPreFocusDIM(HWND hwnd) override;
- STDMETHODIMP OnSysKeyboardProc(UINT, LONG) override;
- STDMETHODIMP OnSysShellProc(INT, UINT, LONG) override;
-
- HRESULT InitIMMX(_Inout_ TLS *pTLS);
- BOOL UnInitIMMX(_Inout_ TLS *pTLS);
- HRESULT ActivateIMMX(_Inout_ TLS *pTLS, _Inout_ ITfThreadMgr_P *pThreadMgr);
- HRESULT DeactivateIMMX(_Inout_ TLS *pTLS, _Inout_ ITfThreadMgr_P *pThreadMgr);
-
- HRESULT CreateInputContext(TLS *pTLS, HIMC hIMC);
- HRESULT DestroyInputContext(TLS *pTLS, HIMC hIMC);
- ITfContext *GetInputContext(CicIMCCLock<CTFIMECONTEXT>& imeContext);
-
- HRESULT SelectEx(
- _Inout_ TLS *pTLS,
- _Inout_ ITfThreadMgr_P *pThreadMgr,
- _In_ HIMC hIMC,
- _In_ BOOL fSelect,
- _In_ HKL hKL);
- HRESULT OnSetOpenStatus(
- TLS *pTLS,
- ITfThreadMgr_P *pThreadMgr,
- CicIMCLock& imcLock,
- CicInputContext *pCicIC);
-
- void PostTransMsg(_In_ HWND hWnd, _In_ INT cTransMsgs, _In_ const TRANSMSG *pTransMsgs);
- void GetDocumentManager(_Inout_ CicIMCCLock<CTFIMECONTEXT>& imeContext);
-
- HRESULT
- ConfigureGeneral(_Inout_ TLS* pTLS,
- _In_ ITfThreadMgr *pThreadMgr,
- _In_ HKL hKL,
- _In_ HWND hWnd);
- HRESULT ConfigureRegisterWord(
- _Inout_ TLS* pTLS,
- _In_ ITfThreadMgr *pThreadMgr,
- _In_ HKL hKL,
- _In_ HWND hWnd,
- _Inout_opt_ LPVOID lpData);
-};
-
-class CActiveLanguageProfileNotifySink : public ITfActiveLanguageProfileNotifySink
-{
-protected:
- typedef INT (CALLBACK *FN_COMPARE)(REFGUID rguid1, REFGUID rguid2, BOOL fActivated, LPVOID pUserData);
- LONG m_cRefs;
- ITfThreadMgr *m_pThreadMgr;
- DWORD m_dwConnection;
- FN_COMPARE m_fnCompare;
- LPVOID m_pUserData;
-
-public:
- CActiveLanguageProfileNotifySink(_In_ FN_COMPARE fnCompare, _Inout_opt_ void *pUserData);
- virtual ~CActiveLanguageProfileNotifySink();
-
- HRESULT _Advise(ITfThreadMgr *pThreadMgr);
- HRESULT _Unadvise();
-
- // IUnknown interface
- STDMETHODIMP QueryInterface(REFIID riid, LPVOID* ppvObj) override;
- STDMETHODIMP_(ULONG) AddRef() override;
- STDMETHODIMP_(ULONG) Release() override;
-
- // ITfActiveLanguageProfileNotifySink interface
- STDMETHODIMP
- OnActivated(
- REFCLSID clsid,
- REFGUID guidProfile,
- BOOL fActivated) override;
-};
-
-/// @implemented
-CActiveLanguageProfileNotifySink::CActiveLanguageProfileNotifySink(
- _In_ FN_COMPARE fnCompare,
- _Inout_opt_ void *pUserData)
-{
- m_dwConnection = (DWORD)-1;
- m_fnCompare = fnCompare;
- m_cRefs = 1;
- m_pUserData = pUserData;
-}
-
-/// @implemented
-CActiveLanguageProfileNotifySink::~CActiveLanguageProfileNotifySink()
-{
-}
-
-/// @implemented
-STDMETHODIMP CActiveLanguageProfileNotifySink::QueryInterface(REFIID riid, LPVOID* ppvObj)
-{
- if (IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, IID_ITfActiveLanguageProfileNotifySink))
- {
- *ppvObj = this;
- AddRef();
- return S_OK;
- }
- *ppvObj = NULL;
- return E_NOINTERFACE;
-}
-
-/// @implemented
-STDMETHODIMP_(ULONG) CActiveLanguageProfileNotifySink::AddRef()
-{
- return ::InterlockedIncrement(&m_cRefs);
-}
-
-/// @implemented
-STDMETHODIMP_(ULONG) CActiveLanguageProfileNotifySink::Release()
-{
- if (::InterlockedDecrement(&m_cRefs) == 0)
- {
- delete this;
- return 0;
- }
- return m_cRefs;
-}
-
-/// @implemented
-STDMETHODIMP
-CActiveLanguageProfileNotifySink::OnActivated(
- REFCLSID clsid,
- REFGUID guidProfile,
- BOOL fActivated)
-{
- if (!m_fnCompare)
- return 0;
-
- return m_fnCompare(clsid, guidProfile, fActivated, m_pUserData);
-}
-
-/// @implemented
-HRESULT
-CActiveLanguageProfileNotifySink::_Advise(
- ITfThreadMgr *pThreadMgr)
-{
- m_pThreadMgr = NULL;
-
- ITfSource *pSource = NULL;
- HRESULT hr = pThreadMgr->QueryInterface(IID_ITfSource, (void **)&pSource);
- if (FAILED(hr))
- return E_FAIL;
-
- hr = pSource->AdviseSink(IID_ITfActiveLanguageProfileNotifySink, this, &m_dwConnection);
- if (SUCCEEDED(hr))
- {
- m_pThreadMgr = pThreadMgr;
- pThreadMgr->AddRef();
- hr = S_OK;
- }
- else
- {
- hr = E_FAIL;
- }
-
- if (pSource)
- pSource->Release();
-
- return hr;
-}
-
-/// @implemented
-HRESULT
-CActiveLanguageProfileNotifySink::_Unadvise()
-{
- if (!m_pThreadMgr)
- return E_FAIL;
-
- ITfSource *pSource = NULL;
- HRESULT hr = m_pThreadMgr->QueryInterface(IID_ITfSource, (void **)&pSource);
- if (SUCCEEDED(hr))
- {
- hr = pSource->UnadviseSink(m_dwConnection);
- if (SUCCEEDED(hr))
- hr = S_OK;
- }
-
- if (pSource)
- pSource->Release();
-
- if (m_pThreadMgr)
- {
- m_pThreadMgr->Release();
- m_pThreadMgr = NULL;
- }
-
- return hr;
-}
-
-/* FIXME */
-class CicProfile : public IUnknown
-{
-protected:
- ITfInputProcessorProfiles *m_pIPProfiles;
- CActiveLanguageProfileNotifySink *m_pActiveLanguageProfileNotifySink;
- LANGID m_LangID1;
- WORD m_padding1;
- DWORD m_dwFlags;
- UINT m_nCodePage;
- LANGID m_LangID2;
- WORD m_padding2;
- DWORD m_dwUnknown1;
- LONG m_cRefs;
-
- static INT CALLBACK
- ActiveLanguageProfileNotifySinkCallback(
- REFGUID rguid1,
- REFGUID rguid2,
- BOOL fActivated,
- LPVOID pUserData);
-
-public:
- CicProfile();
- virtual ~CicProfile();
-
- // IUnknown interface
- STDMETHODIMP QueryInterface(REFIID riid, LPVOID* ppvObj) override;
- STDMETHODIMP_(ULONG) AddRef() override;
- STDMETHODIMP_(ULONG) Release() override;
-
- HRESULT
- GetActiveLanguageProfile(
- _In_ HKL hKL,
- _In_ REFGUID rguid,
- _Out_ TF_LANGUAGEPROFILE *pProfile);
- HRESULT GetLangId(_Out_ LANGID *pLangID);
- HRESULT GetCodePageA(_Out_ UINT *puCodePage);
-
- HRESULT InitProfileInstance(_Inout_ TLS *pTLS);
-};
-
-/// @implemented
-CicProfile::CicProfile()
-{
- m_dwFlags &= 0xFFFFFFF0;
- m_cRefs = 1;
- m_pIPProfiles = NULL;
- m_pActiveLanguageProfileNotifySink = NULL;
- m_LangID1 = 0;
- m_nCodePage = CP_ACP;
- m_LangID2 = 0;
- m_dwUnknown1 = 0;
-}
-
-/// @implemented
-CicProfile::~CicProfile()
-{
- if (m_pIPProfiles)
- {
- if (m_LangID1)
- m_pIPProfiles->ChangeCurrentLanguage(m_LangID1);
-
- m_pIPProfiles->Release();
- m_pIPProfiles = NULL;
- }
-
- if (m_pActiveLanguageProfileNotifySink)
- {
- m_pActiveLanguageProfileNotifySink->_Unadvise();
- m_pActiveLanguageProfileNotifySink->Release();
- m_pActiveLanguageProfileNotifySink = NULL;
- }
-}
-
-/// @implemented
-STDMETHODIMP CicProfile::QueryInterface(REFIID riid, LPVOID* ppvObj)
-{
- *ppvObj = NULL;
- return E_NOINTERFACE;
-}
-
-/// @implemented
-STDMETHODIMP_(ULONG) CicProfile::AddRef()
-{
- return ::InterlockedIncrement(&m_cRefs);
-}
-
-/// @implemented
-STDMETHODIMP_(ULONG) CicProfile::Release()
-{
- if (::InterlockedDecrement(&m_cRefs) == 0)
- {
- delete this;
- return 0;
- }
- return m_cRefs;
-}
-
-/// @implemented
-INT CALLBACK
-CicProfile::ActiveLanguageProfileNotifySinkCallback(
- REFGUID rguid1,
- REFGUID rguid2,
- BOOL fActivated,
- LPVOID pUserData)
-{
- CicProfile *pThis = (CicProfile *)pUserData;
- pThis->m_dwFlags &= ~0xE;
- return 0;
-}
-
-/// @implemented
-HRESULT CicProfile::GetCodePageA(_Out_ UINT *puCodePage)
-{
- if (!puCodePage)
- return E_INVALIDARG;
-
- if (m_dwFlags & 2)
- {
- *puCodePage = m_nCodePage;
- return S_OK;
- }
-
- *puCodePage = 0;
-
- LANGID LangID;
- HRESULT hr = GetLangId(&LangID);
- if (FAILED(hr))
- return E_FAIL;
-
- WCHAR szBuff[12];
- INT cch = ::GetLocaleInfoW(LangID, LOCALE_IDEFAULTANSICODEPAGE, szBuff, _countof(szBuff));
- if (cch)
- {
- szBuff[cch] = 0;
- m_nCodePage = *puCodePage = wcstoul(szBuff, NULL, 10);
- m_dwFlags |= 2;
- }
-
- return S_OK;
-}
-
-/// @implemented
-HRESULT CicProfile::GetLangId(_Out_ LANGID *pLangID)
-{
- *pLangID = 0;
-
- if (!m_pIPProfiles)
- return E_FAIL;
-
- if (m_dwFlags & 4)
- {
- *pLangID = m_LangID2;
- return S_OK;
- }
-
- HRESULT hr = m_pIPProfiles->GetCurrentLanguage(pLangID);
- if (SUCCEEDED(hr))
- {
- m_dwFlags |= 4;
- m_LangID2 = *pLangID;
- }
-
- return hr;
-}
-
-class TLS
-{
-public:
- static DWORD s_dwTlsIndex;
-
- DWORD m_dwSystemInfoFlags;
- CicBridge *m_pBridge;
- CicProfile *m_pProfile;
- ITfThreadMgr_P *m_pThreadMgr;
- DWORD m_dwFlags1;
- DWORD m_dwFlags2;
- DWORD m_dwUnknown2;
- BOOL m_bDestroyed;
- DWORD m_dwNowOpening;
- DWORD m_NonEAComposition;
- DWORD m_cWnds;
-
- /**
- * @implemented
- */
- static BOOL Initialize()
- {
- s_dwTlsIndex = ::TlsAlloc();
- return s_dwTlsIndex != (DWORD)-1;
- }
-
- /**
- * @implemented
- */
- static VOID Uninitialize()
- {
- if (s_dwTlsIndex != (DWORD)-1)
- {
- ::TlsFree(s_dwTlsIndex);
- s_dwTlsIndex = (DWORD)-1;
- }
- }
-
- /**
- * @implemented
- */
- static TLS* GetTLS()
- {
- if (s_dwTlsIndex == (DWORD)-1)
- return NULL;
-
- return InternalAllocateTLS();
- }
-
- /**
- * @implemented
- */
- static TLS* PeekTLS()
- {
- return (TLS*)::TlsGetValue(TLS::s_dwTlsIndex);
- }
-
- static TLS* InternalAllocateTLS();
- static BOOL InternalDestroyTLS();
-
-};
-
-DWORD TLS::s_dwTlsIndex = (DWORD)-1;
-
-/// @implemented
-TLS* TLS::InternalAllocateTLS()
-{
- TLS *pTLS = TLS::PeekTLS();
- if (pTLS)
- return pTLS;
-
- if (DllShutDownInProgress())
- return NULL;
-
- pTLS = (TLS *)cicMemAllocClear(sizeof(TLS));
- if (!pTLS)
- return NULL;
-
- if (!::TlsSetValue(s_dwTlsIndex, pTLS))
- {
- cicMemFree(pTLS);
- return NULL;
- }
-
- pTLS->m_dwFlags1 |= 1;
- pTLS->m_dwUnknown2 |= 1;
- return pTLS;
-}
-
-/// @implemented
-BOOL TLS::InternalDestroyTLS()
-{
- TLS *pTLS = TLS::PeekTLS();
- if (!pTLS)
- return FALSE;
-
- if (pTLS->m_pBridge)
- pTLS->m_pBridge->Release();
- if (pTLS->m_pProfile)
- pTLS->m_pProfile->Release();
- if (pTLS->m_pThreadMgr)
- pTLS->m_pThreadMgr->Release();
-
- cicMemFree(pTLS);
- ::TlsSetValue(s_dwTlsIndex, NULL);
- return TRUE;
-}
-
-/// @implemented
-HRESULT
-CicProfile::InitProfileInstance(_Inout_ TLS *pTLS)
-{
- HRESULT hr = TF_CreateInputProcessorProfiles(&m_pIPProfiles);
- if (FAILED(hr))
- return hr;
-
- if (!m_pActiveLanguageProfileNotifySink)
- {
- CActiveLanguageProfileNotifySink *pSink =
- new(cicNoThrow) CActiveLanguageProfileNotifySink(
- CicProfile::ActiveLanguageProfileNotifySinkCallback, this);
- if (!pSink)
- {
- m_pIPProfiles->Release();
- m_pIPProfiles = NULL;
- return E_FAIL;
- }
- m_pActiveLanguageProfileNotifySink = pSink;
- }
-
- if (pTLS->m_pThreadMgr)
- m_pActiveLanguageProfileNotifySink->_Advise(pTLS->m_pThreadMgr);
-
- return hr;
-}
-
-/// @implemented
-STDMETHODIMP
-CicInputContext::OnCleanupContext(
- _In_ TfEditCookie ecWrite,
- _Inout_ ITfContext *pic)
-{
- TLS *pTLS = TLS::PeekTLS();
- if (!pTLS || !pTLS->m_pProfile)
- return E_OUTOFMEMORY;
-
- LANGID LangID;
- pTLS->m_pProfile->GetLangId(&LangID);
-
- IMEINFO IMEInfo;
- WCHAR szPath[MAX_PATH];
- if (Inquire(&IMEInfo, szPath, 0, (HKL)UlongToHandle(LangID)) != S_OK)
- return E_FAIL;
-
- ITfProperty *pProp = NULL;
- if (!(IMEInfo.fdwProperty & IME_PROP_COMPLETE_ON_UNSELECT))
- return S_OK;
-
- HRESULT hr = pic->GetProperty(GUID_PROP_COMPOSING, &pProp);
- if (FAILED(hr))
- return S_OK;
-
- IEnumTfRanges *pRanges = NULL;
- hr = pProp->EnumRanges(ecWrite, &pRanges, NULL);
- if (SUCCEEDED(hr))
- {
- ITfRange *pRange = NULL;
- while (pRanges->Next(1, &pRange, 0) == S_OK)
- {
- VARIANT vari;
- V_VT(&vari) = VT_EMPTY;
- pProp->GetValue(ecWrite, pRange, &vari);
- if (V_VT(&vari) == VT_I4)
- {
- if (V_I4(&vari))
- pProp->Clear(ecWrite, pRange);
- }
- pRange->Release();
- pRange = NULL;
- }
- pRanges->Release();
- }
- pProp->Release();
-
- return S_OK;
-}
-
-/***********************************************************************
- * CicBridge
- */
-
-CicBridge::CicBridge()
-{
- m_bImmxInited = FALSE;
- m_bUnknown1 = FALSE;
- m_bDeactivating = FALSE;
- m_bUnknown2 = FALSE;
- m_pKeystrokeMgr = NULL;
- m_pDocMgr = NULL;
- m_pThreadMgrEventSink = NULL;
- m_cliendId = 0;
- m_cRefs = 1;
-}
-
-/// @implemented
-STDMETHODIMP CicBridge::QueryInterface(REFIID riid, LPVOID* ppvObj)
-{
- *ppvObj = NULL;
-
- if (!IsEqualIID(riid, IID_ITfSysHookSink))
- return E_NOINTERFACE;
-
- *ppvObj = this;
- AddRef();
-
- return S_OK;
-}
-
-/// @implemented
-STDMETHODIMP_(ULONG) CicBridge::AddRef()
-{
- return ::InterlockedIncrement(&m_cRefs);
-}
-
-/// @implemented
-STDMETHODIMP_(ULONG) CicBridge::Release()
-{
- if (::InterlockedDecrement(&m_cRefs) == 0)
- {
- delete this;
- return 0;
- }
- return m_cRefs;
-}
-
-/// @implemented
-CicBridge::~CicBridge()
-{
- TLS *pTLS = TLS::PeekTLS();
- if (!pTLS || !pTLS->m_pThreadMgr)
- return;
-
- if (SUCCEEDED(DeactivateIMMX(pTLS, pTLS->m_pThreadMgr)))
- UnInitIMMX(pTLS);
-}
-
-void CicBridge::GetDocumentManager(_Inout_ CicIMCCLock<CTFIMECONTEXT>& imeContext)
-{
- CicInputContext *pCicIC = imeContext.get().m_pCicIC;
- if (pCicIC)
- {
- m_pDocMgr = pCicIC->m_pDocumentMgr;
- m_pDocMgr->AddRef();
- }
- else
- {
- m_pDocMgr->Release();
- m_pDocMgr = NULL;
- }
-}
-
-/// @unimplemented
-HRESULT
-CicBridge::CreateInputContext(
- _Inout_ TLS *pTLS,
- _In_ HIMC hIMC)
-{
- CicIMCLock imcLock(hIMC);
- HRESULT hr = imcLock.m_hr;
- if (!imcLock)
- hr = E_FAIL;
- if (FAILED(hr))
- return hr;
-
- if (!imcLock.get().hCtfImeContext)
- {
- HIMCC hCtfImeContext = ImmCreateIMCC(sizeof(CTFIMECONTEXT));
- if (!hCtfImeContext)
- return E_OUTOFMEMORY;
- imcLock.get().hCtfImeContext = hCtfImeContext;
- }
-
- CicIMCCLock<CTFIMECONTEXT> imeContext(imcLock.get().hCtfImeContext);
- CicInputContext *pCicIC = imeContext.get().m_pCicIC;
- if (!pCicIC)
- {
- pCicIC = new(cicNoThrow) CicInputContext(m_cliendId, &m_LibThread, hIMC);
- if (!pCicIC)
- {
- imeContext.unlock();
- imcLock.unlock();
- DestroyInputContext(pTLS, hIMC);
- return E_OUTOFMEMORY;
- }
-
- if (!pTLS->m_pThreadMgr)
- {
- pCicIC->Release();
- imeContext.unlock();
- imcLock.unlock();
- DestroyInputContext(pTLS, hIMC);
- return E_NOINTERFACE;
- }
-
- imeContext.get().m_pCicIC = pCicIC;
- }
-
- hr = pCicIC->CreateInputContext(pTLS->m_pThreadMgr, imcLock);
- if (FAILED(hr))
- {
- pCicIC->Release();
- imeContext.get().m_pCicIC = NULL;
- }
- else
- {
- if (imcLock.get().hWnd && imcLock.get().hWnd == ::GetFocus())
- {
- GetDocumentManager(imeContext);
- //FIXME
- }
- }
-
- return E_NOTIMPL;
-}
-
-/// @implemented
-HRESULT CicBridge::DestroyInputContext(TLS *pTLS, HIMC hIMC)
-{
- CicIMCLock imcLock(hIMC);
- HRESULT hr = imcLock.m_hr;
- if (!imcLock)
- hr = E_FAIL;
- if (FAILED(hr))
- return hr;
-
- hr = E_FAIL;
- CicIMCCLock<CTFIMECONTEXT> imeContext(imcLock.get().hCtfImeContext);
- if (imeContext)
- hr = imeContext.m_hr;
-
- if (SUCCEEDED(hr) && !(imeContext.get().m_dwCicFlags & 1))
- {
- imeContext.get().m_dwCicFlags |= 1;
-
- CicInputContext *pCicIC = imeContext.get().m_pCicIC;
- if (pCicIC)
- {
- imeContext.get().m_pCicIC = NULL;
- hr = pCicIC->DestroyInputContext();
- pCicIC->Release();
- imeContext.get().m_pCicIC = NULL;
- }
- }
-
- if (imcLock.get().hCtfImeContext)
- {
- ImmDestroyIMCC(imcLock.get().hCtfImeContext);
- imcLock.get().hCtfImeContext = NULL;
- hr = S_OK;
- }
-
- return hr;
-}
-
-ITfContext *
-CicBridge::GetInputContext(CicIMCCLock<CTFIMECONTEXT>& imeContext)
-{
- CicInputContext *pCicIC = imeContext.get().m_pCicIC;
- if (!pCicIC)
- return NULL;
- return pCicIC->m_pContext;
-}
-
-/// @unimplemented
-HRESULT CicBridge::OnSetOpenStatus(
- TLS *pTLS,
- ITfThreadMgr_P *pThreadMgr,
- CicIMCLock& imcLock,
- CicInputContext *pCicIC)
-{
- return E_NOTIMPL;
-}
-
-/// Selects the IME context.
-/// @implemented
-HRESULT
-CicBridge::SelectEx(
- _Inout_ TLS *pTLS,
- _Inout_ ITfThreadMgr_P *pThreadMgr,
- _In_ HIMC hIMC,
- _In_ BOOL fSelect,
- _In_ HKL hKL)
-{
- CicIMCLock imcLock(hIMC);
- if (FAILED(imcLock.m_hr))
- return imcLock.m_hr;
-
- CicIMCCLock<CTFIMECONTEXT> imeContext(imcLock.get().hCtfImeContext);
- if (!imeContext)
- imeContext.m_hr = E_FAIL;
- if (FAILED(imeContext.m_hr))
- return imeContext.m_hr;
-
- CicInputContext *pCicIC = imeContext.get().m_pCicIC;
- if (pCicIC)
- pCicIC->m_bSelecting = TRUE;
-
- if (fSelect)
- {
- if (pCicIC)
- pCicIC->m_dwUnknown6[1] &= ~1;
- if (imcLock.get().fOpen)
- OnSetOpenStatus(pTLS, pThreadMgr, imcLock, pCicIC);
- }
- else
- {
- ITfContext *pContext = GetInputContext(imeContext);
- pThreadMgr->RequestPostponedLock(pContext);
- if (pCicIC)
- pCicIC->m_bSelecting = FALSE;
- if (pContext)
- pContext->Release();
- }
-
- return imeContext.m_hr;
-}
-
-/// Used in CicBridge::EnumCreateInputContextCallback and
-/// CicBridge::EnumDestroyInputContextCallback.
-typedef struct ENUM_CREATE_DESTROY_IC
-{
- TLS *m_pTLS;
- CicBridge *m_pBridge;
-} ENUM_CREATE_DESTROY_IC, *PENUM_CREATE_DESTROY_IC;
-
-/// Creates input context for the current thread.
-/// @implemented
-BOOL CALLBACK CicBridge::EnumCreateInputContextCallback(HIMC hIMC, LPARAM lParam)
-{
- PENUM_CREATE_DESTROY_IC pData = (PENUM_CREATE_DESTROY_IC)lParam;
- pData->m_pBridge->CreateInputContext(pData->m_pTLS, hIMC);
- return TRUE;
-}
-
-/// Destroys input context for the current thread.
-/// @implemented
-BOOL CALLBACK CicBridge::EnumDestroyInputContextCallback(HIMC hIMC, LPARAM lParam)
-{
- PENUM_CREATE_DESTROY_IC pData = (PENUM_CREATE_DESTROY_IC)lParam;
- pData->m_pBridge->DestroyInputContext(pData->m_pTLS, hIMC);
- return TRUE;
-}
-
-/// @implemented
-HRESULT
-CicBridge::ActivateIMMX(
- _Inout_ TLS *pTLS,
- _Inout_ ITfThreadMgr_P *pThreadMgr)
-{
- HRESULT hr = pThreadMgr->ActivateEx(&m_cliendId, 1);
- if (hr != S_OK)
- {
- m_cliendId = 0;
- return E_FAIL;
- }
-
- if (m_cActivateLocks++ != 0)
- return S_OK;
-
- ITfSourceSingle *pSource = NULL;
- hr = pThreadMgr->QueryInterface(IID_ITfSourceSingle, (void**)&pSource);
- if (FAILED(hr))
- {
- DeactivateIMMX(pTLS, pThreadMgr);
- return hr;
- }
-
- CFunctionProvider *pProvider = new(cicNoThrow) CFunctionProvider(m_cliendId);
- if (!pProvider)
- {
- hr = E_FAIL;
- goto Finish;
- }
-
- pSource->AdviseSingleSink(m_cliendId, IID_ITfFunctionProvider, pProvider);
- pProvider->Release();
-
- if (!m_pDocMgr)
- {
- hr = pThreadMgr->CreateDocumentMgr(&m_pDocMgr);
- if (FAILED(hr))
- {
- hr = E_FAIL;
- goto Finish;
- }
-
- SetCompartmentDWORD(m_cliendId, m_pDocMgr, GUID_COMPARTMENT_CTFIME_DIMFLAGS, TRUE, FALSE);
- }
-
- pThreadMgr->SetSysHookSink(this);
-
- hr = S_OK;
- if (pTLS->m_bDestroyed)
- {
- ENUM_CREATE_DESTROY_IC Data = { pTLS, this };
- ImmEnumInputContext(0, CicBridge::EnumCreateInputContextCallback, (LPARAM)&Data);
- }
-
-Finish:
- if (FAILED(hr))
- DeactivateIMMX(pTLS, pThreadMgr);
- if (pSource)
- pSource->Release();
- return hr;
-}
-
-/// @implemented
-HRESULT
-CicBridge::DeactivateIMMX(
- _Inout_ TLS *pTLS,
- _Inout_ ITfThreadMgr_P *pThreadMgr)
-{
- if (m_bDeactivating)
- return TRUE;
-
- m_bDeactivating = TRUE;
-
- if (m_cliendId)
- {
- ENUM_CREATE_DESTROY_IC Data = { pTLS, this };
- ImmEnumInputContext(0, CicBridge::EnumDestroyInputContextCallback, (LPARAM)&Data);
- pTLS->m_bDestroyed = TRUE;
-
- ITfSourceSingle *pSource = NULL;
- if (pThreadMgr->QueryInterface(IID_ITfSourceSingle, (void **)&pSource) == S_OK)
- pSource->UnadviseSingleSink(m_cliendId, IID_ITfFunctionProvider);
-
- m_cliendId = 0;
-
- while (m_cActivateLocks > 0)
- {
- --m_cActivateLocks;
- pThreadMgr->Deactivate();
- }
-
- if (pSource)
- pSource->Release();
- }
-
- if (m_pDocMgr)
- {
- m_pDocMgr->Release();
- m_pDocMgr = NULL;
- }
-
- pThreadMgr->SetSysHookSink(NULL);
-
- m_bDeactivating = FALSE;
-
- return S_OK;
-}
-
-/// @implemented
-HRESULT
-CicBridge::InitIMMX(_Inout_ TLS *pTLS)
-{
- if (m_bImmxInited)
- return S_OK;
-
- HRESULT hr = S_OK;
- if (!pTLS->m_pThreadMgr)
- {
- ITfThreadMgr *pThreadMgr = NULL;
- hr = TF_CreateThreadMgr(&pThreadMgr);
- if (FAILED(hr))
- return E_FAIL;
-
- hr = pThreadMgr->QueryInterface(IID_ITfThreadMgr_P, (void **)&pTLS->m_pThreadMgr);
- if (pThreadMgr)
- pThreadMgr->Release();
- if (FAILED(hr))
- return E_FAIL;
- }
-
- if (!m_pThreadMgrEventSink)
- {
- m_pThreadMgrEventSink =
- new(cicNoThrow) CThreadMgrEventSink(CThreadMgrEventSink::DIMCallback, NULL, NULL);
- if (!m_pThreadMgrEventSink)
- {
- UnInitIMMX(pTLS);
- return E_FAIL;
- }
- }
-
- m_pThreadMgrEventSink->SetCallbackPV(m_pThreadMgrEventSink);
- m_pThreadMgrEventSink->_Advise(pTLS->m_pThreadMgr);
-
- if (!pTLS->m_pProfile)
- {
- pTLS->m_pProfile = new(cicNoThrow) CicProfile();
- if (!pTLS->m_pProfile)
- return E_OUTOFMEMORY;
-
- hr = pTLS->m_pProfile->InitProfileInstance(pTLS);
- if (FAILED(hr))
- {
- UnInitIMMX(pTLS);
- return E_FAIL;
- }
- }
-
- hr = pTLS->m_pThreadMgr->QueryInterface(IID_ITfKeystrokeMgr_P, (void **)&m_pKeystrokeMgr);
- if (FAILED(hr))
- {
- UnInitIMMX(pTLS);
- return E_FAIL;
- }
-
- hr = InitDisplayAttrbuteLib(&m_LibThread);
- if (FAILED(hr))
- {
- UnInitIMMX(pTLS);
- return E_FAIL;
- }
-
- m_bImmxInited = TRUE;
- return S_OK;
-}
-
-/// @implemented
-BOOL CicBridge::UnInitIMMX(_Inout_ TLS *pTLS)
-{
- UninitDisplayAttrbuteLib(&m_LibThread);
- TFUninitLib_Thread(&m_LibThread);
-
- if (m_pKeystrokeMgr)
- {
- m_pKeystrokeMgr->Release();
- m_pKeystrokeMgr = NULL;
- }
-
- if (pTLS->m_pProfile)
- {
- pTLS->m_pProfile->Release();
- pTLS->m_pProfile = NULL;
- }
-
- if (m_pThreadMgrEventSink)
- {
- m_pThreadMgrEventSink->_Unadvise();
- m_pThreadMgrEventSink->Release();
- m_pThreadMgrEventSink = NULL;
- }
-
- if (pTLS->m_pThreadMgr)
- {
- pTLS->m_pThreadMgr->Release();
- pTLS->m_pThreadMgr = NULL;
- }
-
- m_bImmxInited = FALSE;
- return TRUE;
-}
-
-/// @implemented
-STDMETHODIMP CicBridge::OnPreFocusDIM(HWND hwnd)
-{
- return S_OK;
-}
-
-/// @unimplemented
-STDMETHODIMP CicBridge::OnSysKeyboardProc(UINT, LONG)
-{
- return E_NOTIMPL;
+ return hr;
}
-/// @implemented
-STDMETHODIMP CicBridge::OnSysShellProc(INT, UINT, LONG)
+HIMC GetActiveContext(VOID)
{
- return S_OK;
+ HWND hwndFocus = ::GetFocus();
+ if (!hwndFocus)
+ hwndFocus = ::GetActiveWindow();
+ return ::ImmGetContext(hwndFocus);
}
/// @implemented
-void
-CicBridge::PostTransMsg(
- _In_ HWND hWnd,
- _In_ INT cTransMsgs,
- _In_ const TRANSMSG *pTransMsgs)
+HRESULT UninitDisplayAttrbuteLib(PCIC_LIBTHREAD pLibThread)
{
- for (INT i = 0; i < cTransMsgs; ++i, ++pTransMsgs)
+ if (!pLibThread)
+ return E_FAIL;
+
+ if (pLibThread->m_pDisplayAttrMgr)
{
- ::PostMessageW(hWnd, pTransMsgs->message, pTransMsgs->wParam, pTransMsgs->lParam);
+ pLibThread->m_pDisplayAttrMgr->Release();
+ pLibThread->m_pDisplayAttrMgr = NULL;
}
+
+ return S_OK;
}
+/// Gets the charset from a language ID.
/// @implemented
-HRESULT
-CicBridge::ConfigureGeneral(
- _Inout_ TLS* pTLS,
- _In_ ITfThreadMgr *pThreadMgr,
- _In_ HKL hKL,
- _In_ HWND hWnd)
+BYTE GetCharsetFromLangId(_In_ DWORD dwValue)
{
- CicProfile *pProfile = pTLS->m_pProfile;
- if (!pProfile)
- return E_OUTOFMEMORY;
-
- TF_LANGUAGEPROFILE profile;
- HRESULT hr = pProfile->GetActiveLanguageProfile(hKL, GUID_TFCAT_TIP_KEYBOARD, &profile);
- if (FAILED(hr))
- return hr;
-
- ITfFunctionProvider *pProvider = NULL;
- hr = pThreadMgr->GetFunctionProvider(profile.clsid, &pProvider);
- if (FAILED(hr))
- return hr;
-
- ITfFnConfigure *pFnConfigure = NULL;
- hr = pProvider->GetFunction(GUID_NULL, IID_ITfFnConfigure, (IUnknown**)&pFnConfigure);
- if (FAILED(hr))
- {
- pProvider->Release();
- return hr;
- }
-
- hr = pFnConfigure->Show(hWnd, profile.langid, profile.guidProfile);
-
- pFnConfigure->Release();
- pProvider->Release();
- return hr;
+ CHARSETINFO info;
+ if (!::TranslateCharsetInfo((DWORD*)(DWORD_PTR)dwValue, &info, TCI_SRCLOCALE))
+ return 0;
+ return info.ciCharset;
}
+/// Selects or unselects the input context.
/// @implemented
HRESULT
-CicBridge::ConfigureRegisterWord(
- _Inout_ TLS* pTLS,
- _In_ ITfThreadMgr *pThreadMgr,
- _In_ HKL hKL,
- _In_ HWND hWnd,
- _Inout_opt_ LPVOID lpData)
+InternalSelectEx(
+ _In_ HIMC hIMC,
+ _In_ BOOL fSelect,
+ _In_ LANGID LangID)
{
- CicProfile *pProfile = pTLS->m_pProfile;
- if (!pProfile)
- return E_OUTOFMEMORY;
-
- TF_LANGUAGEPROFILE profile;
- HRESULT hr = pProfile->GetActiveLanguageProfile(hKL, GUID_TFCAT_TIP_KEYBOARD, &profile);
- if (FAILED(hr))
- return hr;
+ CicIMCLock imcLock(hIMC);
+ if (!imcLock)
+ imcLock.m_hr = E_FAIL;
+ if (FAILED(imcLock.m_hr))
+ return imcLock.m_hr;
- ITfFunctionProvider *pProvider = NULL;
- hr = pThreadMgr->GetFunctionProvider(profile.clsid, &pProvider);
- if (FAILED(hr))
- return hr;
+ if (PRIMARYLANGID(LangID) == LANG_CHINESE)
+ {
+ imcLock.get().cfCandForm[0].dwStyle = 0;
+ imcLock.get().cfCandForm[0].dwIndex = (DWORD)-1;
+ }
- ITfFnConfigureRegisterWord *pFunction = NULL;
- hr = pProvider->GetFunction(GUID_NULL, IID_ITfFnConfigureRegisterWord, (IUnknown**)&pFunction);
- if (FAILED(hr))
+ if (!fSelect)
{
- pProvider->Release();
- return hr;
+ imcLock.get().fdwInit &= ~INIT_GUIDMAP;
+ return imcLock.m_hr;
}
- REGISTERWORDW* pRegWord = (REGISTERWORDW*)lpData;
- if (pRegWord)
+ if (!imcLock.ClearCand())
+ return imcLock.m_hr;
+
+ // Populate conversion mode
+ if (!(imcLock.get().fdwInit & INIT_CONVERSION))
{
- if (pRegWord->lpWord)
+ DWORD dwConv = (imcLock.get().fdwConversion & IME_CMODE_SOFTKBD);
+ if (LangID)
{
- hr = E_OUTOFMEMORY;
- BSTR bstrWord = SysAllocString(pRegWord->lpWord);
- if (bstrWord)
+ if (PRIMARYLANGID(LangID) == LANG_JAPANESE)
{
- hr = pFunction->Show(hWnd, profile.langid, profile.guidProfile, bstrWord);
- SysFreeString(bstrWord);
+ dwConv |= IME_CMODE_ROMAN | IME_CMODE_FULLSHAPE | IME_CMODE_NATIVE;
+ }
+ else if (PRIMARYLANGID(LangID) != LANG_KOREAN)
+ {
+ dwConv |= IME_CMODE_NATIVE;
}
}
- else
- {
- hr = pFunction->Show(hWnd, profile.langid, profile.guidProfile, NULL);
- }
+ imcLock.get().fdwConversion |= dwConv;
+ imcLock.get().fdwInit |= INIT_CONVERSION;
}
- pProvider->Release();
- pFunction->Release();
- return hr;
-}
+ // Populate sentence mode
+ imcLock.get().fdwSentence |= IME_SMODE_PHRASEPREDICT;
-/***********************************************************************
- * CicProfile
- */
+ // Populate LOGFONT
+ if (!(imcLock.get().fdwInit & INIT_LOGFONT))
+ {
+ // Get logical font
+ LOGFONTW lf;
+ HDC hDC = ::GetDC(imcLock.get().hWnd);
+ HGDIOBJ hFont = GetCurrentObject(hDC, OBJ_FONT);
+ ::GetObjectW(hFont, sizeof(LOGFONTW), &lf);
+ ::ReleaseDC(imcLock.get().hWnd, hDC);
-/// @unimplemented
-HRESULT
-CicProfile::GetActiveLanguageProfile(
- _In_ HKL hKL,
- _In_ REFGUID rguid,
- _Out_ TF_LANGUAGEPROFILE *pProfile)
-{
- return E_NOTIMPL;
+ imcLock.get().lfFont.W = lf;
+ imcLock.get().fdwInit |= INIT_LOGFONT;
+ }
+ imcLock.get().lfFont.W.lfCharSet = GetCharsetFromLangId(LangID);
+
+ imcLock.InitContext();
+
+ return imcLock.m_hr;
}
+class TLS;
+
/***********************************************************************
* ImeInquire (MSCTFIME.@)
*
return S_OK;
}
-/***********************************************************************
- * UIComposition
- */
-struct UIComposition
-{
- void OnImeStartComposition(CicIMCLock& imcLock, HWND hUIWnd);
- void OnImeCompositionUpdate(CicIMCLock& imcLock);
- void OnImeEndComposition();
- void OnImeSetContext(CicIMCLock& imcLock, HWND hUIWnd, WPARAM wParam, LPARAM lParam);
- void OnPaintTheme(WPARAM wParam);
- void OnDestroy();
-
- static LRESULT CALLBACK CompWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
-};
-
-/// @unimplemented
-void UIComposition::OnImeStartComposition(CicIMCLock& imcLock, HWND hUIWnd)
-{
- //FIXME
-}
-
-/// @unimplemented
-void UIComposition::OnImeCompositionUpdate(CicIMCLock& imcLock)
-{
- //FIXME
-}
-
-/// @unimplemented
-void UIComposition::OnImeEndComposition()
-{
- //FIXME
-}
-
-/// @unimplemented
-void UIComposition::OnImeSetContext(CicIMCLock& imcLock, HWND hUIWnd, WPARAM wParam, LPARAM lParam)
-{
- //FIXME
-}
-
-/// @unimplemented
-void UIComposition::OnPaintTheme(WPARAM wParam)
-{
- //FIXME
-}
-
-/// @unimplemented
-void UIComposition::OnDestroy()
-{
- //FIXME
-}
-
-/// @unimplemented
-LRESULT CALLBACK
-UIComposition::CompWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
-{
- if (uMsg == WM_CREATE)
- return -1; // FIXME
- return 0;
-}
-
-/***********************************************************************
- * UI
- */
-struct UI
-{
- HWND m_hWnd;
- UIComposition *m_pComp;
-
- UI(HWND hWnd);
- virtual ~UI();
-
- HRESULT _Create();
- void _Destroy();
-
- static void OnCreate(HWND hWnd);
- static void OnDestroy(HWND hWnd);
- void OnImeSetContext(CicIMCLock& imcLock, WPARAM wParam, LPARAM lParam);
-};
-
-// For GetWindowLongPtr/SetWindowLongPtr
-#define UIGWLP_HIMC 0
-#define UIGWLP_UI sizeof(HIMC)
-#define UIGWLP_SIZE (UIGWLP_UI + sizeof(UI*))
-
-/// @implemented
-UI::UI(HWND hWnd) : m_hWnd(hWnd)
-{
-}
-
-/// @implemented
-UI::~UI()
-{
- delete m_pComp;
-}
-
-/// @unimplemented
-HRESULT UI::_Create()
-{
- m_pComp = new(cicNoThrow) UIComposition();
- if (!m_pComp)
- return E_OUTOFMEMORY;
-
- SetWindowLongPtrW(m_hWnd, UIGWLP_UI, (LONG_PTR)this);
- //FIXME
- return S_OK;
-}
-
-/// @implemented
-void UI::_Destroy()
-{
- m_pComp->OnDestroy();
- SetWindowLongPtrW(m_hWnd, UIGWLP_UI, 0);
-}
-
-/// @implemented
-void UI::OnCreate(HWND hWnd)
-{
- UI *pUI = (UI*)GetWindowLongPtrW(hWnd, UIGWLP_UI);
- if (pUI)
- return;
- pUI = new(cicNoThrow) UI(hWnd);
- if (pUI)
- pUI->_Create();
-}
-
-/// @implemented
-void UI::OnDestroy(HWND hWnd)
-{
- UI *pUI = (UI*)GetWindowLongPtrW(hWnd, UIGWLP_UI);
- if (!pUI)
- return;
-
- pUI->_Destroy();
- delete pUI;
-}
-
-/// @implemented
-void UI::OnImeSetContext(CicIMCLock& imcLock, WPARAM wParam, LPARAM lParam)
-{
- m_pComp->OnImeSetContext(imcLock, m_hWnd, wParam, lParam);
-}
-
-/***********************************************************************
- * CIMEUIWindowHandler
- */
-
-struct CIMEUIWindowHandler
-{
- static LRESULT CALLBACK ImeUIMsImeHandler(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
- static LRESULT CALLBACK ImeUIMsImeMouseHandler(HWND hWnd, WPARAM wParam, LPARAM lParam);
- static LRESULT CALLBACK ImeUIMsImeModeBiasHandler(HWND hWnd, WPARAM wParam, LPARAM lParam);
- static LRESULT CALLBACK ImeUIMsImeReconvertRequest(HWND hWnd, WPARAM wParam, LPARAM lParam);
- static LRESULT CALLBACK ImeUIWndProcWorker(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
-};
-
-/// @unimplemented
-LRESULT CALLBACK
-CIMEUIWindowHandler::ImeUIMsImeMouseHandler(HWND hWnd, WPARAM wParam, LPARAM lParam)
-{
- return 0; //FIXME
-}
-
-/// @unimplemented
-LRESULT CALLBACK
-CIMEUIWindowHandler::ImeUIMsImeModeBiasHandler(HWND hWnd, WPARAM wParam, LPARAM lParam)
-{
- return 0; //FIXME
-}
-
-/// @unimplemented
-LRESULT CALLBACK
-CIMEUIWindowHandler::ImeUIMsImeReconvertRequest(HWND hWnd, WPARAM wParam, LPARAM lParam)
-{
- return 0; //FIXME
-}
-
-/// @implemented
-LRESULT CALLBACK
-CIMEUIWindowHandler::ImeUIMsImeHandler(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
-{
- if (uMsg == WM_MSIME_MOUSE)
- return ImeUIMsImeMouseHandler(hWnd, wParam, lParam);
- if (uMsg == WM_MSIME_MODEBIAS)
- return ImeUIMsImeModeBiasHandler(hWnd, wParam, lParam);
- if (uMsg == WM_MSIME_RECONVERTREQUEST)
- return ImeUIMsImeReconvertRequest(hWnd, wParam, lParam);
- if (uMsg == WM_MSIME_SERVICE)
- {
- TLS *pTLS = TLS::GetTLS();
- if (pTLS && pTLS->m_pProfile)
- {
- LANGID LangID;
- pTLS->m_pProfile->GetLangId(&LangID);
- if (PRIMARYLANGID(LangID) == LANG_KOREAN)
- return FALSE;
- }
- return TRUE;
- }
- return 0;
-}
-
-/// @unimplemented
-LRESULT CALLBACK
-CIMEUIWindowHandler::ImeUIWndProcWorker(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
-{
- TLS *pTLS = TLS::GetTLS();
- if (pTLS && (pTLS->m_dwSystemInfoFlags & IME_SYSINFO_WINLOGON))
- {
- if (uMsg == WM_CREATE)
- return -1;
- return DefWindowProcW(hWnd, uMsg, wParam, lParam);
- }
-
- switch (uMsg)
- {
- case WM_CREATE:
- {
- UI::OnCreate(hWnd);
- break;
- }
- case WM_DESTROY:
- case WM_ENDSESSION:
- {
- UI::OnDestroy(hWnd);
- break;
- }
- case WM_IME_STARTCOMPOSITION:
- case WM_IME_COMPOSITION:
- case WM_IME_ENDCOMPOSITION:
- case WM_IME_SETCONTEXT:
- case WM_IME_NOTIFY:
- case WM_IME_SELECT:
- case WM_TIMER:
- {
- HIMC hIMC = (HIMC)GetWindowLongPtrW(hWnd, UIGWLP_HIMC);
- UI* pUI = (UI*)GetWindowLongPtrW(hWnd, UIGWLP_UI);
- CicIMCLock imcLock(hIMC);
- switch (uMsg)
- {
- case WM_IME_STARTCOMPOSITION:
- {
- pUI->m_pComp->OnImeStartComposition(imcLock, pUI->m_hWnd);
- break;
- }
- case WM_IME_COMPOSITION:
- {
- if (lParam & GCS_COMPSTR)
- {
- pUI->m_pComp->OnImeCompositionUpdate(imcLock);
- ::SetTimer(hWnd, 0, 10, NULL);
- //FIXME
- }
- break;
- }
- case WM_IME_ENDCOMPOSITION:
- {
- ::KillTimer(hWnd, 0);
- pUI->m_pComp->OnImeEndComposition();
- break;
- }
- case WM_IME_SETCONTEXT:
- {
- pUI->OnImeSetContext(imcLock, wParam, lParam);
- ::KillTimer(hWnd, 1);
- ::SetTimer(hWnd, 1, 300, NULL);
- break;
- }
- case WM_TIMER:
- {
- //FIXME
- ::KillTimer(hWnd, wParam);
- break;
- }
- case WM_IME_NOTIFY:
- case WM_IME_SELECT:
- default:
- {
- pUI->m_pComp->OnPaintTheme(wParam);
- break;
- }
- }
- break;
- }
- default:
- {
- if (IsMsImeMessage(uMsg))
- return CIMEUIWindowHandler::ImeUIMsImeHandler(hWnd, uMsg, wParam, lParam);
- return DefWindowProcW(hWnd, uMsg, wParam, lParam);
- }
- }
-
- return 0;
-}
-
-/// @implemented
-EXTERN_C LRESULT CALLBACK
-UIWndProc(
- _In_ HWND hWnd,
- _In_ UINT uMsg,
- _In_ WPARAM wParam,
- _In_ LPARAM lParam)
-{
- return CIMEUIWindowHandler::ImeUIWndProcWorker(hWnd, uMsg, wParam, lParam);
-}
-
-/// @unimplemented
-BOOL RegisterImeClass(VOID)
-{
- WNDCLASSEXW wcx;
-
- if (!GetClassInfoExW(g_hInst, L"MSCTFIME UI", &wcx))
- {
- ZeroMemory(&wcx, sizeof(wcx));
- wcx.cbSize = sizeof(WNDCLASSEXW);
- wcx.cbWndExtra = UIGWLP_SIZE;
- wcx.hIcon = LoadIconW(0, (LPCWSTR)IDC_ARROW);
- wcx.hInstance = g_hInst;
- wcx.hCursor = LoadCursorW(NULL, (LPCWSTR)IDC_ARROW);
- wcx.hbrBackground = (HBRUSH)GetStockObject(NULL_BRUSH);
- wcx.style = CS_IME | CS_GLOBALCLASS;
- wcx.lpfnWndProc = UIWndProc;
- wcx.lpszClassName = L"MSCTFIME UI";
- if (!RegisterClassExW(&wcx))
- return FALSE;
- }
-
- if (!GetClassInfoExW(g_hInst, L"MSCTFIME Composition", &wcx))
- {
- ZeroMemory(&wcx, sizeof(wcx));
- wcx.cbSize = sizeof(WNDCLASSEXW);
- wcx.cbWndExtra = sizeof(DWORD);
- wcx.hIcon = NULL;
- wcx.hInstance = g_hInst;
- wcx.hCursor = LoadCursorW(NULL, (LPCWSTR)IDC_IBEAM);
- wcx.hbrBackground = (HBRUSH)GetStockObject(NULL_BRUSH);
- wcx.style = CS_IME | CS_HREDRAW | CS_VREDRAW;
- wcx.lpfnWndProc = UIComposition::CompWndProc;
- wcx.lpszClassName = L"MSCTFIME Composition";
- if (!RegisterClassExW(&wcx))
- return FALSE;
- }
-
- return TRUE;
-}
-
-/// @implemented
-VOID UnregisterImeClass(VOID)
-{
- WNDCLASSEXW wcx;
-
- GetClassInfoExW(g_hInst, L"MSCTFIME UI", &wcx);
- UnregisterClassW(L"MSCTFIME UI", g_hInst);
- DestroyIcon(wcx.hIcon);
- DestroyIcon(wcx.hIconSm);
-
- GetClassInfoExW(g_hInst, L"MSCTFIME Composition", &wcx);
- UnregisterClassW(L"MSCTFIME Composition", g_hInst);
- DestroyIcon(wcx.hIcon);
- DestroyIcon(wcx.hIconSm);
-}
-
/// @implemented
BOOL AttachIME(VOID)
{