设为首页 收藏本站
查看: 702|回复: 0

[经验分享] IBM Voice CMDMenu语音命令控制技术 适用于Emmbbed IBM Viavoice的语音菜单,语音拨号

[复制链接]

尚未签到

发表于 2017-5-26 11:41:51 | 显示全部楼层 |阅读模式
  class CVCmdMenuDlg;
  class CIVCmdNotifySink: public IVCmdNotifySink
{
private:
DWORD m_dwRefCnt; /* count how many people our using us (the object)*/
CVCmdMenuDlg *pDlg;/* used to send notifications back to demo dialog object */
  public:
CIVCmdNotifySink (void); /* obligatory constructor*/
~CIVCmdNotifySink (void); /* obligatory destructory*/
CIVCmdNotifySink( CVCmdMenuDlg *pDlgInit );/* overloaded constructor for this demo */
  /* IUnknown */
STDMETHODIMP QueryInterface (REFIID, LPVOID FAR*);
STDMETHODIMP_(ULONG)AddRef(void); /* increment count*/
STDMETHODIMP_(ULONG)Release(void); /* decrements count*/
  /* IVCCmdNotifySink member functions */
STDMETHODIMP CommandRecognize (DWORD, PVCMDNAME, DWORD, DWORD, PVOID, DWORD, PSTR, PSTR);
STDMETHODIMP CommandOther (PVCMDNAME, PTSTR);
STDMETHODIMP CommandStart (void);
STDMETHODIMP MenuActivate (PVCMDNAME, BOOL);
STDMETHODIMP UtteranceBegin (void);
STDMETHODIMP UtteranceEnd (void);
STDMETHODIMP VUMeter (WORD);
STDMETHODIMP AttribChanged (DWORD);
STDMETHODIMP Interference (DWORD);
};
  typedef CIVCmdNotifySink* PCIVCmdNotifySink;
  
#include "stdafx.h"
#include "winreg.h"// supports reading the registry
#include "speech.h"// defines SAPI structures, interfaces
#include "VCmdNfy.h"
#include "VCmdMenu.h"
#include "VCmdDlg.h"
#include "initguid.h"// required by references to GUIDs
#include "SrWrapEn.h"// defines IBM speech engine GUIDs
  #ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
  // external for accessing the application object
extern CVCmdMenuApp theApp;
  /////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About
  class CAboutDlg : public CDialog
{
public:
CAboutDlg();
  // Dialog Data
//{{AFX_DATA(CAboutDlg)
enum { IDD = IDD_ABOUTBOX };
//}}AFX_DATA
  // ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CAboutDlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL
  // Implementation
protected:
//{{AFX_MSG(CAboutDlg)
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
  CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
//{{AFX_DATA_INIT(CAboutDlg)
//}}AFX_DATA_INIT
}
  void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CAboutDlg)
//}}AFX_DATA_MAP
}
  BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
//{{AFX_MSG_MAP(CAboutDlg)
// No message handlers
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
  /////////////////////////////////////////////////////////////////////////////
// CVCmdMenuDlg dialog
  CVCmdMenuDlg::CVCmdMenuDlg(CWnd* pParent /*=NULL*/)
: CDialog(CVCmdMenuDlg::IDD, pParent)
{
// don't forget to init pointers being tested later on !!! 11/05/96 pwa
gpIVCmdMenu=NULL;
gpIVoiceCommand=NULL;

//{{AFX_DATA_INIT(CVCmdMenuDlg)
m_strRecoEcho = _T("");
//}}AFX_DATA_INIT
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
  void CVCmdMenuDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CVCmdMenuDlg)
DDX_Control(pDX, IDC_STOP, m_buttonDeactivate);
DDX_Control(pDX, IDC_START, m_buttonActivate);
DDX_Control(pDX, IDC_PHRASELIST, m_listPhrase);
DDX_Text(pDX, IDC_RECOEOCHO, m_strRecoEcho);
//}}AFX_DATA_MAP
}
  BEGIN_MESSAGE_MAP(CVCmdMenuDlg, CDialog)
//{{AFX_MSG_MAP(CVCmdMenuDlg)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_START, OnActivate)
ON_BN_CLICKED(IDC_STOP, OnDeactivate)
ON_WM_CLOSE()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
  /////////////////////////////////////////////////////////////////////////////
// CVCmdMenuDlg message handlers
  // Return value of UseSpeech in registry, or -1 on read error.
int CVCmdMenuDlg::GetUseSpeech()
{
HKEY hKey;
DWORD dwType, dwSize, dwVal;
CString s;
  dwType = REG_DWORD;
dwSize = sizeof(DWORD);
  s.LoadString( IDS_KEYVOICE );
  if( ERROR_SUCCESS != RegOpenKeyEx(HKEY_CURRENT_USER, s.GetBuffer(0), 0, KEY_READ, &hKey) ) {
CString sMsg;
AfxFormatString1( sMsg, IDS_ERROR14, s.GetBuffer(0) );
AfxMessageBox( sMsg );
return -1;
}
  s.LoadString( IDS_VALUE );
if( ERROR_SUCCESS != RegQueryValueEx (hKey, s.GetBuffer(0), 0, &dwType, (LPBYTE)&dwVal, &dwSize) ) {
CString sMsg;
AfxFormatString1( sMsg, IDS_ERROR15, s.GetBuffer(0) );
AfxMessageBox( sMsg );
return -1;
}
  RegCloseKey (hKey);
  return (int)dwVal;
}
  // Create a pointer to a voice command interface
// On error, show message box and return 0.
// On success, return valid pointer.
PIVOICECMD CVCmdMenuDlg::CreatePIVCmd()
{
PIVOICECMD pIVCmd = 0;
  if ( S_OK != CoCreateInstance
(CLSID_VCmd, // voice command object class identifier
NULL,
CLSCTX_LOCAL_SERVER,
IID_IVoiceCmd,// voice command object interface identifier
(LPVOID*)&pIVCmd //ptr to voice command object interface
)
)
AfxMessageBox( IDS_ERROR1 );

return pIVCmd;
}
  // See if default site is using IBM speech engine
// If not, ask user if we can change it.
// Show error message and return FALSE on any error
// Assume: gpIVoiceCommand has already been registered
BOOL CVCmdMenuDlg::CheckSelectIBMEngine()
{
  BOOL bRc = FALSE;
PIVCMDATTRIBUTES pIVCmdAttr = 0;
GUID modeGuid;
BOOL bMBoxRc = FALSE;

if ( !gpIVoiceCommand )
return FALSE;
  if ( NOERROR != gpIVoiceCommand->QueryInterface(IID_IVCmdAttributes, (LPVOID FAR *)&pIVCmdAttr) )
AfxMessageBox( IDS_ERROR16 );
else {
if ( NOERROR != pIVCmdAttr->SRModeGet(&modeGuid) )
AfxMessageBox( IDS_ERROR17 );
else {
//check for US English navigation mode
if ( !bRc && ::IsEqualGUID(CLSID_SREngineEnumIBMContinuousModeUS,modeGuid) ) {
theApp.LanguageID=LANG_ENGLISH;
theApp.SubLangID =SUBLANG_ENGLISH_US;
bRc=TRUE;
}
  //check for UK English navigation mode
if ( !bRc && ::IsEqualGUID(CLSID_SREngineEnumIBMContinuousModeUK,modeGuid) ) {
theApp.LanguageID=LANG_ENGLISH;
theApp.SubLangID =SUBLANG_ENGLISH_UK;
bRc=TRUE;
}
  //check for German navigation mode
if ( !bRc && ::IsEqualGUID(CLSID_SREngineEnumIBMContinuousModeGR,modeGuid) ) {
theApp.LanguageID=LANG_GERMAN;
theApp.SubLangID =SUBLANG_GERMAN;
bRc=TRUE;
}
  //check for French navigation mode
if ( !bRc && ::IsEqualGUID(CLSID_SREngineEnumIBMContinuousModeFR,modeGuid) ) {
theApp.LanguageID=LANG_FRENCH;
theApp.SubLangID =SUBLANG_FRENCH;
bRc=TRUE;
}
  //check for Italian navigation mode
if ( !bRc && ::IsEqualGUID(CLSID_SREngineEnumIBMContinuousModeIT,modeGuid) ) {
theApp.LanguageID=LANG_ITALIAN;
theApp.SubLangID =SUBLANG_ITALIAN;
bRc=TRUE;
}
  //check for Spanish navigation mode
if ( !bRc && ::IsEqualGUID(CLSID_SREngineEnumIBMContinuousModeES,modeGuid) ) {
theApp.LanguageID=LANG_SPANISH;
theApp.SubLangID =SUBLANG_SPANISH;
bRc=TRUE;
}
  //prompt on unknown GUID mode
if ( !bRc )
bMBoxRc = AfxMessageBox(IDS_STRING151, MB_OKCANCEL);
  if ( !bRc && bMBoxRc == IDOK ) {
if ( NOERROR != pIVCmdAttr->SRModeSet(CLSID_SREngineEnumIBMContinuousModeUS) ) {
//if ( NOERROR != pIVCmdAttr->SRModeSet(CLSID_SREngineEnumIBMContinuousModeGR) ) {
AfxMessageBox( IDS_ERROR18 );
bRc = FALSE;
}
else {
theApp.LanguageID=LANG_ENGLISH;
theApp.SubLangID =SUBLANG_ENGLISH_US;
//theApp.LanguageID=LANG_GERMAN;
//theApp.SubLangID =SUBLANG_GERMAN;
bRc = TRUE;
}
}
else if ( !bRc && bMBoxRc == IDCANCEL ) {
// Want to use whatever engine is set in site.
bRc = TRUE;
}
}
}
  if ( pIVCmdAttr )
pIVCmdAttr->Release();
  return bRc;
}
  // Create a voice command menu for this app
// nAppState is the resource ID of a string specifying app state when menu should
//be active.
// dwFlags specifies how to create the menu
// Shows message box on any error and returns 0
// Returns pointer to menu object on success.
PIVCMDMENU CVCmdMenuDlg::CreateMainMenu( UINT nAppState, DWORD dwFlags )
{
PIVCMDMENU pIVCmdMenu = 0;
VCMDNAME VCmdName; // Command Name
LANGUAGE Language; // language to use
CString s;
int iLangStringID;
  //findresourceex
// Get our app name from our resource file
s.LoadString( IDS_STRING148 );
// Truncate our name to field length
lstrcpy( VCmdName.szApplication,
(s.Left(VCMD_APPLEN)).GetBuffer(0)
);
  // Get our app state from our resource file
if ( !s.LoadString( nAppState ) )
AfxMessageBox( IDS_ERROR19 );
// Truncate our state to field length
lstrcpy( VCmdName.szState,
(s.Left(VCMD_STATELEN)).GetBuffer(0)
);
  // Specify United States English language model
Language.LanguageID = theApp.LanguageID;

switch(theApp.LanguageID)
{
case LANG_ENGLISH:
switch(theApp.SubLangID)
{
case SUBLANG_ENGLISH_US:
iLangStringID=IDS_Lang_US;
break;
case SUBLANG_ENGLISH_UK:
iLangStringID=IDS_Lang_UK;
break;
}
break;
case LANG_GERMAN:
iLangStringID=IDS_Lang_GR;
break;
case LANG_FRENCH:
iLangStringID=IDS_Lang_FR;
break;
case LANG_ITALIAN:
iLangStringID=IDS_Lang_IT;
break;
case LANG_SPANISH:
iLangStringID=IDS_Lang_ES;
break;
default:
iLangStringID=IDS_Lang_US;
break;
}
  s.LoadString( iLangStringID );
lstrcpy (Language.szDialect,
(s.Left(LANG_LEN)).GetBuffer(0)
);
  if ( NOERROR != gpIVoiceCommand->MenuCreate(&VCmdName,
&Language,
dwFlags,
&pIVCmdMenu
)
)
AfxMessageBox( IDS_ERROR4 );
  return pIVCmdMenu;
}
  // Initialize SAPI voice command interface on default site,
// register a notification sink, and create a temporary voice command menu.
// On success, global pointers
//gpIVoiceCommand
//gpVCmdNotifySink
//gpIVCmdMenu
// are non-zero and ready to be used.
// Error messages displayed as appropriate.
// Application exits if error reading required entries in registry
// If default site is not using IBM engine, user is given a chance to set it,
void CVCmdMenuDlg::OnInitSpeech()
{
  /* ----------------------------------------------------------- */
/* Check the registry to see if user has installed and enabled */
/* SAPI voice recognition */
/* ----------------------------------------------------------- */
int nUseSpeech = GetUseSpeech();
switch( nUseSpeech ) {
case -1:
// Cannot find required key/value in registry. Something's wrong
// with user's install of SAPI etc.
AfxMessageBox( IDS_STRING147 );
//OnClose();//don't do that !!! 11/05/96 pwa
this->EndDialog(0);//bye-bye due to errors 11/05/96 pwa
break;
case 0:
// User has installed SAPI speech, but it is not enabled.
// You should ask the user whether to continue.
// We're going to go ahead anyway.
// See SAPI Speech API Developer's Guide, Chapter 8.
case 1:
// User has installed and enabled SAPI speech
default:
// The key/value exists, but the value is unexpected...
break;
}
  /* -------------------------------------------------------- */
/* Create an instance of the voice command and voice menu */
/* objects. */
/* -------------------------------------------------------- */
gpIVoiceCommand = 0;
gpVCmdNotifySink = 0;
gpIVCmdMenu = 0;
  gpIVoiceCommand = CreatePIVCmd();
  if ( gpIVoiceCommand ) {
/* -------------------------------------------------- */
/* Create the VCmd notification sink interface object */
/* ---------------------------------------------------*/
gpVCmdNotifySink = new CIVCmdNotifySink( this );
if ( 0 == gpVCmdNotifySink )
AfxMessageBox( IDS_ERROR2 );
else {
/* ------------------------------------------------------ */
/* Register the notification sink with the voice cmd obj. */
/* We are passing VCMDRF_ALLMESSAGES because we want our */
/* app to be notified of all possible notifications. */
/* ------------------------------------------------------ */
// Note: This version of the call uses the default
// site with default settings
if ( NOERROR != gpIVoiceCommand->Register(
"", // means voice input is from computer
gpVCmdNotifySink,// adr of voice-command object
// notification interface
IID_IVCmdNotifySink,// GUID of sink type being passed
VCMDRF_ALLMESSAGES,// send us all notification msgs
NULL // use the voice-site settings from the
// registry, or the defaults if there are none
)
)
AfxMessageBox( IDS_ERROR3 );
else {
// See if default engine is IBM. Let user select it.
if ( !CheckSelectIBMEngine() )
return;
  // init the voice command list
InitListBox();
// Save current SAPI site enabled state. We'll restore it when we exit.
gdwSiteState = GetSiteState();
// Now, make sure SAPI site is enabled
SetSiteState( TRUE );
  gpIVCmdMenu = CreateMainMenu( IDS_STRING149, VCMDMC_CREATE_TEMP );
}
}
}
}
  void CVCmdMenuDlg::OnExitSpeech()
{
/* ------------------------------------------ */
/* Release the voice command menu interface */
/* ------------------------------------------ */
if (gpIVCmdMenu) {
gpIVCmdMenu->Release();
gpIVCmdMenu = 0;
}
  /* ------------------------------------------ */
/* Restore the voice command enabled state */
/* before releasing voice command object */
/* ------------------------------------------ */
SetSiteState( gdwSiteState );
  /* ------------------------------------------ */
/* Release the voice command object interface */
/* ------------------------------------------ */
if (gpIVoiceCommand) {
gpIVoiceCommand->Release();
gpIVoiceCommand = 0;
}

// Note: gpIVoiceCommand object releases our gpVCmdNotifySink object,
//which we "new"ed in OnInitSpeech(). Its release logic deletes it
// when the last (ie. one and only) reference is released, so we
//do not delete it here.
  }
  BOOL CVCmdMenuDlg::OnInitDialog()
{
m_strRecoEcho.LoadString( IDS_INITRECOECHO );
  CDialog::OnInitDialog();
  // Add "About..." menu item to system menu.
  // IDM_ABOUTBOX must be in the system command range.
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
  CMenu* pSysMenu = GetSystemMenu(FALSE);
CString strAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
  // Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE);// Set big icon
SetIcon(m_hIcon, FALSE);// Set small icon

// TODO: Add extra initialization here
  OnInitSpeech();// Initialize SAPI voice command speech recognition
  return TRUE; // return TRUE unless you set the focus to a control
}
  void CVCmdMenuDlg::InitListBox()
{
/********************************************************/
/* Initialize the phrase list box.*/
/* This code depends on the phrases being consecutively*/
/* numbered string resources between IDS_PhraseBase and*/
/* IDS_PhraseLast.*/
/********************************************************/
CString s;
int iPhraseBase, iPhraseLast;

switch(theApp.LanguageID)
{
case LANG_ENGLISH:
switch(theApp.SubLangID)
{
case SUBLANG_ENGLISH_US:
iPhraseBase=IDS_PhraseBase_US;
iPhraseLast=IDS_PhraseLast_US;
break;
case SUBLANG_ENGLISH_UK:
iPhraseBase=IDS_PhraseBase_UK;
iPhraseLast=IDS_PhraseLast_UK;
break;
}
break;
case LANG_GERMAN:
iPhraseBase=IDS_PhraseBase_GR;
iPhraseLast=IDS_PhraseLast_GR;
break;
case LANG_FRENCH:
iPhraseBase=IDS_PhraseBase_FR;
iPhraseLast=IDS_PhraseLast_FR;
break;
case LANG_ITALIAN:
iPhraseBase=IDS_PhraseBase_IT;
iPhraseLast=IDS_PhraseLast_IT;
break;
case LANG_SPANISH:
iPhraseBase=IDS_PhraseBase_ES;
iPhraseLast=IDS_PhraseLast_ES;
break;
default:
iPhraseBase=IDS_PhraseBase_US;
iPhraseLast=IDS_PhraseLast_US;
break;
}
  for( int i = iPhraseBase + 1; i < iPhraseLast; i++ ) {
if ( s.LoadString(i) ) {
if ( LB_ERR == m_listPhrase.AddString( s.GetBuffer(0) ) ) {
AfxMessageBox( IDS_ERROR5 );
break;
}
}
}
m_listPhrase.SetSel( 0 );// select the first phrase
m_buttonDeactivate.EnableWindow( FALSE );
}
  void CVCmdMenuDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialog::OnSysCommand(nID, lParam);
}
}
  // If you add a minimize button to your dialog, you will need the code below
// to draw the icon. For MFC applications using the document/view model,
// this is automatically done for you by the framework.
  void CVCmdMenuDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // device context for painting
  SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
  // Center icon in client rectangle
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
  // Draw the icon
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialog::OnPaint();
}
}
  // The system calls this to obtain the cursor to display while the user drags
// the minimized window.
HCURSOR CVCmdMenuDlg::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
}
  void CVCmdMenuDlg::OnActivate()
{
// TODO: Add your control notification handler code here
  // If no phrases selected, then we can't build a voice command menu
int nCount = m_listPhrase.GetSelCount();
if ( 0 >= nCount ) {
AfxMessageBox( IDS_STRING141 );
return;
}
  // If voice command menu setup ok
if ( VoiceCmdMenuEmpty()
&& VoiceCmdMenuFill()
&& VoiceCmdMenuActivate()
) {
// toggle buttons
m_buttonActivate.EnableWindow( FALSE );
m_buttonDeactivate.EnableWindow( TRUE );
// reinitialize recognized text area
m_strRecoEcho.LoadString( IDS_INITRECOECHO );
UpdateData( FALSE );
}
}
  void CVCmdMenuDlg::OnDeactivate()
{
// TODO: Add your control notification handler code here
if ( gpIVCmdMenu )
if ( NOERROR != gpIVCmdMenu->Deactivate() )
AfxMessageBox( IDS_ERROR20 );
  m_buttonActivate.EnableWindow( TRUE );
m_buttonDeactivate.EnableWindow( FALSE );

}
  
BOOL CVCmdMenuDlg::VoiceCmdMenuActivate()
{
HRESULT hResult;
  // check initialization did not fail
if ( 0 == gpIVCmdMenu )
return FALSE;
  // first argument is handle of window to associate with this menu. NULL makes it global to this application
// second argument is whether menu should be active when voice reco is "awake" (0) or "asleep" (VWGFLAG_ASLEEP)
hResult = gpIVCmdMenu->Activate( NULL, 0 );
if ( NOERROR != hResult ) {
AfxMessageBox( IDS_ERROR6 );
return FALSE;
} else return TRUE;
  }
  BOOL CVCmdMenuDlg::VoiceCmdMenuEmpty()
{
HRESULT hResult;
DWORD dwNum;
  // check initialization did not fail
if ( 0 == gpIVCmdMenu )
return FALSE;
  // get the number of items in a voice command menu
hResult = gpIVCmdMenu->Num( &dwNum );
if ( NOERROR != hResult ) {
AfxMessageBox( IDS_ERROR7 );
return FALSE;
}
  // remove items from first parameter to first plus second parameter from a voice command menu
// if third parameter is VCMD_BY_IDENTIFIER, then second parameter is identifier of commands to remove
if ( dwNum ) {
hResult = gpIVCmdMenu->Remove( 1, dwNum, VCMD_BY_POSITION );
if ( NOERROR != hResult ) {
AfxMessageBox( IDS_ERROR8 );
return FALSE;
}
}
  return TRUE;
}
  BOOL CVCmdMenuDlg::VoiceCmdMenuFill()
{
HRESULT hResult;
SDATA data;
PVCMDCOMMAND pVCmdCmd;
DWORD dwNum, dwStart, dwSize, dwCatSize;
CHAR szCat[] = "Main";
int *nArraySelect;
  // check initialization did not fail
if ( 0 == gpIVCmdMenu )
return FALSE;
  dwNum = m_listPhrase.GetSelCount();
if ( 0 == dwNum ) {
AfxMessageBox( IDS_STRING142 );
return FALSE;
}
nArraySelect = (int *)CoTaskMemAlloc( dwNum* sizeof(int) );
if ( NULL == nArraySelect ) {
AfxMessageBox( IDS_ERROR9 );
return FALSE;
}
m_listPhrase.GetSelItems( dwNum, nArraySelect );
  // SDATA can refer to an "array" of VCMDCOMMAND structures.
// We'll build this array be reallocating pVCmdCmd, once
// each time through our list loop below.
dwSize = 0;
pVCmdCmd = (PVCMDCOMMAND)CoTaskMemAlloc( dwSize );
if ( 0 == pVCmdCmd ) {
AfxMessageBox( IDS_ERROR10 );
return FALSE;
}

// The variable data at the end of VCMDCOMMAND structure must all begin on 32-bit boundaries
// See SAPI specification for more details
dwCatSize = 1 + lstrlen( szCat );
dwCatSize = (dwCatSize+3)&(~3);
  for( int i = 0; i < (int)dwNum; i++ ) {
PCHAR pNext;
PVCMDCOMMAND pVCmdNew;
DWORD dwStrSize, dwAlignSize, dwNewSize;
  // extend existing structure for next VCMDCOMMAND structure
dwStrSize = 1 + m_listPhrase.GetTextLen( nArraySelect );
dwAlignSize = (dwStrSize+3)&(~3);
dwNewSize = dwSize + sizeof(VCMDCOMMAND) + 2*dwAlignSize + dwCatSize + sizeof(DWORD);
pVCmdCmd = (PVCMDCOMMAND)CoTaskMemRealloc( pVCmdCmd, dwNewSize );
if ( 0 == pVCmdCmd ) {
AfxMessageBox( IDS_ERROR11 );
return FALSE;
}
// fill in the new VCMDCOMMAND structure
pNext = (PCHAR)pVCmdCmd + dwSize;
memset( pNext, 0, dwNewSize - dwSize );
pVCmdNew = (PVCMDCOMMAND)pNext;
pVCmdNew->dwSize = dwNewSize - dwSize;// sizeof this structure
pVCmdNew->dwFlags = 0;// these flags can specify confirmaton, disabled. See SAPI spec.
pVCmdNew->dwCommandText= NULL;// use dwCommand to show voice command menu to user
pVCmdNew->dwActionSize = sizeof(DWORD);// size of action data
// fill in the variable data at end of new structure
pNext += sizeof(VCMDCOMMAND);// variable data starts at abdata[]
pVCmdNew->dwAction = (DWORD)(pNext - (PCHAR)pVCmdNew);// offset to app-unique action code
*(DWORD *)(pNext) = (DWORD)i;// make up an action code for this command
pNext += sizeof(DWORD);
pVCmdNew->dwCommand = (DWORD)(pNext - (PCHAR)pVCmdNew);// offset to command string
if ( (int)dwStrSize != 1 + m_listPhrase.GetText(nArraySelect, (LPTSTR)pNext) ) {
AfxMessageBox( IDS_ERROR12 );
return FALSE;
}
pNext += dwAlignSize;
pVCmdNew->dwDescription = (DWORD)(pNext - (PCHAR)pVCmdNew);// offset to command description
if ( (int)dwStrSize != 1 + m_listPhrase.GetText(nArraySelect, (LPTSTR)pNext) ) {
AfxMessageBox( IDS_ERROR12 );
return FALSE;
}
pNext += dwAlignSize;
pVCmdNew->dwCategory = (DWORD)(pNext - (PCHAR)pVCmdNew);// offset to command category
strcpy( pNext, szCat );
dwSize = dwNewSize;
}
  data.pData = pVCmdCmd;
data.dwSize = dwSize;
  hResult = gpIVCmdMenu->Add( dwNum, data, &dwStart );
if ( NOERROR != hResult ) {
AfxMessageBox( IDS_ERROR13 );
return FALSE;
}
  CoTaskMemFree( nArraySelect );
CoTaskMemFree( data.pData );
return TRUE;
}
  void CVCmdMenuDlg::CommandRecognized( PSTR pszText )
{
m_strRecoEcho = pszText;
UpdateData( FALSE );// send fields to dialog window
}
  void CVCmdMenuDlg::CommandOther( PSTR pszText )
{
if ( NULL == pszText )
m_strRecoEcho.LoadString( IDS_NOTRECOED );
else {
m_strRecoEcho.LoadString( IDS_CMDOTHER );
m_strRecoEcho += pszText;
}
UpdateData( FALSE );
}
void CVCmdMenuDlg::TooNoisy()
{
m_strRecoEcho.LoadString( IDS_TOONOISY );
UpdateData( FALSE );// send fields to dialog window
}
  void CVCmdMenuDlg::NoSignal()
{
m_strRecoEcho.LoadString( IDS_NOSIGNAL );
UpdateData( FALSE );// send fields to dialog window
}
  void CVCmdMenuDlg::TooLoud()
{
m_strRecoEcho.LoadString( IDS_TOOLOUD );
UpdateData( FALSE );// send fields to dialog window
}
  void CVCmdMenuDlg::TooQuiet()
{
m_strRecoEcho.LoadString( IDS_TOOQUIET );
UpdateData( FALSE );// send fields to dialog window
}
  // Read enabled state of voice command site
// Show message box on error.
DWORD CVCmdMenuDlg::GetSiteState()
{
PIVCMDATTRIBUTES pIVCmdAttr = 0;
DWORD dwEnabled = 0;

if ( gpIVoiceCommand ) {
if ( NOERROR != gpIVoiceCommand->QueryInterface(IID_IVCmdAttributes, (LPVOID FAR *)&pIVCmdAttr) )
AfxMessageBox( IDS_ERROR16 );
else {
if ( NOERROR != pIVCmdAttr->EnabledGet(&dwEnabled) )
AfxMessageBox( IDS_ERROR21 );
}
}
  if ( pIVCmdAttr )
pIVCmdAttr->Release();
  return dwEnabled;
}
  // Set enabled state of voice command site
// Show message box on error.
void CVCmdMenuDlg::SetSiteState( DWORD dwEnabled )
{
PIVCMDATTRIBUTES pIVCmdAttr = 0;

if ( gpIVoiceCommand ) {
if ( NOERROR != gpIVoiceCommand->QueryInterface(IID_IVCmdAttributes, (LPVOID FAR *)&pIVCmdAttr) )
AfxMessageBox( IDS_ERROR16 );
else {
if ( NOERROR != pIVCmdAttr->EnabledSet(dwEnabled) )
AfxMessageBox( IDS_ERROR22 );
}
}
  if ( pIVCmdAttr )
pIVCmdAttr->Release();
}
  void CVCmdMenuDlg::OnOK()
{
// TODO: Add extra validation here
  // Restore site state and shut down voice reco objects...
OnExitSpeech();
  CDialog::OnOK();
}
  void CVCmdMenuDlg::OnClose()
{
// TODO: Add your message handler code here and/or call default

// Restore site state and shut down voice reco objects...
OnExitSpeech();
  CDialog::OnClose();
}
  void CVCmdMenuDlg::WinHelp(DWORD dwData, UINT nCmd)
{
// TODO: Add your specialized code here and/or call the base class
return;
}
  需要源码的留下邮件,我来发,

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-381347-1-1.html 上篇帖子: 2006"IBM 杯"中国高校 SOA 应用大赛题目 下篇帖子: IBM pSeries AIX System Administration -- 系统分页空间管理
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表