📄 voicecmd.shtml.htm
字号:
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
<meta name="author" content="zafir anjum">
<title>mfc programmer's sourcebook : advanced ui</title>
<meta name="description" content="source code for implementing advanced ui features">
<meta name="keywords" content>
</head>
<body background="../di2001.jpg"
tppabs="http://www.codeguru.com/fancyhome/back.gif" bgcolor="#ffffff">
<h3 align="center"><font color="#aoao99">voice command enabling your software </font></h3>
<hr>
<p>this article was contributed by <a href="mailto:keithsw@geocities.com">keith westley</a>.
</p>
<p>ibm and dragon have made quite a splash with their voice software enabling users to
dictate text to their computers and use voice to control applications. this article
presents an mfc class based on the microsoft speech sdk which will enable you to make your
application work with these engines to accept voice commands. </p>
<p>to use this class you must have a copy of the microsoft speech sdk version 3 or above.
i believe this is available on msdn. it is also available from microsoft's <a
href="http://research.microsoft.com/stg/" tppabs="http://research.microsoft.com/stg/"
target="_new">web site</a>. </p>
<p>these classes basically wrap the ivoicecmd com interface. they are specifically
designed to simplify the interface so you can put speech into your applications with
minimum effort. they also provide some features above and beyond the sdk including a built
in "what can i say?" command and confirmation prompts. my cdialog and
cscrollview derived classes show how you can also voice enable windows built in message
boxes. if you wish to use this feature you will need to create similar classes for cview,
cformview etc. i leave this as an exercise for the reader. </p>
<p><b>the ccommandmenu class</b> </p>
<p>before i leap into code i will outline each of the public methods on the ccommandmenu
class which does most of the hard work. <!-- start a block of source code --> </p>
<pre><tt><font color="#990000">
static ccommandmenu* createwindowcommandmenu(cwnd* pwnd, const cstring& sverify = "do it",
const cstring& swhatcanisay = "what can i say", const dword dwverifytimeout = 3000,
cwnd* pmessagetarget = null);
</font></tt></pre>
<p>this method is the only way in which a ccommandmenu object can be created. it returns
null if it cannot be created. the most typical reason it fails is that a suitable engine
has not been installed on the users machine. the parameters are ...
<ul>
<li>pwnd - this is the window that the commands are associated with. it must be a top level
window. do not pass a cview derived class here. if you are voice enabling a view class
then you must pass in the cmainframe class here. the commands in this menu will only be
available when this window is the active window. </li>
<li>sverify - this is the phrase the user must say after a voice command that requires
confirmation to confirm the computer has heard the command correctly. </li>
<li>swhatcanisay - this is the phrase the user can use to query the computer for what voice
commands the computer can understand. </li>
<li>dwverifytimeout - this is the number of milliseconds the computer allows for the user to
confirm their command before it just assumes it heard you wrong. </li>
<li>pmessagetarget - this is the window to send notifications to. if this parameter is null
then notifications are sent to pwnd. if you are voice enabling a view and want the view to
receove the voice messages then pass a pointer to the view here. if you are voice enabling
a dialog then this can be null. </li>
</ul>
<!-- start a block of source code -->
<pre><tt><font color="#990000">
bool deactivate(void);
bool activate(void);
</font></tt></pre>
<p>these methods activate and deactivate the command menu. if you are adding several voice
commands to the menu then you will find it runs faster if you deactivate the menu before
the first add and then re-activate it after the last add. <!-- start a block of source code --> </p>
<pre><tt><font color="#990000">
bool add(const cstring& scmd, const dword dwid, const bool fconfirmation,
const cpoint& ptconfirmationpromptpos, const bool fsendwm_command);
<!-- end the block of source code -->
</font></tt></pre>
<p>this method adds a voice command that your window is listening for. the parameters are
...
<ul>
<li>scmd - this is the word or phrase the computer will listen for. to help the reliability
of the voice command recognition it is recommended that you make the commands as
distinctly sounding as possible without confusing your users. </li>
<li>dwid - this is an identifier for your command. it must be unique otherwise you won't be
able to tell which command was spoken. if fsendwm_command is true then it must be the
control id of the button or menu you want to receive the wm_command message. </li>
<li>fconfirmation - if this is true then the user will be prompted to confirm their command
before the command is executed. this should be used for any command that does anything
that is not reversable. </li>
<li>ptconfirmationpromptpos - this is a point relative to the window where the confirmation
prompt tooltip should be displayed. </li>
<li>fsendwm_command - if this is true then the voice command notification is sent to your
window via a wm_command message. this simplifies you coding on the window but requires you
have a button for each voice command. </li>
</ul>
<!-- start a block of source code -->
<pre><tt><font color="#990000">
bool remove(const cstring& scmd);
bool remove(const dword dwid);
</font></tt></pre>
<p>these methods remove a voice command from the menu. <!-- start a block of source code --> </p>
<pre><tt><font color="#990000">
bool removeall(void);
<!-- end the block of source code -->
</font></tt></pre>
<p>this method removes all voice commands from the menu. <!-- start a block of source code --> </p>
<pre><tt><font color="#990000">
bool enableitem(const dword dwid, const bool fenable);
bool enableitem(const cstring& scmd, const bool fenable);
<!-- end the block of source code -->
</font></tt></pre>
<p>these methods are used to enable and disable voice commands. when a voice command is
disabled it will not appear on the "what can i say?" list. <!-- start a block of source code --> </p>
<pre><tt><font color="#990000">
static bool isavailable(void);
<!-- end the block of source code -->
</font></tt></pre>
<!-- create more blocks of article text as needed -->
<p>this method can be called at any time to see if voice input is available on this
machine. </p>
<p><b>sample project</b> </p>
<p>now that we understand the cvoicecommand class it is time to add some voice commands to
a project. our sample project is a very simple dialog based project. </p>
<p><u>step 1</u> </p>
<p>in order to use this class you project needs to have the appropriate ole code inserted.
this may be already there but it may not. </p>
<p>in stdafx.h check that the following include statement is present <!-- start a block of source code --> </p>
<pre><tt><font color="#990000">
#include <afxdisp.h> // mfc ole automation classes
<!-- end the block of source code -->
</font></tt></pre>
<p>in your applications initinstance check you are initialising the com libraries </p>
<pre><tt><font color="#990000">
// initialize ole libraries
if (!afxoleinit())
{
afxmessagebox("ole did not initialise.");
return false;
}
</font></tt></pre>
<p><u>step 2</u> </p>
<p>we must change the class from which our csampledialog is derived. by default this was
cdialog and we need to change it to cvoicecommanddialog. a simple search and replace in
the sampledlg.h and sampledlg.cpp files does the trick. </p>
<p><u>step 3</u> </p>
<p>in our dialog box constructor we can override some of the default settings used for
message boxes. </p>
<pre><tt><font color="#990000">
// enable voice input
setvoiceenabled(true);
// enable voice input on message boxes
setmessageboxverify(true);
</font></tt></pre>
<p><u>step 4</u> </p>
<p>now we need to add some voice commands. this is most easily done in the oninitdialog
member funtion. don't forget to check the m_pvoicecmd is not null before using it. </p>
<pre><tt><font color="#990000">
if (m_pvoicecmd != null)
{
m_pvoicecmd->deactivate();
m_pvoicecmd->add("close", m_close.getdlgctrlid(), true, cpoint(0,0), true);
m_pvoicecmd->add("message box", m_messagebox.getdlgctrlid(), true, cpoint(0,0), true);
m_pvoicecmd->add("up", 1, false, cpoint(0,0), false);
m_pvoicecmd->add("down", 2, false, cpoint(0,0), false);
m_pvoicecmd->activate();
}
else
{
messagebox("voice command not available.", "warning", mb_ok);
}
</font></tt></pre>
<p><u>step 5</u> </p>
<p>we need to add a message handler to receive the command notifications </p>
<pre><tt><font color="#990000">
begin_message_map(csampledlg, cvoicecommanddialog)
on_command_confirmed()
</font></tt></pre>
<p>and insert it's definition in the dialogs header file </p>
<pre><tt><font color="#990000">
afx_msg long oncommandconfirmed(uint, long);
declare_message_map()
</font></tt></pre>
<p>and then actually write the handler </p>
<pre><tt><font color="#990000">
afx_msg long csampledlg::oncommandconfirmed(uint dwid, long lunused)
{
updatedata(false);
switch(dwid)
{
case 1:
if (m_edit < 10)
{
m_edit++;
}
break;
case 2:
if (m_edit > 0)
{
m_edit--;
}
break;
default:
assert(false);
break;
}
updatedata(false);
return 0;
}
</font></tt></pre>
<p><u>step 6</u> </p>
<p>lastly don't forget to add my source files to your project so it will link correctly...
<ul>
<li>speachinput.cpp </li>
<li>timerwindow.cpp </li>
<li>tip.cpp </li>
<li>voicecommanddialog.cpp </li>
</ul>
<p>... and that is all there is to it. </p>
<p><a href="voicecmd.zip" tppabs="http://www.codeguru.com/advancedui/voicecmd.zip">download
source - 60 kb</a> </p>
<p>date posted: november 6, 1998 <!--comments--> </p>
</body>
</html>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -