[MSCTF_WINETEST] Sync with Wine Staging 1.9.23. CORE-12409
[reactos.git] / rostests / winetests / msctf / inputprocessor.c
index 8f409c3..18a248f 100644 (file)
@@ -62,6 +62,7 @@ static BOOL test_ShouldDeactivate = FALSE;
 
 static DWORD tmSinkCookie;
 static DWORD tmSinkRefCount;
+static DWORD dmSinkCookie;
 static DWORD documentStatus;
 static ITfDocumentMgr *test_CurrentFocus = NULL;
 static ITfDocumentMgr *test_PrevFocus = NULL;
@@ -73,6 +74,7 @@ static INT  test_OnPushContext = SINK_UNEXPECTED;
 static INT  test_OnPopContext = SINK_UNEXPECTED;
 static INT  test_KEV_OnSetFocus = SINK_UNEXPECTED;
 static INT  test_ACP_AdviseSink = SINK_UNEXPECTED;
+static INT  test_ACP_UnadviseSink = SINK_UNEXPECTED;
 static INT  test_ACP_GetStatus = SINK_UNEXPECTED;
 static INT  test_ACP_RequestLock = SINK_UNEXPECTED;
 static INT  test_ACP_GetEndACP = SINK_UNEXPECTED;
@@ -117,9 +119,7 @@ static inline void _sink_fire_ok(INT *sink, const CHAR* name)
             *sink = (*sink & ~SINK_EXPECTED_COUNT_MASK) + (count << 16);
             return;
         default:
-            if (todo)
-                todo_wine winetest_ok(0, "Unexpected %s sink\n",name);
-            else
+            todo_wine_if (todo)
                 winetest_ok(0, "Unexpected %s sink\n",name);
     }
     *sink = SINK_FIRED;
@@ -147,9 +147,7 @@ static inline void _sink_check_ok(INT *sink, const CHAR* name)
                 winetest_trace("optional sink %s not fired\n",name);
             break;
         default:
-            if (todo)
-                todo_wine winetest_ok(0, "%s not fired as expected, in state %x\n",name,*sink);
-            else
+            todo_wine_if (todo)
                 winetest_ok(0, "%s not fired as expected, in state %x\n",name,*sink);
     }
     *sink = SINK_UNEXPECTED;
@@ -193,17 +191,16 @@ static void TextStoreACP_Destructor(TextStoreACP *This)
 
 static HRESULT WINAPI TextStoreACP_QueryInterface(ITextStoreACP *iface, REFIID iid, LPVOID *ppvOut)
 {
-    TextStoreACP *This = impl_from_ITextStoreACP(iface);
     *ppvOut = NULL;
 
     if (IsEqualIID(iid, &IID_IUnknown) || IsEqualIID(iid, &IID_ITextStoreACP))
     {
-        *ppvOut = This;
+        *ppvOut = iface;
     }
 
     if (*ppvOut)
     {
-        IUnknown_AddRef(iface);
+        ITextStoreACP_AddRef(iface);
         return S_OK;
     }
 
@@ -230,19 +227,28 @@ static ULONG WINAPI TextStoreACP_Release(ITextStoreACP *iface)
 static HRESULT WINAPI TextStoreACP_AdviseSink(ITextStoreACP *iface,
     REFIID riid, IUnknown *punk, DWORD dwMask)
 {
+    ITextStoreACPServices *services;
     HRESULT hr;
 
     sink_fire_ok(&test_ACP_AdviseSink,"TextStoreACP_AdviseSink");
 
-    hr = IUnknown_QueryInterface(punk, &IID_ITextStoreACPSink,(LPVOID*)(&ACPSink));
+    if(ACPSink)
+        return S_OK;
+
+    hr = IUnknown_QueryInterface(punk, &IID_ITextStoreACPSink, (void**)&ACPSink);
     ok(SUCCEEDED(hr),"Unable to QueryInterface on sink\n");
+
+    hr = ITextStoreACPSink_QueryInterface(ACPSink, &IID_ITextStoreACPServices, (void**)&services);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+    ITextStoreACPServices_Release(services);
+
     return S_OK;
 }
 
 static HRESULT WINAPI TextStoreACP_UnadviseSink(ITextStoreACP *iface,
     IUnknown *punk)
 {
-    trace("\n");
+    sink_fire_ok(&test_ACP_UnadviseSink,"TextStoreACP_UnadviseSink");
     return S_OK;
 }
 
@@ -457,7 +463,7 @@ static HRESULT TextStoreACP_Constructor(IUnknown **ppOut)
     This->ITextStoreACP_iface.lpVtbl = &TextStoreACP_TextStoreACPVtbl;
     This->refCount = 1;
 
-    *ppOut = (IUnknown *)This;
+    *ppOut = (IUnknown*)&This->ITextStoreACP_iface;
     return S_OK;
 }
 
@@ -482,17 +488,16 @@ static void ThreadMgrEventSink_Destructor(ThreadMgrEventSink *This)
 
 static HRESULT WINAPI ThreadMgrEventSink_QueryInterface(ITfThreadMgrEventSink *iface, REFIID iid, LPVOID *ppvOut)
 {
-    ThreadMgrEventSink *This = impl_from_ITfThreadMgrEventSink(iface);
     *ppvOut = NULL;
 
     if (IsEqualIID(iid, &IID_IUnknown) || IsEqualIID(iid, &IID_ITfThreadMgrEventSink))
     {
-        *ppvOut = This;
+        *ppvOut = iface;
     }
 
     if (*ppvOut)
     {
-        IUnknown_AddRef(iface);
+        ITfThreadMgrEventSink_AddRef(iface);
         return S_OK;
     }
 
@@ -560,9 +565,9 @@ ITfContext *pic)
     hr = ITfContext_GetDocumentMgr(pic,&docmgr);
     ok(SUCCEEDED(hr),"GetDocumentMgr failed\n");
     test = (ITfContext*)0xdeadbeef;
-    ITfDocumentMgr_Release(docmgr);
     hr = ITfDocumentMgr_GetTop(docmgr,&test);
     ok(SUCCEEDED(hr),"GetTop failed\n");
+    ITfDocumentMgr_Release(docmgr);
     ok(test == pic, "Wrong context is on top\n");
     if (test)
         ITfContext_Release(test);
@@ -616,10 +621,46 @@ static HRESULT ThreadMgrEventSink_Constructor(IUnknown **ppOut)
     This->ITfThreadMgrEventSink_iface.lpVtbl = &ThreadMgrEventSink_ThreadMgrEventSinkVtbl;
     This->refCount = 1;
 
-    *ppOut = (IUnknown *)This;
+    *ppOut = (IUnknown*)&This->ITfThreadMgrEventSink_iface;
     return S_OK;
 }
 
+static HRESULT WINAPI TfTransitoryExtensionSink_QueryInterface(ITfTransitoryExtensionSink *iface, REFIID riid, void **ppv)
+{
+    if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_ITfTransitoryExtensionSink, riid)) {
+        *ppv = iface;
+        return S_OK;
+    }
+
+    *ppv = NULL;
+    return E_NOINTERFACE;
+}
+
+static ULONG WINAPI TfTransitoryExtensionSink_AddRef(ITfTransitoryExtensionSink *iface)
+{
+    return 2;
+}
+
+static ULONG WINAPI TfTransitoryExtensionSink_Release(ITfTransitoryExtensionSink *iface)
+{
+    return 1;
+}
+
+static HRESULT WINAPI TfTransitoryExtensionSink_OnTransitoryExtensionUpdated(ITfTransitoryExtensionSink *iface, ITfContext *pic,
+        TfEditCookie ecReadOnly, ITfRange *pResultRange, ITfRange *pCompositionRange, BOOL *pfDeleteResultRange)
+{
+    ok(0, "unexpected call\n");
+    return E_NOTIMPL;
+}
+
+static const ITfTransitoryExtensionSinkVtbl TfTransitoryExtensionSinkVtbl = {
+    TfTransitoryExtensionSink_QueryInterface,
+    TfTransitoryExtensionSink_AddRef,
+    TfTransitoryExtensionSink_Release,
+    TfTransitoryExtensionSink_OnTransitoryExtensionUpdated
+};
+
+static ITfTransitoryExtensionSink TfTransitoryExtensionSink = { &TfTransitoryExtensionSinkVtbl };
 
 /********************************************************************************************
  * Stub text service for testing
@@ -730,7 +771,7 @@ static HRESULT ClassFactory_Constructor(LPFNCONSTRUCTOR ctor, LPVOID *ppvOut)
     This->IClassFactory_iface.lpVtbl = &ClassFactoryVtbl;
     This->ref = 1;
     This->ctor = ctor;
-    *ppvOut = (LPVOID)This;
+    *ppvOut = &This->IClassFactory_iface;
     TS_refCount++;
     return S_OK;
 }
@@ -742,17 +783,16 @@ static void TextService_Destructor(TextService *This)
 
 static HRESULT WINAPI TextService_QueryInterface(ITfTextInputProcessor *iface, REFIID iid, LPVOID *ppvOut)
 {
-    TextService *This = impl_from_ITfTextInputProcessor(iface);
     *ppvOut = NULL;
 
     if (IsEqualIID(iid, &IID_IUnknown) || IsEqualIID(iid, &IID_ITfTextInputProcessor))
     {
-        *ppvOut = This;
+        *ppvOut = iface;
     }
 
     if (*ppvOut)
     {
-        IUnknown_AddRef(iface);
+        ITfTextInputProcessor_AddRef(iface);
         return S_OK;
     }
 
@@ -815,7 +855,7 @@ static HRESULT TextService_Constructor(IUnknown *pUnkOuter, IUnknown **ppOut)
     This->ITfTextInputProcessor_iface.lpVtbl = &TextService_TextInputProcessorVtbl;
     This->refCount = 1;
 
-    *ppOut = (IUnknown *)This;
+    *ppOut = (IUnknown*)&This->ITfTextInputProcessor_iface;
     return S_OK;
 }
 
@@ -921,6 +961,7 @@ static void test_EnumInputProcessorInfo(void)
             if(IsEqualGUID(&g,&CLSID_FakeService))
                 found = TRUE;
         }
+        IEnumGUID_Release(ppEnum);
     }
     ok(found,"Did not find registered text service\n");
 }
@@ -929,6 +970,11 @@ static void test_EnumLanguageProfiles(void)
 {
     BOOL found = FALSE;
     IEnumTfLanguageProfiles *ppEnum;
+    HRESULT hr;
+
+    hr = ITfInputProcessorProfiles_EnumLanguageProfiles(g_ipp, gLangid, NULL);
+    ok(hr == E_INVALIDARG, "EnumLanguageProfiles failed: %x\n", hr);
+
     if (SUCCEEDED(ITfInputProcessorProfiles_EnumLanguageProfiles(g_ipp,gLangid,&ppEnum)))
     {
         TF_LANGUAGEPROFILE profile;
@@ -938,10 +984,12 @@ static void test_EnumLanguageProfiles(void)
             {
                 found = TRUE;
                 ok(profile.langid == gLangid, "LangId Incorrect\n");
-                ok(IsEqualGUID(&profile.catid,&GUID_TFCAT_TIP_KEYBOARD), "CatId Incorrect\n");
+                ok(IsEqualGUID(&profile.catid,&GUID_TFCAT_TIP_KEYBOARD) ||
+                   broken(IsEqualGUID(&profile.catid,&GUID_NULL) /* Win8 */), "CatId Incorrect\n");
                 ok(IsEqualGUID(&profile.guidProfile,&CLSID_FakeService), "guidProfile Incorrect\n");
             }
         }
+        IEnumTfLanguageProfiles_Release(ppEnum);
     }
     ok(found,"Registered text service not found\n");
 }
@@ -1048,6 +1096,34 @@ static void test_ThreadMgrUnadviseSinks(void)
     ITfSource_Release(source);
 }
 
+static void test_DocumentMgrAdviseSinks(void)
+{
+    ITfSource *source;
+    HRESULT hr;
+
+    hr = ITfDocumentMgr_QueryInterface(g_dm, &IID_ITfSource, (void**)&source);
+    ok(hr == S_OK,"Failed to get IID_ITfSource for DocumentMgr\n");
+
+    dmSinkCookie = 0;
+    hr = ITfSource_AdviseSink(source, &IID_ITfTransitoryExtensionSink, (IUnknown*)&TfTransitoryExtensionSink, &dmSinkCookie);
+    ok(hr == S_OK,"Failed to Advise Sink\n");
+
+    ITfSource_Release(source);
+}
+
+static void test_DocumentMgrUnadviseSinks(void)
+{
+    ITfSource *source = NULL;
+    HRESULT hr;
+
+    hr = ITfDocumentMgr_QueryInterface(g_dm, &IID_ITfSource, (void**)&source);
+    ok(hr == S_OK,"Failed to get IID_ITfSource for DocumentMgr\n");
+
+    hr = ITfSource_UnadviseSink(source, dmSinkCookie);
+    ok(hr == S_OK,"Failed to unadvise Sink\n");
+    ITfSource_Release(source);
+}
+
 /**********************************************************************
  * ITfKeyEventSink
  **********************************************************************/
@@ -1069,17 +1145,16 @@ static void KeyEventSink_Destructor(KeyEventSink *This)
 
 static HRESULT WINAPI KeyEventSink_QueryInterface(ITfKeyEventSink *iface, REFIID iid, LPVOID *ppvOut)
 {
-    KeyEventSink *This = impl_from_ITfKeyEventSink(iface);
     *ppvOut = NULL;
 
     if (IsEqualIID(iid, &IID_IUnknown) || IsEqualIID(iid, &IID_ITfKeyEventSink))
     {
-        *ppvOut = This;
+        *ppvOut = iface;
     }
 
     if (*ppvOut)
     {
-        IUnknown_AddRef(iface);
+        ITfKeyEventSink_AddRef(iface);
         return S_OK;
     }
 
@@ -1201,13 +1276,13 @@ static void test_KeystrokeMgr(void)
     ok(hr == E_INVALIDARG,"Wrong return, expected E_INVALIDARG\n");
 
     hr =ITfKeystrokeMgr_PreserveKey(keymgr, 0, &CLSID_PreservedKey, &tfpk, NULL, 0);
-    ok(hr==E_INVALIDARG,"ITfKeystrokeMgr_PreserveKey inproperly succeeded\n");
+    ok(hr==E_INVALIDARG,"ITfKeystrokeMgr_PreserveKey improperly succeeded\n");
 
     hr =ITfKeystrokeMgr_PreserveKey(keymgr, tid, &CLSID_PreservedKey, &tfpk, NULL, 0);
     ok(SUCCEEDED(hr),"ITfKeystrokeMgr_PreserveKey failed\n");
 
     hr =ITfKeystrokeMgr_PreserveKey(keymgr, tid, &CLSID_PreservedKey, &tfpk, NULL, 0);
-    ok(hr == TF_E_ALREADY_EXISTS,"ITfKeystrokeMgr_PreserveKey inproperly succeeded\n");
+    ok(hr == TF_E_ALREADY_EXISTS,"ITfKeystrokeMgr_PreserveKey improperly succeeded\n");
 
     preserved = FALSE;
     hr = ITfKeystrokeMgr_IsPreservedKey(keymgr, &CLSID_PreservedKey, &tfpk, &preserved);
@@ -1222,7 +1297,7 @@ static void test_KeystrokeMgr(void)
     if (hr == S_FALSE) ok(preserved == FALSE,"misreporting preserved key\n");
 
     hr = ITfKeystrokeMgr_UnpreserveKey(keymgr, &CLSID_PreservedKey,&tfpk);
-    ok(hr==CONNECT_E_NOCONNECTION,"ITfKeystrokeMgr_UnpreserveKey inproperly succeeded\n");
+    ok(hr==CONNECT_E_NOCONNECTION,"ITfKeystrokeMgr_UnpreserveKey improperly succeeded\n");
 
     hr = ITfKeystrokeMgr_UnadviseKeyEventSink(keymgr,tid);
     ok(SUCCEEDED(hr),"ITfKeystrokeMgr_UnadviseKeyEventSink failed\n");
@@ -1305,8 +1380,8 @@ static void test_EnumDocumentMgr(ITfThreadMgr *tm, ITfDocumentMgr *search, ITfDo
 
 static inline int check_context_refcount(ITfContext *iface)
 {
-    IUnknown_AddRef(iface);
-    return IUnknown_Release(iface);
+    ITfContext_AddRef(iface);
+    return ITfContext_Release(iface);
 }
 
 
@@ -1331,17 +1406,16 @@ static void TextEditSink_Destructor(TextEditSink *This)
 
 static HRESULT WINAPI TextEditSink_QueryInterface(ITfTextEditSink *iface, REFIID iid, LPVOID *ppvOut)
 {
-    TextEditSink *This = impl_from_ITfTextEditSink(iface);
     *ppvOut = NULL;
 
     if (IsEqualIID(iid, &IID_IUnknown) || IsEqualIID(iid, &IID_ITfTextEditSink))
     {
-        *ppvOut = This;
+        *ppvOut = iface;
     }
 
     if (*ppvOut)
     {
-        IUnknown_AddRef(iface);
+        ITfTextEditSink_AddRef(iface);
         return S_OK;
     }
 
@@ -1404,8 +1478,9 @@ static void test_startSession(void)
     DWORD editCookie;
     ITfDocumentMgr *dmtest;
     ITfContext *cxt,*cxt2,*cxt3,*cxtTest;
-    ITextStoreACP *ts;
+    ITextStoreACP *ts = NULL;
     TfClientId cid2 = 0;
+    ITfThreadMgrEx *tmex;
 
     hr = ITfThreadMgr_Deactivate(g_tm);
     ok(hr == E_UNEXPECTED,"Deactivate should have failed with E_UNEXPECTED\n");
@@ -1418,10 +1493,24 @@ static void test_startSession(void)
     test_ShouldActivate = FALSE;
     hr = ITfThreadMgr_Activate(g_tm,&cid2);
     ok(SUCCEEDED(hr),"Failed to Activate\n");
-    ok (cid == cid2, "Second activate client ID does not match\n");
+    ok(cid == cid2, "Second activate client ID does not match\n");
+
+    hr = ITfThreadMgr_QueryInterface(g_tm, &IID_ITfThreadMgrEx, (void **)&tmex);
+    if (hr == S_OK)
+    {
+        hr = ITfThreadMgrEx_ActivateEx(tmex, &cid2, 0);
+        ok(SUCCEEDED(hr), "Failed to Activate\n");
+        ok(cid == cid2, "ActivateEx client ID does not match\n");
+
+        ITfThreadMgrEx_Release(tmex);
+    }
+    else
+        win_skip("ITfThreadMgrEx is not supported\n");
 
     hr = ITfThreadMgr_Deactivate(g_tm);
-    ok(SUCCEEDED(hr),"Failed to Deactivate\n");
+    ok(SUCCEEDED(hr), "Failed to Deactivate\n");
+    hr = ITfThreadMgr_Deactivate(g_tm);
+    ok(SUCCEEDED(hr), "Failed to Deactivate\n");
 
     test_EnumDocumentMgr(g_tm,NULL,NULL);
 
@@ -1556,6 +1645,8 @@ static void test_startSession(void)
     ok(hr == S_FALSE, "ITfContext_GetDocumentMgr wrong rc %x\n",hr);
     ok(dmtest == NULL,"returned documentmgr should be null\n");
 
+    ITfContext_Release(cxt2);
+
     hr = ITfDocumentMgr_GetTop(g_dm, &cxtTest);
     ok(SUCCEEDED(hr),"GetTop Failed\n");
     ok(cxtTest == cxt, "Wrong context on top\n");
@@ -1566,6 +1657,25 @@ static void test_startSession(void)
     ok(cxtTest == cxt, "Wrong context on base\n");
     ITfContext_Release(cxtTest);
 
+    hr = ITfDocumentMgr_CreateContext(g_dm, cid, 0, (IUnknown*)ts, &cxt2, &editCookie);
+    ok(hr == S_OK,"CreateContext Failed\n");
+
+    test_OnPushContext = SINK_EXPECTED;
+    test_ACP_AdviseSink = SINK_EXPECTED;
+    hr = ITfDocumentMgr_Push(g_dm, cxt2);
+    ok(hr == S_OK,"Push Failed\n");
+    sink_check_ok(&test_OnPushContext,"OnPushContext");
+    sink_check_ok(&test_ACP_AdviseSink,"TextStoreACP_AdviseSink");
+
+    test_ACP_UnadviseSink = SINK_EXPECTED;
+    cnt = check_context_refcount(cxt2);
+    test_OnPopContext = SINK_EXPECTED;
+    hr = ITfDocumentMgr_Pop(g_dm, 0);
+    ok(hr == S_OK,"Pop Failed\n");
+    ok(check_context_refcount(cxt2) < cnt, "Ref count did not decrease\n");
+    sink_check_ok(&test_OnPopContext,"OnPopContext");
+    sink_check_ok(&test_ACP_UnadviseSink,"TextStoreACP_AdviseSink");
+
     hr = ITfDocumentMgr_Pop(g_dm, 0);
     ok(FAILED(hr),"Pop Succeeded\n");
 
@@ -1687,17 +1797,16 @@ static void EditSession_Destructor(EditSession *This)
 
 static HRESULT WINAPI EditSession_QueryInterface(ITfEditSession *iface, REFIID iid, LPVOID *ppvOut)
 {
-    EditSession *This = impl_from_ITfEditSession(iface);
     *ppvOut = NULL;
 
     if (IsEqualIID(iid, &IID_IUnknown) || IsEqualIID(iid, &IID_ITfEditSession))
     {
-        *ppvOut = This;
+        *ppvOut = iface;
     }
 
     if (*ppvOut)
     {
-        IUnknown_AddRef(iface);
+        ITfEditSession_AddRef(iface);
         return S_OK;
     }
 
@@ -1901,10 +2010,9 @@ static void test_TStoApplicationText(void)
     {
         hr = ITfSource_UnadviseSink(source, editSinkCookie);
         ok(SUCCEEDED(hr),"Failed to unadvise Sink\n");
-        ITfTextEditSink_Release(sink);
         ITfSource_Release(source);
     }
-
+    ITfTextEditSink_Release(sink);
     ITfContext_Release(cxt);
     ITfDocumentMgr_Release(dm);
     ITfEditSession_Release(es);
@@ -2001,10 +2109,10 @@ static void processPendingMessages(void)
     {
         if (MsgWaitForMultipleObjects(0, NULL, FALSE, min_timeout, QS_ALLINPUT) == WAIT_TIMEOUT)
             break;
-        while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
+        while (PeekMessageW(&msg, 0, 0, 0, PM_REMOVE))
         {
             TranslateMessage(&msg);
-            DispatchMessage(&msg);
+            DispatchMessageW(&msg);
         }
         diff = time - GetTickCount();
     }
@@ -2033,11 +2141,11 @@ static void test_AssociateFocus(void)
     hr = ITfThreadMgr_CreateDocumentMgr(g_tm,&dm2);
     ok(SUCCEEDED(hr),"CreateDocumentMgr failed\n");
 
-    wnd1 = CreateWindow("edit",NULL,WS_POPUP,0,0,200,60,NULL,NULL,NULL,NULL);
+    wnd1 = CreateWindowA("edit",NULL,WS_POPUP,0,0,200,60,NULL,NULL,NULL,NULL);
     ok(wnd1!=NULL,"Unable to create window 1\n");
-    wnd2 = CreateWindow("edit",NULL,WS_POPUP,0,65,200,60,NULL,NULL,NULL,NULL);
+    wnd2 = CreateWindowA("edit",NULL,WS_POPUP,0,65,200,60,NULL,NULL,NULL,NULL);
     ok(wnd2!=NULL,"Unable to create window 2\n");
-    wnd3 = CreateWindow("edit",NULL,WS_POPUP,0,130,200,60,NULL,NULL,NULL,NULL);
+    wnd3 = CreateWindowA("edit",NULL,WS_POPUP,0,130,200,60,NULL,NULL,NULL,NULL);
     ok(wnd3!=NULL,"Unable to create window 3\n");
 
     processPendingMessages();
@@ -2076,20 +2184,15 @@ static void test_AssociateFocus(void)
     processPendingMessages();
 
     ITfThreadMgr_GetFocus(g_tm, &dmcheck);
-    if (dmcheck != NULL)
-    {
-        ok(dmcheck == dm1, "Expected DocumentMgr not focused\n");
-        ITfDocumentMgr_Release(dmcheck);
-    }
-    else
-    {
-        /* Sometimes we need to explicitly set focus on Win7 */
-        test_CurrentFocus = dm1;
-        test_PrevFocus = FOCUS_IGNORE;
-        test_OnSetFocus = SINK_EXPECTED;
-        ITfThreadMgr_SetFocus(g_tm, dm1);
-        sink_check_ok(&test_OnSetFocus,"OnSetFocus");
-    }
+    ok(dmcheck == dm1 || broken(dmcheck == dmorig /* Win7+ */), "Expected DocumentMgr not focused\n");
+    ITfDocumentMgr_Release(dmcheck);
+
+    /* We need to explicitly set focus on Win7+ */
+    test_CurrentFocus = dm1;
+    test_PrevFocus = FOCUS_IGNORE;
+    test_OnSetFocus = SINK_OPTIONAL; /* Doesn't always fire on Win7+ */
+    ITfThreadMgr_SetFocus(g_tm, dm1);
+    sink_check_ok(&test_OnSetFocus, "OnSetFocus");
 
     hr = ITfThreadMgr_AssociateFocus(g_tm,wnd2,dm2,&olddm);
     ok(SUCCEEDED(hr),"AssociateFocus failed\n");
@@ -2134,7 +2237,7 @@ static void test_AssociateFocus(void)
 
     test_CurrentFocus = dmorig;
     test_PrevFocus = dm1;
-    test_OnSetFocus  = SINK_EXPECTED;
+    test_OnSetFocus  = SINK_OPTIONAL; /* Doesn't always fire on Win7+ */
     test_ACP_GetStatus = SINK_IGNORE;
     ITfThreadMgr_SetFocus(g_tm,dmorig);
     sink_check_ok(&test_OnSetFocus,"OnSetFocus");
@@ -2179,7 +2282,6 @@ static void test_AssociateFocus(void)
     test_PrevFocus = FOCUS_IGNORE;
     DestroyWindow(wnd1);
     DestroyWindow(wnd2);
-    test_OnSetFocus = SINK_UNEXPECTED;
     test_OnPopContext = SINK_OPTIONAL; /* Vista and greater */
     test_OnSetFocus = SINK_OPTIONAL; /* Vista and greater */
     ITfThreadMgr_GetFocus(g_tm, &test_PrevFocus);
@@ -2191,6 +2293,28 @@ static void test_AssociateFocus(void)
     sink_check_ok(&test_OnPopContext,"OnPopContext");
 }
 
+static void test_profile_mgr(void)
+{
+    IEnumTfInputProcessorProfiles *enum_profiles;
+    ITfInputProcessorProfileMgr *ipp_mgr;
+    HRESULT hres;
+
+    hres = ITfInputProcessorProfiles_QueryInterface(g_ipp, &IID_ITfInputProcessorProfileMgr, (void**)&ipp_mgr);
+    if (hres != S_OK)
+    {
+        win_skip("ITfInputProcessorProfileMgr is not supported.\n");
+        return;
+    }
+    ok(hres == S_OK, "Could not get ITfInputProcessorProfileMgr iface: %08x\n", hres);
+
+    hres = ITfInputProcessorProfileMgr_EnumProfiles(ipp_mgr, 0, &enum_profiles);
+    ok(hres == S_OK, "EnumProfiles failed: %08x\n", hres);
+
+    IEnumTfInputProcessorProfiles_Release(enum_profiles);
+
+    ITfInputProcessorProfileMgr_Release(ipp_mgr);
+}
+
 START_TEST(inputprocessor)
 {
     if (SUCCEEDED(initialize()))
@@ -2205,6 +2329,7 @@ START_TEST(inputprocessor)
         test_ThreadMgrAdviseSinks();
         test_Activate();
         test_startSession();
+        test_DocumentMgrAdviseSinks();
         test_TfGuidAtom();
         test_ClientId();
         test_KeystrokeMgr();
@@ -2215,8 +2340,13 @@ START_TEST(inputprocessor)
         test_FindClosestCategory();
         test_Disable();
         test_ThreadMgrUnadviseSinks();
+        test_DocumentMgrUnadviseSinks();
         test_UnregisterCategory();
         test_Unregister();
+        test_profile_mgr();
+
+        ITextStoreACPSink_Release(ACPSink);
+        ITfDocumentMgr_Release(g_dm);
     }
     else
         skip("Unable to create InputProcessor\n");