Microsoft TSF - Использование ITfThreadMgr::GetFocus подобно IUIAutomation::GetFocusedElement
Когда я пытаюсь подключиться к Microsoft Text Services Framework (TSF) вне контекста текстовой службы, я не могу получить информацию, необходимую для взаимодействия с текстом активного приложения.
#include <SDKDDKVer.h>
#include <stdio.h>
#include <tchar.h>
#include <msctf.h>
#include <atlbase.h>
#include <iostream>
// Macro throws a descriptive WCHAR* exception if(FAILED(hr))
#define OK(hrExpr) do{std::cout<<"IN: "<<#hrExpr<<std::endl; HRESULT returnCode = hrExpr; if( FAILED(returnCode) ){std::cout<<std::endl<<"ERROR! "<<#hrExpr<<" @"<<__FILE__<<":"<<__LINE__<<" returned "<<returnCode<<std::endl; throw L#hrExpr; }else{std::cout << "OK: " << #hrExpr << std::endl;}}while(0)
int _tmain(int argc, _TCHAR* argv[])
{
::CoInitialize(0);
ITfThreadMgr* pThreadMgr = NULL;
TfClientId clientId = NULL;
ITfDocumentMgr* docMgr = NULL;
ITfContext* pContext = NULL;
try
{
std::cout << "Use the next 5 seconds to switch to a TSF-enabled application and make a text selection." << std::endl;
Sleep(5000);
OK( CoCreateInstance( CLSID_TF_ThreadMgr,
NULL,
CLSCTX_INPROC_SERVER,
IID_ITfThreadMgr,
(void**)&pThreadMgr) );
OK( pThreadMgr->Activate(&clientId) );
OK( pThreadMgr->GetFocus(&docMgr) );
if (docMgr == NULL)
{
throw L"NULL document manager";
}
OK( docMgr->GetTop(&pContext) );
// TODO: use ITfContext to get selection or make document edits
}
catch(LPCSTR msg)
{
std::wcout << L"Exception: " << msg << std::endl;
}
catch(LPCWSTR msg)
{
std::wcout << L"Exception: " << msg << std::endl;
}
if (pContext)
pContext->Release();
if (docMgr)
docMgr->Release();
::CoUninitialize();
return 0;
}
Я использую WordPad в Windows 7 в качестве целевого тестового приложения, и я стараюсь сосредоточиться на WordPad к тому времени, когда выполняются методы TSF.
Программа доходит до попытки получить в данный момент сфокусированный ITfDocumentMgr ( ITfThreadMgr:: GetFocus), но возвращенный менеджер документов имеет значение NULL. Согласно документации API это означает, что в настоящее время нет сфокусированного ITfDocumentMgr, однако:
Если я использую совершенно другой подход: зарегистрируйте пользовательский текстовый сервис и получите ссылку ITfThreadMgr через ITfTextInputProcessor:: Activate, я смогу получить целевой ITfDocumentMgr для WordPad через ITfThreadMgr::GetFocus. Однако по разным причинам я бы предпочел не устанавливать пользовательский текстовый сервис inproc.
Есть ли способ подключиться к TSF API через границы процесса, как это возможно с AutomationElement.FocusedElement
, IUIAutomation::GetFocusedElement
или же AccessibleObjectFromWindow
?
1 ответ
Text Services Framework не работает кросс-процесс. Там нет ни прокси, ни заглушки доступны. Сожалею.
Между прочим, ваш код пытается получить целенаправленный менеджер документов для вашего процесса. Вы создаете ITfThreadMgr
с помощью CLSCTX_INPROC_SERVER
, который запускает менеджер потоков в вашем процессе, а не в цели.