当我尝试附加到文本服务上下文之外Microsoft文本服务框架 (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;
}
我在 Windows 7 上使用写字板作为我的目标测试应用程序,并确保在执行 TSF 方法时专注于写字板。
该程序尝试获取当前聚焦的 ITfDocumentMgr (ITfThreadMgr::GetFocus(,但返回的文档管理器为 NULL。 根据API文档,这意味着目前没有专注于ITfDocumentMgr,但是:
如果我采用完全不同的方法:注册自定义文本服务并通过 ITfTextInputProcessor::Activate 接收 ITfThreadMgr 引用,我能够通过 ITfThreadMgr::GetFocus 检索写字板的焦点 ITfDocumentMgr。 但是,由于各种原因,我宁愿不安装自定义的inproc文本服务。
有没有办法跨进程边界挂接到TSF API,就像AutomationElement.FocusedElement
、IUIAutomation::GetFocusedElement
或AccessibleObjectFromWindow
一样?
文本服务框架无法跨进程工作。 既没有可用的代理,也没有可用的存根。 不好意思。
顺便说一下,您的代码正在尝试为您的流程获取重点文档管理器。 您可以使用 CLSCTX_INPROC_SERVER
创建ITfThreadMgr
,这会在进程中启动线程管理器,而不是在目标中启动线程管理器。