MFC使用TTS发音,后来在VC知识库发现一篇不错的文章,大家可以上去看一下(
http://www.vckbase.com/document/viewdoc/?id=1051)但是文章写得太简单,而且他实现的方法一定要在创建MFC项目的时候在选上
Automation,而我现在讲一下在我们以有的项目上添加TTS发音功能(创建项目的时候没有选上Automation)。 下面我把实现步骤写下来:
1、 下载Microsoft Speech SDK, version 5.1,要实现中文发音的话要再下载个SimpChinese Speech Package。
2、 安装了Microsoft Speech SDK, version 5.1后在C:\Program Files\Common Files\Microsoft Shared\Speech目录下找到sapi.dll。
3、 将sapi.dll复制到你的项目文件下。
4、 打开 MFC ClassWizard,选择 Automation 页,单击按钮"Add Class…",选择"From a type library…",选中"sapi.dll"文件,这时系统会出现 confirm Classes 对话框,询问将要导入的类(有20多个类)。如果只要实现发音功能,只要导入IspeechObjectToken,IspeechObjectTokens,IspeechVoice这3个,其它类的功能我还在研究中。(如果在建项目的时候勾选了Automation,系统会自动帮你生成3个文件,分别是DlgProxy.cpp,DlgProxy.h还有一个根据你项目名.odl文件,如果没有勾选上Automation就不会创建这三个文件,所以我们要实现发音功能,就要自己添加修改这三个文件)
5、 没有自动生成的文件怎么办呢?最好的办法就是新建一个项目,它的名称和你现有的项目名称一样,然后在创建MFC Dialog Based项目的时候,选上Automation,然后做步骤4,将它生成的3个文件复制并加入到你现有项目中。
6、 复制好后,就要在一些文件上添加修改代码了。下面我以一个名为test的工程为例子首先在test.cpp文件添加这些代码(红色):
BOOL CTestApp::InitInstance()
{
if (!AfxOleInit())
{
AfxMessageBox("OLE 程序初始化失败。请确认 OLE 库程序是正确的版本");
return FALSE;
}
AfxEnableControlContainer();
// Standard initialization
// If you are not using these features and wish to reduce the size
// of your final executable, you should remove from the following
// the specific initialization routines you do not need.
#ifdef _AFXDLL
Enable3dControls(); // Call this when using MFC in a shared DLL
#else
Enable3dControlsStatic(); // Call this when linking to MFC statically
#endif
if (RunEmbedded() || RunAutomated())
{
// Register all OLE server (factories) as running. This enables the
// OLE libraries to create objects from other applications.
COleTemplateServer::RegisterAll();
}
else
{
// When a server application is launched stand-alone, it is a good idea
// to update the system registry in case it has been damaged.
COleObjectFactory::UpdateRegistryAll();
}
CTestDlg dlg;
m_pMainWnd = &dlg;
int nResponse = dlg.DoModal();
if (nResponse == IDOK)
{
// TODO: Place code here to handle when the dialog is
// dismissed with OK
}
7、 接着在testDlg.h文件添加以下代码:
#include "sapi.h"
class CtestDlgAutoProxy;
/////////////////////////////////////////////////////////////////////////////
// CTestDlg dialog
class CTestDlg : public CDialog
{
DECLARE_DYNAMIC(CTestDlg);
friend class CtestDlgAutoProxy;
// Construction
public:
virtual ~CTestDlg();
CTestDlg(CWnd* pParent = NULL); // standard constructor
ISpeechObjectToken recoObject;
LPDISPATCH pDisp;
CLSID CLSID_SpVoice;
ISpeechVoice voice;
ISpeechObjectTokens voiceList;
// Dialog Data
//{{AFX_DATA(CTestDlg)
enum { IDD = IDD_TEST_DIALOG };
CComboBox m_voice; //拖控件并添加control类型数据成员
long m_Rate;
long m_Vol;
//}}AFX_DATA
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CTestDlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL
// Implementation
protected:
HICON m_hIcon;
CtestDlgAutoProxy* m_pAutoProxy;
// Generated message map functions
//{{AFX_MSG(CTestDlg)
8、 接着在testDlg.cpp添加下面代码:
#include "DlgProxy.h"
////////////////////////////////////
IMPLEMENT_DYNAMIC(CTestDlg, CDialog);
CTestDlg::CTestDlg(CWnd* pParent /*=NULL*/)
: CDialog(CTestDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CTestDlg)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
m_pAutoProxy = NULL;
}
CTestDlg::~CTestDlg()
{
if (m_pAutoProxy != NULL)
m_pAutoProxy->m_pDialog = NULL;
}
//////////////////////////
BOOL CTestDlg::OnInitDialog()
{
。。。。。。。。。。。。。
// TODO: Add extra initialization here
CLSIDFromProgID(L"SAPI.SpVoice", &CLSID_SpVoice);
voice.CreateDispatch(CLSID_SpVoice);
pDisp = voice.m_lpDispatch;
HRESULT hr = pDisp->QueryInterface(CLSID_SpVoice, (void**)&voice.m_lpDispatch);
if (hr == S_OK) {
pDisp->Release();
}
else {
voice.AttachDispatch(pDisp, TRUE);
}
m_Rate=0;//语速
voice.SetRate(m_Rate);
m_Vol=100; //音量
voice.SetVolume(m_Vol);
//用来获取支持多少种声音
voiceList=voice.GetVoices(NULL,NULL);
m_voice.SetCurSel(0);
voice.SetRefVoice(voiceList.Item(0)); //item(0)是英文发音,如果装了中文包可设item(3)
//为中文发音
return TRUE; // return TRUE unless you set the focus to a control
}
9、 添加个button
void CTestDlg::OnButton1()
{
voice.Speak("you", 1);//发音
}
10、 在DlgProxy.cpp找到下面一句代码:
IMPLEMENT_OLECREATE2(CtestDlgAutoProxy, "test.Application", 0xc1b93196, 0x3df8, 0x4a61, 0xb1, 0x22, 0xa4, 0xc2, 0x8e, 0xe2, 0x75, 0xdb) 并将它注释掉。(我不知道原因,但不注释的话运行会出错,如果有朋友知道原因的话请告诉我)
经过上面的步骤后,就可以实现到发音了,可以用IspeechVoice类的函数调发音的速度和音量等。我试过了,在默认情况下发音和金山词霸差不多。