https://git.reactos.org/?p=reactos.git;a=commitdiff;h=6c438e4530fe2e26c4b89…
commit 6c438e4530fe2e26c4b8922934660e68cfb79aa4
Author: Katayama Hirofumi MZ <katayama.hirofumi.mz(a)gmail.com>
AuthorDate: Tue Dec 19 19:23:52 2023 +0900
Commit: GitHub <noreply(a)github.com>
CommitDate: Tue Dec 19 19:23:52 2023 +0900
[MSCTFIME] Implement ImeConfigure (#6197)
Add code to CicInputContext and CicBridge classes.
Implement ImeConfigure function by using them.
CORE-19360
---
dll/ime/msctfime/msctfime.cpp | 166 +++++++++++++++++++++++++++++++++++++++++-
dll/ime/msctfime/msctfime.h | 2 +
2 files changed, 166 insertions(+), 2 deletions(-)
diff --git a/dll/ime/msctfime/msctfime.cpp b/dll/ime/msctfime/msctfime.cpp
index 8d1d17f364a..1fcdf3363a4 100644
--- a/dll/ime/msctfime/msctfime.cpp
+++ b/dll/ime/msctfime/msctfime.cpp
@@ -83,7 +83,7 @@ IsInteractiveUserLogon(VOID)
}
/* FIXME */
-class CicInputContext : public IUnknown
+class CicInputContext : public ITfContextOwnerCompositionSink
{
LONG m_cRefs;
public:
@@ -95,10 +95,16 @@ public:
{
}
+ // IUnknown interface
STDMETHODIMP QueryInterface(REFIID riid, LPVOID* ppvObj) override;
STDMETHODIMP_(ULONG) AddRef() override;
STDMETHODIMP_(ULONG) Release() override;
+ // ITfContextOwnerCompositionSink interface
+ STDMETHODIMP OnStartComposition(ITfCompositionView *pComposition, BOOL *pfOk)
override;
+ STDMETHODIMP OnUpdateComposition(ITfCompositionView *pComposition, ITfRange
*pRangeNew) override;
+ STDMETHODIMP OnEndComposition(ITfCompositionView *pComposition) override;
+
HRESULT
GetGuidAtom(
_Inout_ IMCLock& imcLock,
@@ -152,6 +158,38 @@ STDMETHODIMP_(ULONG) CicInputContext::Release()
return m_cRefs;
}
+/**
+ * @unimplemented
+ */
+STDMETHODIMP
+CicInputContext::OnStartComposition(
+ ITfCompositionView *pComposition,
+ BOOL *pfOk)
+{
+ return E_NOTIMPL;
+}
+
+/**
+ * @unimplemented
+ */
+STDMETHODIMP
+CicInputContext::OnUpdateComposition(
+ ITfCompositionView *pComposition,
+ ITfRange *pRangeNew)
+{
+ return E_NOTIMPL;
+}
+
+/**
+ * @unimplemented
+ */
+STDMETHODIMP
+CicInputContext::OnEndComposition(
+ ITfCompositionView *pComposition)
+{
+ return E_NOTIMPL;
+}
+
/**
* @unimplemented
*/
@@ -291,11 +329,15 @@ public:
HRESULT ActivateIMMX(TLS *pTLS, ITfThreadMgr *pThreadMgr);
HRESULT DeactivateIMMX(TLS *pTLS, ITfThreadMgr *pThreadMgr);
HRESULT DestroyInputContext(TLS *pTLS, HIMC hIMC);
+
+ HRESULT ConfigureGeneral(TLS* pTLS, ITfThreadMgr *pThreadMgr, HKL hKL, HWND hWnd);
+ HRESULT ConfigureRegisterWord(TLS* pTLS, ITfThreadMgr *pThreadMgr, HKL hKL, HWND
hWnd, LPVOID lpData);
};
/* FIXME */
struct CicProfile : IUnknown
{
+ HRESULT GetActiveLanguageProfile(HKL hKL, REFGUID rguid, TF_LANGUAGEPROFILE
*pProfile);
};
class TLS
@@ -589,6 +631,112 @@ STDMETHODIMP CicBridge::OnSysShellProc(INT, UINT, LONG)
return S_OK;
}
+HRESULT
+CicBridge::ConfigureGeneral(
+ TLS* pTLS,
+ ITfThreadMgr *pThreadMgr,
+ HKL hKL,
+ HWND hWnd)
+{
+ 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;
+}
+
+HRESULT
+CicBridge::ConfigureRegisterWord(
+ TLS* pTLS,
+ ITfThreadMgr *pThreadMgr,
+ HKL hKL,
+ HWND hWnd,
+ LPVOID lpData)
+{
+ 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;
+ hr = pThreadMgr->GetFunctionProvider(profile.clsid, &pProvider);
+ if (FAILED(hr))
+ return hr;
+
+ ITfFnConfigureRegisterWord *pFunction;
+ hr = pProvider->GetFunction(GUID_NULL, IID_ITfFnConfigureRegisterWord,
(IUnknown**)pFunction);
+ if (FAILED(hr))
+ {
+ pProvider->Release();
+ return hr;
+ }
+
+ REGISTERWORDW* pRegWord = (REGISTERWORDW*)lpData;
+ if (pRegWord)
+ {
+ if (pRegWord->lpWord)
+ {
+ hr = E_OUTOFMEMORY;
+ BSTR bstrWord = SysAllocString(pRegWord->lpWord);
+ if (bstrWord)
+ {
+ hr = pFunction->Show(hWnd, profile.langid, profile.guidProfile,
bstrWord);
+ SysFreeString(bstrWord);
+ }
+ }
+ else
+ {
+ hr = pFunction->Show(hWnd, profile.langid, profile.guidProfile, NULL);
+ }
+ }
+
+ pProvider->Release();
+ pFunction->Release();
+ return hr;
+}
+
+/***********************************************************************
+ * CicProfile
+ */
+
+/**
+ * @unimplemented
+ */
+HRESULT
+CicProfile::GetActiveLanguageProfile(
+ HKL hKL,
+ REFGUID rguid,
+ TF_LANGUAGEPROFILE *pProfile)
+{
+ return E_NOTIMPL;
+}
+
/***********************************************************************
* ImeInquire (MSCTFIME.@)
*
@@ -709,7 +857,21 @@ ImeConfigure(
_In_ DWORD dwMode,
_Inout_opt_ LPVOID lpData)
{
- FIXME("stub:(%p, %p, %lu, %p)\n", hKL, hWnd, dwMode, lpData);
+ TRACE("(%p, %p, %lu, %p)\n", hKL, hWnd, dwMode, lpData);
+
+ TLS *pTLS = TLS::GetTLS();
+ if (!pTLS || !pTLS->m_pBridge || !pTLS->m_pThreadMgr)
+ return FALSE;
+
+ CicBridge *pBridge = pTLS->m_pBridge;
+ ITfThreadMgr *pThreadMgr = pTLS->m_pThreadMgr;
+
+ if (dwMode & 1)
+ return (pBridge->ConfigureGeneral(pTLS, pThreadMgr, hKL, hWnd) == S_OK);
+
+ if (dwMode & 2)
+ return (pBridge->ConfigureRegisterWord(pTLS, pThreadMgr, hKL, hWnd, lpData) ==
S_OK);
+
return FALSE;
}
diff --git a/dll/ime/msctfime/msctfime.h b/dll/ime/msctfime/msctfime.h
index 9b962285029..892bd76ef26 100644
--- a/dll/ime/msctfime/msctfime.h
+++ b/dll/ime/msctfime/msctfime.h
@@ -16,7 +16,9 @@
#include <windows.h>
#include <imm.h>
#include <ddk/immdev.h>
+#include <cguid.h>
#include <msctf.h>
+#include <ctffunc.h>
#include <shlwapi.h>
#include <strsafe.h>