应用程序未通过Text Service Framework DLL检测输入语言更改

时间:2013-07-26 04:21:55

标签: callback text-services-framework input-language

好的,我已经有一段时间了......

我正在尝试跟踪用户何时从语言栏更改输入语言。

我有一个文本服务DLL - 模仿MSDN和WinSDK样本 - 注册很好,我可以使用接口ITfActiveLanguageProfileNotifySink& ITfLanguageProfileNotifySink并看到那些事件就好了。

我也终于意识到,当我更改语言时,这些事件会发生在当前具有焦点的应用程序/进程中。

我需要做的是让这些事件能够回调到我自己的应用程序,当它有焦点时。我知道我错过了什么。

感谢您的任何帮助。

感谢。

1 个答案:

答案 0 :(得分:1)

我做了一些双重检查,只要你不调用ITfThreadMgr :: Activate,你应该能够创建一个线程管理器对象而不实现ITextStoreACP

因此,代码应如下所示:

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();
        }
    }
}

或者,您可以使用ITfLanguageProfileNotifySink - 此接口由ItfInputProcessorProfiles对象而不是ItfThreadMgr驱动。有一个如何在MSDN page for ItfLanguageProfileNotifySink上设置它的示例。

对于这两个对象,您需要将源对象(ITfThreadMgr或ITfInputProcessorProfiles)以及接收器对象(您实现的内容)保持活动状态,直到您的应用程序退出。

在应用程序退出之前,您需要使用ITfSource::UnadviseSink从源对象中删除接收器,然后释放源对象(使用Release)。 (但是,您不需要在应用程序的生命周期内保持ItfSource接口处于活动状态。)