[PATCH 1/3] msctf: Implement ITfThreadMgr2 stub.

Jactry Zeng jzeng at codeweavers.com
Wed Sep 25 10:13:54 CDT 2019


Signed-off-by: Jactry Zeng <jzeng at codeweavers.com>
---
 dlls/msctf/tests/inputprocessor.c |  49 +++++++++
 dlls/msctf/threadmgr.c            | 176 ++++++++++++++++++++++++++++++
 include/msctf.idl                 |  23 ++++
 3 files changed, 248 insertions(+)

diff --git a/dlls/msctf/tests/inputprocessor.c b/dlls/msctf/tests/inputprocessor.c
index 1222085fe0..ebc0e36154 100644
--- a/dlls/msctf/tests/inputprocessor.c
+++ b/dlls/msctf/tests/inputprocessor.c
@@ -2558,6 +2558,54 @@ static void test_MultiThreadApartment(void)
     CloseHandle(thread);
 }
 
+static void test_thread_mgr2(void)
+{
+    TfClientId clientid1, clientid2, clientid3;
+    ITfDocumentMgr *docmgr;
+    ITfThreadMgr2 *thmgr2;
+    ITfThreadMgr *thmgr;
+    HRESULT hr;
+
+    hr = CoCreateInstance(&CLSID_TF_ThreadMgr, NULL, CLSCTX_INPROC_SERVER,
+                          &IID_ITfThreadMgr2, (void**)&thmgr2);
+    ok(hr == S_OK || broken(hr == E_NOINTERFACE), /* pre-win8 */
+       "Couldn't create ITfThreadMgr2: %#x.\n", hr);
+
+    if (FAILED(hr))
+    {
+        win_skip("ITfThreadMgr2 interface isn't available.\n");
+        return;
+    }
+
+    hr = ITfThreadMgr2_QueryInterface(thmgr2, &IID_ITfThreadMgr, (void **)&thmgr);
+    ok(hr == S_OK, "ITfThreadMgr2_QueryInterface failed: %#x.\n", hr);
+    ITfThreadMgr_Release(thmgr);
+
+    hr = ITfThreadMgr2_ActivateEx(thmgr2, &clientid1, 0);
+    ok(hr == S_OK, "ITfThreadMgr2_ActivateEx failed: %#x.\n", hr);
+
+    hr = ITfThreadMgr_Activate(g_tm, &clientid2);
+    ok(hr == S_OK, "ITfThreadMgr_Activate failed: %#x.\n", hr);
+    ok(clientid1 == clientid2, "Got unexpected client ID.\n");
+
+    hr = ITfThreadMgr_Activate(thmgr, &clientid3);
+    ok(hr == S_OK, "ITfThreadMgr_Activate failed: %#x.\n", hr);
+    ok(clientid1 == clientid3, "Got unexpected client ID.\n");
+
+    hr = ITfThreadMgr2_CreateDocumentMgr(thmgr2, &docmgr);
+    ok(hr == S_OK, "ITfThreadMgr2_CreateDocumentMgr failed: %#x.\n", hr);
+
+    hr = ITfThreadMgr2_Deactivate(thmgr2);
+    ok(hr == S_OK, "ITfThreadMgr2_Deactivate failed: %#x.\n", hr);
+    hr = ITfThreadMgr2_Deactivate(thmgr2);
+    ok(hr == S_OK, "ITfThreadMgr2_Deactivate failed: %#x.\n", hr);
+    hr = ITfThreadMgr2_Deactivate(thmgr2);
+    ok(hr == S_OK, "ITfThreadMgr2_Deactivate failed: %#x.\n", hr);
+
+    ITfDocumentMgr_Release(docmgr);
+    ITfThreadMgr2_Release(thmgr2);
+}
+
 START_TEST(inputprocessor)
 {
     if (SUCCEEDED(initialize()))
@@ -2588,6 +2636,7 @@ START_TEST(inputprocessor)
         test_Unregister();
         test_profile_mgr();
         test_MultiThreadApartment();
+        test_thread_mgr2();
 
         ITextStoreACPSink_Release(ACPSink);
         ITfDocumentMgr_Release(g_dm);
diff --git a/dlls/msctf/threadmgr.c b/dlls/msctf/threadmgr.c
index 2c208fbc04..2e5deb62ee 100644
--- a/dlls/msctf/threadmgr.c
+++ b/dlls/msctf/threadmgr.c
@@ -61,6 +61,7 @@ typedef struct tagAssociatedWindow
 
 typedef struct tagACLMulti {
     ITfThreadMgrEx ITfThreadMgrEx_iface;
+    ITfThreadMgr2 ITfThreadMgr2_iface;
     ITfSource ITfSource_iface;
     ITfKeystrokeMgr ITfKeystrokeMgr_iface;
     ITfMessagePump ITfMessagePump_iface;
@@ -115,6 +116,11 @@ static inline ThreadMgr *impl_from_ITfThreadMgrEx(ITfThreadMgrEx *iface)
     return CONTAINING_RECORD(iface, ThreadMgr, ITfThreadMgrEx_iface);
 }
 
+static inline ThreadMgr *impl_from_ITfThreadMgr2(ITfThreadMgr2 *iface)
+{
+    return CONTAINING_RECORD(iface, ThreadMgr, ITfThreadMgr2_iface);
+}
+
 static inline ThreadMgr *impl_from_ITfSource(ITfSource *iface)
 {
     return CONTAINING_RECORD(iface, ThreadMgr, ITfSource_iface);
@@ -215,6 +221,10 @@ static HRESULT WINAPI ThreadMgr_QueryInterface(ITfThreadMgrEx *iface, REFIID iid
     {
         *ppvOut = &This->ITfThreadMgrEx_iface;
     }
+    else if (IsEqualIID(iid, &IID_ITfThreadMgr2))
+    {
+        *ppvOut = &This->ITfThreadMgr2_iface;
+    }
     else if (IsEqualIID(iid, &IID_ITfSource))
     {
         *ppvOut = &This->ITfSource_iface;
@@ -581,6 +591,171 @@ static const ITfThreadMgrExVtbl ThreadMgrExVtbl =
     ThreadMgr_GetActiveFlags
 };
 
+static HRESULT WINAPI ThreadMgr2_QueryInterface(ITfThreadMgr2 *iface, REFIID iid, LPVOID *out)
+{
+    ThreadMgr *This = impl_from_ITfThreadMgr2(iface);
+    return ITfThreadMgrEx_QueryInterface(&This->ITfThreadMgrEx_iface, iid, out);
+}
+
+static ULONG WINAPI ThreadMgr2_AddRef(ITfThreadMgr2 *iface)
+{
+    ThreadMgr *This = impl_from_ITfThreadMgr2(iface);
+    return ITfThreadMgrEx_AddRef(&This->ITfThreadMgrEx_iface);
+}
+
+static ULONG WINAPI ThreadMgr2_Release(ITfThreadMgr2 *iface)
+{
+    ThreadMgr *This = impl_from_ITfThreadMgr2(iface);
+    return ITfThreadMgrEx_Release(&This->ITfThreadMgrEx_iface);
+}
+
+static HRESULT WINAPI ThreadMgr2_Activate(ITfThreadMgr2 *iface, TfClientId *id)
+{
+    ThreadMgr *This = impl_from_ITfThreadMgr2(iface);
+
+    TRACE("(%p, %p).\n", This, id);
+
+    return ITfThreadMgrEx_Activate(&This->ITfThreadMgrEx_iface, id);
+}
+
+static HRESULT WINAPI ThreadMgr2_Deactivate(ITfThreadMgr2 *iface)
+{
+    ThreadMgr *This = impl_from_ITfThreadMgr2(iface);
+
+    TRACE("(%p).\n", This);
+
+    return ITfThreadMgrEx_Deactivate(&This->ITfThreadMgrEx_iface);
+}
+
+static HRESULT WINAPI ThreadMgr2_CreateDocumentMgr(ITfThreadMgr2 *iface, ITfDocumentMgr **manager)
+{
+    ThreadMgr *This = impl_from_ITfThreadMgr2(iface);
+
+    TRACE("(%p, %p).\n", This, manager);
+
+    return ITfThreadMgrEx_CreateDocumentMgr(&This->ITfThreadMgrEx_iface, manager);
+}
+
+static HRESULT WINAPI ThreadMgr2_EnumDocumentMgrs(ITfThreadMgr2 *iface, IEnumTfDocumentMgrs **managers)
+{
+    ThreadMgr *This = impl_from_ITfThreadMgr2(iface);
+
+    FIXME("(%p, %p): stub.\n", This, managers);
+
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ThreadMgr2_GetFocus(ITfThreadMgr2 *iface, ITfDocumentMgr **focus)
+{
+    ThreadMgr *This = impl_from_ITfThreadMgr2(iface);
+
+    FIXME("(%p, %p): stub.\n", This, focus);
+
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ThreadMgr2_SetFocus(ITfThreadMgr2 *iface, ITfDocumentMgr *focus)
+{
+    ThreadMgr *This = impl_from_ITfThreadMgr2(iface);
+
+    FIXME("(%p, %p): stub.\n", This, focus);
+
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ThreadMgr2_IsThreadFocus(ITfThreadMgr2 *iface, BOOL *focus)
+{
+    ThreadMgr *This = impl_from_ITfThreadMgr2(iface);
+
+    FIXME("(%p, %p): stub.\n", This, focus);
+
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ThreadMgr2_GetFunctionProvider(ITfThreadMgr2 *iface, REFCLSID clsid, ITfFunctionProvider **provider)
+{
+    ThreadMgr *This = impl_from_ITfThreadMgr2(iface);
+
+    FIXME("(%p, %p): stub.\n", This, provider);
+
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ThreadMgr2_EnumFunctionProviders(ITfThreadMgr2 *iface, IEnumTfFunctionProviders **providers)
+{
+    ThreadMgr *This = impl_from_ITfThreadMgr2(iface);
+
+    FIXME("(%p, %p): stub.\n", This, providers);
+
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ThreadMgr2_GetGlobalCompartment(ITfThreadMgr2 *iface, ITfCompartmentMgr **compartment)
+{
+    ThreadMgr *This = impl_from_ITfThreadMgr2(iface);
+
+    FIXME("(%p, %p): stub.\n", This, compartment);
+
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ThreadMgr2_ActivateEx(ITfThreadMgr2 *iface, TfClientId *id, DWORD flags)
+{
+    ThreadMgr *This = impl_from_ITfThreadMgr2(iface);
+
+    TRACE("(%p, %p, %x).\n", This, id, flags);
+
+    return ITfThreadMgrEx_ActivateEx(&This->ITfThreadMgrEx_iface, id, flags);
+}
+
+static HRESULT WINAPI ThreadMgr2_GetActiveFlags(ITfThreadMgr2 *iface, DWORD *flags)
+{
+    ThreadMgr *This = impl_from_ITfThreadMgr2(iface);
+
+    FIXME("(%p, %p): stub.\n", This, flags);
+
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ThreadMgr2_SuspendKeystrokeHandling(ITfThreadMgr2 *iface)
+{
+    ThreadMgr *This = impl_from_ITfThreadMgr2(iface);
+
+    FIXME("(%p): stub.\n", This);
+
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ThreadMgr2_ResumeKeystrokeHandling(ITfThreadMgr2 *iface)
+{
+    ThreadMgr *This = impl_from_ITfThreadMgr2(iface);
+
+    FIXME("(%p): stub.\n", This);
+
+    return E_NOTIMPL;
+}
+
+static const ITfThreadMgr2Vtbl ThreadMgr2Vtbl =
+{
+    ThreadMgr2_QueryInterface,
+    ThreadMgr2_AddRef,
+    ThreadMgr2_Release,
+    ThreadMgr2_Activate,
+    ThreadMgr2_Deactivate,
+    ThreadMgr2_CreateDocumentMgr,
+    ThreadMgr2_EnumDocumentMgrs,
+    ThreadMgr2_GetFocus,
+    ThreadMgr2_SetFocus,
+    ThreadMgr2_IsThreadFocus,
+    ThreadMgr2_GetFunctionProvider,
+    ThreadMgr2_EnumFunctionProviders,
+    ThreadMgr2_GetGlobalCompartment,
+    ThreadMgr2_ActivateEx,
+    ThreadMgr2_GetActiveFlags,
+    ThreadMgr2_SuspendKeystrokeHandling,
+    ThreadMgr2_ResumeKeystrokeHandling,
+};
+
 static HRESULT WINAPI Source_QueryInterface(ITfSource *iface, REFIID iid, LPVOID *ppvOut)
 {
     ThreadMgr *This = impl_from_ITfSource(iface);
@@ -1351,6 +1526,7 @@ HRESULT ThreadMgr_Constructor(IUnknown *pUnkOuter, IUnknown **ppOut)
         return E_OUTOFMEMORY;
 
     This->ITfThreadMgrEx_iface.lpVtbl = &ThreadMgrExVtbl;
+    This->ITfThreadMgr2_iface.lpVtbl = &ThreadMgr2Vtbl;
     This->ITfSource_iface.lpVtbl = &ThreadMgrSourceVtbl;
     This->ITfKeystrokeMgr_iface.lpVtbl = &KeystrokeMgrVtbl;
     This->ITfMessagePump_iface.lpVtbl = &MessagePumpVtbl;
diff --git a/include/msctf.idl b/include/msctf.idl
index 5ef33119fd..8de62d0add 100644
--- a/include/msctf.idl
+++ b/include/msctf.idl
@@ -228,6 +228,29 @@ interface ITfThreadMgrEx : ITfThreadMgr
         [out] DWORD *flags);
 }
 
+[
+    object,
+    uuid(0ab198ef-6477-4ee8-8812-6780edb82d5e),
+    pointer_default(unique)
+]
+interface ITfThreadMgr2 : IUnknown
+{
+    HRESULT Activate([out] TfClientId *id);
+    HRESULT Deactivate();
+    HRESULT CreateDocumentMgr([out] ITfDocumentMgr **manager);
+    HRESULT EnumDocumentMgrs([out] IEnumTfDocumentMgrs **managers);
+    HRESULT GetFocus([out] ITfDocumentMgr **focus);
+    HRESULT SetFocus([in] ITfDocumentMgr *focus);
+    HRESULT IsThreadFocus([out] BOOL *focus);
+    HRESULT GetFunctionProvider([in] REFCLSID clsid, [out] ITfFunctionProvider **provider);
+    HRESULT EnumFunctionProviders([out] IEnumTfFunctionProviders **providers);
+    HRESULT GetGlobalCompartment([out] ITfCompartmentMgr **compartment);
+    HRESULT ActivateEx([out] TfClientId *id, [in] DWORD flags);
+    HRESULT GetActiveFlags([out] DWORD *flags);
+    HRESULT SuspendKeystrokeHandling();
+    HRESULT ResumeKeystrokeHandling();
+}
+
 [
     object,
     uuid(d7540241-f9a1-4364-befc-dbcd2c4395b7),
-- 
2.23.0





More information about the wine-devel mailing list