Application not detecting input language changes via Text Service Framework DLL

1.2k views Asked by At

OK, I have been at this for a while ...

I am trying to track when user changes input languages from Language Bar.

I have a Text Service DLL - modeled from MSDN and WinSDK samples - that registers fine, and I can use the interfaces ITfActiveLanguageProfileNotifySink & ITfLanguageProfileNotifySink and see those events just fine.

I also have finally realized that when I change languages these events occur for the application/process that currently has focus.

What I need to do is to simply have these events able to callback to my own application, when it has the focus. I know I am missing something.

Any help here is appreciated.

Thanks.

1

There are 1 answers

3
Eric Brown On

I did some double-checking, and you should be able to create a thread manager object without implementing ITextStoreACP so long as you don't call ITfThreadMgr::Activate.

So, the code should look like:

HRESULT hr = CoInitialize(NULL);
if (SUCCEEDED(hr))
{
    ITfThreadMgr* pThreadMgr(NULL);
    hr = CoCreateInstance(CLSID_TF_ThreadMgr, NULL, CLSCTX_INPROC_SERVER, IID_ITfThreadMgr, (LPVOID*) &pThreadMgr);
    if (SUCCEEDED(hr))
    {
        ITfSource *pSource;
        hr = pThreadMgr->QueryInterface(IID_ITfSource, (LPVOID*)&pSource);
        if(SUCCEEDED(hr))
        {
            hr = pSource->AdviseSink(IID_ITfActiveLanguageProfileNotifySink, 
                (ITfActiveLanguageProfileNotifySink*)this,
                &m_dwCookie);

            pSource->Release();
        }
    }
}

Alternatively, you can use ITfLanguageProfileNotifySink - this interface is driven from the ItfInputProcessorProfiles object instead of ItfThreadMgr. There's a sample of how to set it up on the MSDN page for ItfLanguageProfileNotifySink.

For both objects, you need to keep the source object (ITfThreadMgr or ITfInputProcessorProfiles) as well as the sink object (what you implement) alive until your application exits.

Before your application exits, you need to remove the sink from the source object using ITfSource::UnadviseSink, and then release the source object (using Release). (You don't need to keep the ItfSource interface alive for the life of your application, though.)