msctf: Implement ITfClientId.
diff --git a/dlls/msctf/tests/inputprocessor.c b/dlls/msctf/tests/inputprocessor.c
index b5ae508..8d6579b 100644
--- a/dlls/msctf/tests/inputprocessor.c
+++ b/dlls/msctf/tests/inputprocessor.c
@@ -648,6 +648,36 @@
todo_wine ok(!IsEqualGUID(&g1,&GUID_NULL),"guid should not be NULL\n");
}
+static void test_ClientId(void)
+{
+ ITfClientId *pcid;
+ TfClientId id1,id2;
+ HRESULT hr;
+ GUID g2;
+
+ hr = ITfThreadMgr_QueryInterface(g_tm, &IID_ITfClientId, (LPVOID*)&pcid);
+ ok(SUCCEEDED(hr),"Unable to aquire ITfClientId interface\n");
+
+ CoCreateGuid(&g2);
+
+ hr = ITfClientId_GetClientId(pcid,&GUID_NULL,&id1);
+ ok(SUCCEEDED(hr),"GetClientId failed\n");
+ hr = ITfClientId_GetClientId(pcid,&GUID_NULL,&id2);
+ ok(SUCCEEDED(hr),"GetClientId failed\n");
+ ok(id1==id2,"Id's for GUID_NULL do not match\n");
+ hr = ITfClientId_GetClientId(pcid,&CLSID_FakeService,&id2);
+ ok(SUCCEEDED(hr),"GetClientId failed\n");
+ ok(id2!=id1,"Id matches GUID_NULL\n");
+ todo_wine ok(id2==tid,"Id for CLSID_FakeService not matching tid\n");
+ ok(id2!=cid,"Id for CLSID_FakeService matching cid\n");
+ hr = ITfClientId_GetClientId(pcid,&g2,&id2);
+ ok(SUCCEEDED(hr),"GetClientId failed\n");
+ ok(id2!=id1,"Id matches GUID_NULL\n");
+ ok(id2!=tid,"Id for random guid matching tid\n");
+ ok(id2!=cid,"Id for random guid matching cid\n");
+ ITfClientId_Release(pcid);
+}
+
START_TEST(inputprocessor)
{
if (SUCCEEDED(initialize()))
@@ -660,6 +690,7 @@
test_Activate();
test_startSession();
test_TfGuidAtom();
+ test_ClientId();
test_KeystrokeMgr();
test_endSession();
test_EnumLanguageProfiles();
diff --git a/dlls/msctf/threadmgr.c b/dlls/msctf/threadmgr.c
index fa13a2f..fcd4dae 100644
--- a/dlls/msctf/threadmgr.c
+++ b/dlls/msctf/threadmgr.c
@@ -61,6 +61,7 @@
const ITfSourceVtbl *SourceVtbl;
const ITfKeystrokeMgrVtbl *KeystrokeMgrVtbl;
const ITfMessagePumpVtbl *MessagePumpVtbl;
+ const ITfClientIdVtbl *ClientIdVtbl;
LONG refCount;
const ITfThreadMgrEventSinkVtbl *ThreadMgrEventSinkVtbl; /* internal */
@@ -91,6 +92,11 @@
return (ThreadMgr *)((char *)iface - FIELD_OFFSET(ThreadMgr,MessagePumpVtbl));
}
+static inline ThreadMgr *impl_from_ITfClientIdVtbl(ITfClientId *iface)
+{
+ return (ThreadMgr *)((char *)iface - FIELD_OFFSET(ThreadMgr,ClientIdVtbl));
+}
+
static inline ThreadMgr *impl_from_ITfThreadMgrEventSink(ITfThreadMgrEventSink *iface)
{
return (ThreadMgr *)((char *)iface - FIELD_OFFSET(ThreadMgr,ThreadMgrEventSinkVtbl));
@@ -173,6 +179,10 @@
{
*ppvOut = &This->MessagePumpVtbl;
}
+ else if (IsEqualIID(iid, &IID_ITfClientId))
+ {
+ *ppvOut = &This->ClientIdVtbl;
+ }
if (*ppvOut)
{
@@ -660,6 +670,54 @@
};
/*****************************************************
+ * ITfClientId functions
+ *****************************************************/
+
+static HRESULT WINAPI ClientId_QueryInterface(ITfClientId *iface, REFIID iid, LPVOID *ppvOut)
+{
+ ThreadMgr *This = impl_from_ITfClientIdVtbl(iface);
+ return ThreadMgr_QueryInterface((ITfThreadMgr *)This, iid, *ppvOut);
+}
+
+static ULONG WINAPI ClientId_AddRef(ITfClientId *iface)
+{
+ ThreadMgr *This = impl_from_ITfClientIdVtbl(iface);
+ return ThreadMgr_AddRef((ITfThreadMgr*)This);
+}
+
+static ULONG WINAPI ClientId_Release(ITfClientId *iface)
+{
+ ThreadMgr *This = impl_from_ITfClientIdVtbl(iface);
+ return ThreadMgr_Release((ITfThreadMgr *)This);
+}
+
+static HRESULT WINAPI ClientId_GetClientId(ITfClientId *iface,
+ REFCLSID rclsid, TfClientId *ptid)
+
+{
+ HRESULT hr;
+ ITfCategoryMgr *catmgr;
+ ThreadMgr *This = impl_from_ITfClientIdVtbl(iface);
+
+ TRACE("(%p) %s\n",This,debugstr_guid(rclsid));
+
+ CategoryMgr_Constructor(NULL,(IUnknown**)&catmgr);
+ hr = ITfCategoryMgr_RegisterGUID(catmgr,rclsid,ptid);
+ ITfCategoryMgr_Release(catmgr);
+
+ return hr;
+}
+
+static const ITfClientIdVtbl ThreadMgr_ClientIdVtbl =
+{
+ ClientId_QueryInterface,
+ ClientId_AddRef,
+ ClientId_Release,
+
+ ClientId_GetClientId
+};
+
+/*****************************************************
* ITfThreadMgrEventSink functions (internal)
*****************************************************/
static HRESULT WINAPI ThreadMgrEventSink_QueryInterface(ITfThreadMgrEventSink *iface, REFIID iid, LPVOID *ppvOut)
@@ -803,6 +861,7 @@
This->SourceVtbl = &ThreadMgr_SourceVtbl;
This->KeystrokeMgrVtbl= &ThreadMgr_KeystrokeMgrVtbl;
This->MessagePumpVtbl= &ThreadMgr_MessagePumpVtbl;
+ This->ClientIdVtbl = &ThreadMgr_ClientIdVtbl;
This->ThreadMgrEventSinkVtbl = &ThreadMgr_ThreadMgrEventSinkVtbl;
This->refCount = 1;
TlsSetValue(tlsIndex,This);
diff --git a/include/msctf.idl b/include/msctf.idl
index 115e643..7e643f4 100644
--- a/include/msctf.idl
+++ b/include/msctf.idl
@@ -686,3 +686,16 @@
[in] UINT wMsgFilterMax,
[out] BOOL *pfResult);
};
+
+[
+ object,
+ local,
+ uuid(d60a7b49-1b9f-4be2-b702-47e9dc05dec3),
+ pointer_default(unique)
+]
+interface ITfClientId : IUnknown
+{
+ HRESULT GetClientId(
+ [in] REFCLSID rclsid,
+ [out] TfClientId *ptid);
+};