1

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

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

我有一个文本服务 DLL - 从 MSDN 和 WinSDK 示例建模 - 注册良好,我可以使用接口 ITfActiveLanguageProfileNotifySink 和 ITfLanguageProfileNotifySink 并很好地查看这些事件。

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

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

任何帮助在这里表示赞赏。

谢谢。

4

1 回答 1

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 驱动。在ItfLanguageProfileNotifySink的 MSDN 页面上有一个如何设置它的示例。

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

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

于 2013-07-29T20:16:00.147 回答