语音API(SAPI)浮点在C++;Windows7上的生成器 < >我在C++ Builder中使用下面的代码来为盲人提供文本到语音的应用程序控件(最有可能的例子可以在Delphi中使用)。主窗体已选中KeyPreview属性,以启用键F11 preview以开始使用活动(聚焦)控件。代码本身是有效的,但存在一些问题。这个例子是在C++ Builder代码中,但是从我发现的,Delphi遇到了同样的问题,我发现的解决方案是一样的。如果你有德尔福的解决方案,请随意张贴,它是类似的反正 #include <sapi.h> #include <WTypes.h> //--------------------------------------------------------------------------- // Speak text string (synchronous function) //--------------------------------------------------------------------------- bool SpeakText(UnicodeString Text) { ISpVoice* pVoice = NULL; if (FAILED(::CoInitialize(NULL))) return false; Word Saved8087CW = Default8087CW; // Disable floating point division by zero exception caused by Speak Set8087CW(0x133f); HRESULT hr = CoCreateInstance(CLSID_SpVoice, NULL, CLSCTX_ALL, IID_ISpVoice, (void **)&pVoice); if (SUCCEEDED(hr)) { //pVoice->SpeakCompleteEvent() //pVoice->SetSyncSpeakTimeout(1000); hr = pVoice->Speak(WideString(Text).c_bstr(), SPF_DEFAULT, NULL); pVoice->Release(); pVoice = NULL; } Set8087CW(Saved8087CW); ::CoUninitialize(); return true; } //--------------------------------------------------------------------------- void __fastcall TForm1::FormKeyUp(TObject *Sender, WORD &Key, TShiftState Shift) { UnicodeString Speaker; if (Key == VK_F11) { if (Screen->ActiveControl->InheritsFrom(__classid(TButton))) { Speaker += "Button, " + static_cast<TButton*>(Screen->ActiveControl)->Caption + "."; } else if (Screen->ActiveControl->InheritsFrom(__classid(TEdit))) { Speaker += "Edit box, " + static_cast<TEdit*>(Screen->ActiveControl)->Text + "."; } } if (Speaker != "") SpeakText(Speaker); } //---------------------------------------------------------------------------
还可以在CodeRage 4会话中找到详细示例:语音API(SAPI)浮点在C++;Windows7上的生成器 < >我在C++ Builder中使用下面的代码来为盲人提供文本到语音的应用程序控件(最有可能的例子可以在Delphi中使用)。主窗体已选中KeyPreview属性,以启用键F11 preview以开始使用活动(聚焦)控件。代码本身是有效的,但存在一些问题。这个例子是在C++ Builder代码中,但是从我发现的,Delphi遇到了同样的问题,我发现的解决方案是一样的。如果你有德尔福的解决方案,请随意张贴,它是类似的反正 #include <sapi.h> #include <WTypes.h> //--------------------------------------------------------------------------- // Speak text string (synchronous function) //--------------------------------------------------------------------------- bool SpeakText(UnicodeString Text) { ISpVoice* pVoice = NULL; if (FAILED(::CoInitialize(NULL))) return false; Word Saved8087CW = Default8087CW; // Disable floating point division by zero exception caused by Speak Set8087CW(0x133f); HRESULT hr = CoCreateInstance(CLSID_SpVoice, NULL, CLSCTX_ALL, IID_ISpVoice, (void **)&pVoice); if (SUCCEEDED(hr)) { //pVoice->SpeakCompleteEvent() //pVoice->SetSyncSpeakTimeout(1000); hr = pVoice->Speak(WideString(Text).c_bstr(), SPF_DEFAULT, NULL); pVoice->Release(); pVoice = NULL; } Set8087CW(Saved8087CW); ::CoUninitialize(); return true; } //--------------------------------------------------------------------------- void __fastcall TForm1::FormKeyUp(TObject *Sender, WORD &Key, TShiftState Shift) { UnicodeString Speaker; if (Key == VK_F11) { if (Screen->ActiveControl->InheritsFrom(__classid(TButton))) { Speaker += "Button, " + static_cast<TButton*>(Screen->ActiveControl)->Caption + "."; } else if (Screen->ActiveControl->InheritsFrom(__classid(TEdit))) { Speaker += "Edit box, " + static_cast<TEdit*>(Screen->ActiveControl)->Text + "."; } } if (Speaker != "") SpeakText(Speaker); } //---------------------------------------------------------------------------,exception,text-to-speech,c++builder,sapi,Exception,Text To Speech,C++builder,Sapi,还可以在CodeRage 4会话中找到详细示例: 这个错误也发生在Vista中。屏蔽浮点异常是唯一的解决方案 要使Speak()异步运行,需要在调用它时包含SPF\u ASYNC标志。如果需要检测异步通话何时结束,可以使用ISpVoice::WaitUntilDone(),或调用ISpVoice::SpeakCompleteEvent()并将返回的句柄传递给WaitFor…()函数族之一,如WaitForSingleObject()。 其他网站谈论什么样的泄密 而不是,否。olcheck()仅检
Speak()
异步运行,需要在调用它时包含SPF\u ASYNC
标志。如果需要检测异步通话何时结束,可以使用ISpVoice::WaitUntilDone()
,或调用ISpVoice::SpeakCompleteEvent()
并将返回的句柄
传递给WaitFor…()
函数族之一,如WaitForSingleObject()。
olcheck()
仅检查HRESULT
值的值,如果该值为错误值,则引发异常。您仍然必须首先调用返回实际HRESULT
值的COM函数。如果有的话,olcheck()
将取代successed()
struct s8087CW
{
Word Saved8087CW;
s8087CW(Word NewCW)
{
Saved8087CW = Default8087CW;
Set8087CW(NewCW);
// alternatively, the VCL documentation says to use SetExceptionMask() instead of Set8087CW() directly...
}
~s8087CW()
{
Set8087CW(Saved8087CW);
}
};
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent *Owner)
: TForm(Owner)
{
::CoInitialize(NULL);
}
//---------------------------------------------------------------------------
__fastcall TForm1::~TForm1()
{
if (pVoice) pVoice->Release();
::CoUninitialize();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormKeyUp(TObject *Sender, WORD &Key, TShiftState Shift)
{
if (Key == VK_F11)
{
TWinControl *Ctrl = Screen->ActiveControl;
if (Ctrl)
{
TButton *btn;
TEdit *edit;
if ((btn = dynamic_cast<TButton*>(Ctrl)) != NULL)
SpeakText("Button, " + btn->Caption);
else if ((edit = dynamic_cast<TEdit*>(Ctrl)) != NULL)
SpeakText("Edit box, " + edit->Text);
}
}
}
//---------------------------------------------------------------------------
ISpVoice* pVoice = NULL;
bool __fastcall TForm1::SpeakText(const String &Text)
{
s8087CW cw(0x133f);
if (!pVoice)
{
if (FAILED(CoCreateInstance(CLSID_SpVoice, NULL, CLSCTX_ALL, IID_ISpVoice, (void **)&pVoice)))
return false;
}
SPVOICESTATUS stat;
pVoice->GetStatus(&stat, NULL);
while (stat.dwRunningState == SPRS_IS_SPEAKING)
{
ULONG skipped;
pVoice->Skip(L"SENTENCE", 1000, &skipped);
pVoice->GetStatus(&stat, NULL);
}
return SUCCEEDED(pVoice->Speak(WideString(Text).c_bstr(), SPF_ASYNC, NULL));
}
结构s8087CW
{
字保存8087cw;
s8087CW(单词NewCW)
{
Saved8087CW=Default8087CW;
Set8087CW(新CW);
//或者,VCL文档说直接使用SetExceptionMask()而不是Set8087CW()。。。
}
~s8087CW()
{
设置8087CW(保存8087CW);
}
};
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent*Owner)
:t表格(所有者)
{
::协同初始化(空);
}
//---------------------------------------------------------------------------
__快速调用TForm1::~TForm1()
{
如果(pVoice)pVoice->Release();
::coninitialize();
}
//---------------------------------------------------------------------------
void _fastcall TForm1::FormKeyUp(TObject*发送方、字和键、tshift状态移位)
{
如果(键==VK_F11)
{
TWinControl*Ctrl=Screen->ActiveControl;
如果(Ctrl)
{
t按钮*btn;
TEdit*编辑;
如果((btn=dynamic_cast(Ctrl))!=NULL)
SpeakText(“按钮,”+btn->标题);
如果((编辑=动态_转换(Ctrl))!=NULL,则为else
SpeakText(“编辑框,”+编辑->文本);
}
}
}
//---------------------------------------------------------------------------
ISpVoice*pVoice=NULL;
bool\uuu fastcall TForm1::SpeakText(常量字符串和文本)
{
s8087CW(0x133f);
如果(!pVoice)
{
if(失败(CoCreateInstance(CLSID_SpVoice、NULL、CLSCTX_ALL、IID_ISpVoice、(void**)和pVoice)))
返回false;
}
spvoicestat;
pVoice->GetStatus(&stat,NULL);
while(stat.dwRunningState==SPRS\u正在讲话)
{
乌龙跳;
pVoice->Skip(L“句子”、1000和跳过);
pVoice->GetStatus(&stat,NULL);
}
返回成功(pVoice->Speak(宽字符串(Text).c_bstr(),SPF_ASYNC,NULL));
}
这是一个非常优雅的解决方案,做得很好,比我想到的要好得多!我喜欢
8087CW
结构解决方案。小更正-结构名称以数字开头。否则就太完美了!我更改了结构名称。我尝试了上面的代码,但没有听到语音。我得到的hr值为null。我已经打开了一个新的线程帮助:请你帮助我?@程序员你的问题不适用于C++ Builder编译器,以上的解决方案是C++ Cuilder。谢谢评论。你对我贴的问题有什么建议吗?我希望我能让它工作。@programmer我不使用Visual Studio,所以不使用。但它可能与上面的类似。
struct s8087CW
{
Word Saved8087CW;
s8087CW(Word NewCW)
{
Saved8087CW = Default8087CW;
Set8087CW(NewCW);
// alternatively, the VCL documentation says to use SetExceptionMask() instead of Set8087CW() directly...
}
~s8087CW()
{
Set8087CW(Saved8087CW);
}
};
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent *Owner)
: TForm(Owner)
{
::CoInitialize(NULL);
}
//---------------------------------------------------------------------------
__fastcall TForm1::~TForm1()
{
if (pVoice) pVoice->Release();
::CoUninitialize();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormKeyUp(TObject *Sender, WORD &Key, TShiftState Shift)
{
if (Key == VK_F11)
{
TWinControl *Ctrl = Screen->ActiveControl;
if (Ctrl)
{
TButton *btn;
TEdit *edit;
if ((btn = dynamic_cast<TButton*>(Ctrl)) != NULL)
SpeakText("Button, " + btn->Caption);
else if ((edit = dynamic_cast<TEdit*>(Ctrl)) != NULL)
SpeakText("Edit box, " + edit->Text);
}
}
}
//---------------------------------------------------------------------------
ISpVoice* pVoice = NULL;
bool __fastcall TForm1::SpeakText(const String &Text)
{
s8087CW cw(0x133f);
if (!pVoice)
{
if (FAILED(CoCreateInstance(CLSID_SpVoice, NULL, CLSCTX_ALL, IID_ISpVoice, (void **)&pVoice)))
return false;
}
SPVOICESTATUS stat;
pVoice->GetStatus(&stat, NULL);
while (stat.dwRunningState == SPRS_IS_SPEAKING)
{
ULONG skipped;
pVoice->Skip(L"SENTENCE", 1000, &skipped);
pVoice->GetStatus(&stat, NULL);
}
return SUCCEEDED(pVoice->Speak(WideString(Text).c_bstr(), SPF_ASYNC, NULL));
}