[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