让您的浏览器开口说话






4.33/5 (3投票s)
使用语音 SDK 让 Internet Explorer 读取文档或文档的部分内容给用户。

要求
- Microsoft Speech SDK 5.1
http://msdn2.microsoft.com/en-us/library/bb250489.aspx (使用 VS2005 构建 BHO) 和
http://msdn2.microsoft.com/en-us/library/bb735853(VS.85).aspx#IEAddOnsMenus_topic2 (为 IE 创建菜单) 是我创建此插件时使用的两个网站。 我将跳过如何创建浏览器助手对象并将其添加到 Internet Explorer 工具菜单的过程,直接进入有趣的部分。 speakThread
中实际进行语音朗读的大部分代码都来自 MSDN 文档中关于 Speech
API 的说明。
语音线程
#include <sapi.h >//we need this
...
DWORD WINAPI speakThread(LPVOID bstr)
{
if (FAILED(::CoInitialize(NULL)))
return -1;
ISpVoice * pVoice = NULL;
HRESULT hr = CoCreateInstance(CLSID_SpVoice, NULL, CLSCTX_ALL, IID_ISpVoice,
(void **)&pVoice);
if( SUCCEEDED( hr ) )
{
hr = pVoice->Speak((BSTR)bstr,0,NULL);
pVoice->WaitUntilDone(INFINITE);
pVoice->Release();
pVoice = NULL;
::CoUninitialize();
return hr;
}
::CoUninitialize();
return hr;
}
这里发生的事情是,我们将一个 BSTR
作为 LPVOID
传递给线程。 我们初始化 COM 并创建一个类型为 ISpVoice
的接口。 我们调用此接口的 Speak
例程,并为其提供接收到的 string
。 接下来,我们等待该例程完成,然后进行清理。
STDMETHODIMP CCIESpeechBHO::Exec(const GUID *pguidCmdGroup,
DWORD nCmdID, DWORD nCmdExecOpt,
VARIANTARG *pvaIn, VARIANTARG *pvaOut) {
CComPtr spDoc;
HRESULT hr = m_pBrowser->get_Document(&spDoc);
if(SUCCEEDED(hr))
{
CComQIPtr spHTMLDoc = spDoc;
if(NULL != spHTMLDoc)
{
IHTMLElement* pHtmlElement = NULL;
IHTMLSelectionObject* pHtmlSelectionObject;
spHTMLDoc->get_selection(&pHtmlSelectionObject);
BSTR bstr;
pHtmlSelectionObject->get_type(&bstr);
if (_tcscmp(_tcsupr(bstr),L"TEXT")!=0)
{
spHTMLDoc->get_body(&pHtmlElement);
pHtmlElement->get_innerText(&bstr);
}
else
{
IHTMLTxtRange* pHtmlTxtRange;
pHtmlSelectionObject->createRange((IDispatch**)&pHtmlTxtRange);
pHtmlTxtRange->get_text(&bstr);
}
DWORD dwThreadID=0;
CreateThread(NULL,0,speakThread,(LPVOID)bstr,0,&dwThreadID);
}
}
return hr;
}
在 Exec
函数中,浏览器在选择菜单项时会调用该函数,执行几项操作。 首先,我们要求浏览器提供 HTML 的副本。 接下来,我们创建一个 IHTMLSelectionObject
接口,并检查是否选择了任何文本。 如果选择了文本,则我们创建一个范围并获取文本;否则,我们获取正文并从 HTML 的内部正文中获取文本。 最后,我们创建一个线程,并将从我们的选择或 HTML 正文接收到的文本传递给它。
注释
- 必须创建一个线程,否则 Internet Explorer 将会锁定,直到文本朗读完成。
- 如果页面上有隐藏文本,它将读取所有隐藏文本,例如 MSDN 网站上的链接。
- 此方法允许您查看其他页面,而无需等待文本朗读完成,但是 API 中没有实现停止机制,因此用户必须等待文本朗读完成,然后才能进行新的选择并朗读。
我希望看到的功能
- Adobe Acrobat 版本
- Microsoft Word 版本
- 添加了跳过和重放段落的方法
历史
- 2008 年 4 月 21 日:初始发布