Приложение не обнаруживает изменения языка ввода через библиотеку Text Service Framework DLL

Хорошо, я был в этом некоторое время...

Я пытаюсь отслеживать, когда пользователь меняет язык ввода из языковой панели.

У меня есть библиотека Text Service DLL - смоделированная из примеров MSDN и WinSDK - которая отлично регистрируется, и я могу использовать интерфейсы ITfActiveLanguageProfileNotifySink & ITfLanguageProfileNotifySink и видеть эти события просто отлично.

Я также наконец понял, что когда я меняю языки, эти события происходят для приложения / процесса, который в данный момент находится в фокусе.

Что мне нужно сделать, это просто сделать так, чтобы эти события могли обращаться к моему собственному приложению, когда оно имеет фокус. Я знаю, что что-то упустил.

Любая помощь здесь приветствуется.

Благодарю.

1 ответ

Я провел двойную проверку, и вы сможете создать объект диспетчера потоков без реализации ITextStoreACP, если только вы не вызываете ITfThreadMgr::Activate.

Итак, код должен выглядеть так:

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 для ItfLanguageProfileNotifySink.

Для обоих объектов вам нужно поддерживать исходный объект (ITfThreadMgr или ITfInputProcessorProfiles), а также объект приемника (то, что вы реализуете), пока ваше приложение не завершится.

Перед выходом из приложения необходимо удалить приемник из исходного объекта с помощью ITfSource:: UnadviseSink, а затем освободить исходный объект (с помощью Release). (Однако вам не нужно поддерживать интерфейс ItfSource в течение всего срока службы вашего приложения.)

Другие вопросы по тегам