好的,我已经有一段时间了......
我正在尝试跟踪用户何时从语言栏更改输入语言。
我有一个文本服务DLL - 模仿MSDN和WinSDK样本 - 注册很好,我可以使用接口ITfActiveLanguageProfileNotifySink& ITfLanguageProfileNotifySink并看到那些事件就好了。
我也终于意识到,当我更改语言时,这些事件会发生在当前具有焦点的应用程序/进程中。
我需要做的是让这些事件能够回调到我自己的应用程序,当它有焦点时。我知道我错过了什么。
感谢您的任何帮助。
感谢。
答案 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接口处于活动状态。)