2020-09-30 16:53:49 +02:00

251 lines
8.7 KiB
C++

// XMLCommand.cpp: implementation of the CXMLCommand class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "XMLCommand.h"
#include "sphelper.h"
#include "debug.h"
#include "utils.h"
extern WCHAR g_szPrefix[];
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CXMLCommand::~CXMLCommand()
{
}
CXMLCommanding::~CXMLCommanding()
{
}
//
//
//
void CXMLCommanding::Callback()
{
CSpEvent event;
if (m_cpRecoCtxt)
{
while (event.GetFrom(m_cpRecoCtxt) == S_OK)
{
switch (event.eEventId)
{
case SPEI_RECOGNITION:
{
HRESULT hr=ExecuteCommand(event.RecoResult());
}
break;
}
}
}
}
//
// These rules fire, let's see what we're supposed to do with them!
// we get the text that the user said, we then find the command (one of our children)
// we then find the ID, and if the parent isn't disabled, we send the message.
//
HRESULT CXMLCommanding::ExecuteCommand( ISpPhrase *pPhrase )
{
HRESULT hr=S_OK;
LPWSTR pszSaid = GetRecognizedText( pPhrase );
int i=0;
CXMLCommand * pCommand;
// go through the list of commands, and find the one the user said.
BOOL bFound=FALSE;
while( pCommand=m_Commands.GetPointer(i++) )
{
LPWSTR pszText;
if( SUCCEEDED( pCommand->get_Attr( TEXT("TEXT"), &pszText )))
{
if( *pszText==L'+' )
pszText++;
if( *pszText==L'-' )
pszText++;
if( *pszText==L'?' )
pszText++;
if(lstrcmpi( pszText, pszSaid ) == 0 )
{
LPWSTR pszCommandID;
bFound=TRUE;
if( SUCCEEDED( pCommand->get_Attr( TEXT("ID"), &pszCommandID )))
{
UINT uiID=StringToIntDef(pszCommandID,0);
if(uiID)
{
IRCMLNode * pParent;
if( SUCCEEDED(DetachParent( & pParent )))
{
IRCMLControl * pControl;
if( SUCCEEDED( pParent->QueryInterface( __uuidof( IRCMLControl ) , (LPVOID*)&pControl )))
{
HWND hWnd;
if( SUCCEEDED( pControl->get_Window( &hWnd )))
{
if( IsWindow( hWnd ) )
{
if (IsEnabled(hWnd)==FALSE)
{
hr=E_FAIL;
break;
}
// See if there is a target child window.
if( TRUE || (GetForegroundWindow() == hWnd ) )
{
HWND hwndFrom=hWnd;
LPWSTR pszTarget;
if( SUCCEEDED( get_Attr( TEXT("TARGET"), &pszTarget )))
{
UINT uiChild = StringToIntDef(pszTarget, 0 );
if(uiChild)
hWnd=GetDlgItem( hWnd, uiChild );
}
LPWSTR pszFrom;
if( SUCCEEDED( get_Attr( TEXT("FROM"), &pszFrom )))
{
UINT uiChild = StringToIntDef(pszFrom, 0 );
if(uiChild)
hwndFrom=GetDlgItem( hWnd, uiChild );
}
PostMessage(hWnd, WM_COMMAND, MAKEWPARAM( uiID,0) , (LPARAM)hwndFrom);
}
else
{
TRACE(TEXT("Trying to send a command to a non-foreground window\n"));
hr=E_FAIL;
}
}
else
{
TRACE(TEXT("The window 0x%08x cannot receive commands\n"),hWnd );
hr=E_FAIL;
}
}
if( SUCCEEDED(pCommand->IsType(L"CICERO:COMMAND" )))
{
CXMLCommand * pXMLCommand=(CXMLCommand*)pCommand;
if(SUCCEEDED(hr))
{
if( hr!=S_FALSE )
{
pXMLCommand->SaySuccess();
}
}
else
{
pXMLCommand->SayFailure();
}
}
pControl->Release();
}
}
}
}
break;
}
}
}
if( bFound==FALSE )
{
TCHAR szStuff[1024];
wsprintf(szStuff,TEXT("You said %s"),pszSaid);
g_Notifications.SetText(szStuff);
}
delete pszSaid;
return hr;
}
////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////
//
// The base sapi node has provisions for a FAILURE element, and list of SYNONYMs
//
HRESULT STDMETHODCALLTYPE CXMLCommanding::AcceptChild(
IRCMLNode __RPC_FAR *pChild)
{
LPWSTR pType;
LPWSTR pChildType;
get_StringType( &pType );
pChild->get_StringType( &pChildType );
if( SUCCEEDED( pChild->IsType( L"CICERO:COMMAND" )))
{
m_Commands.Append((CXMLCommand*)pChild);
return S_OK;
}
return E_INVALIDARG; // we don't take children.
}
//////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Check the type of the control, perhaps the text, and build a CFG accordingly.
//
HRESULT STDMETHODCALLTYPE CXMLCommanding::InitNode(
IRCMLNode __RPC_FAR *pParent)
{
HRESULT hr=S_OK;
TCHAR temp[1024];
TCHAR szBuffer[2];
szBuffer[0]=0xfeff;
szBuffer[1]=NULL;
PSTRINGBUFFER pBuffer = AppendText( NULL, szBuffer);
pBuffer = AppendText(pBuffer, g_szPrefix);
pBuffer = AppendText(pBuffer, TEXT("<RULE NAME=\"MENU\" TOPLEVEL=\"ACTIVE\">"));
pBuffer = AppendText(pBuffer, TEXT("<L>"));
BOOL bAnythingAdded=FALSE;
int i=0;
CXMLCommand * pCommand;
while( pCommand=m_Commands.GetPointer(i++) )
{
LPWSTR pszText;
if( SUCCEEDED( pCommand->get_Attr( TEXT("TEXT"), &pszText )))
{
wsprintf(temp,TEXT("<P>%s</P>"),pszText);
pBuffer = AppendText(pBuffer, temp );
bAnythingAdded=TRUE;
}
}
pBuffer = AppendText(pBuffer, TEXT("</L>"));
pBuffer = AppendText(pBuffer, TEXT("</RULE></GRAMMAR>"));
if( bAnythingAdded )
{
IRCMLControl * pControl;
if( SUCCEEDED( pParent->QueryInterface( __uuidof( IRCMLControl ) , (LPVOID*)&pControl )))
{
LPWSTR pszControlText=GetControlText(pControl);
hr=LoadCFGFromString( pBuffer->pszString, pszControlText );
delete pszControlText;
pControl->Release();
}
}
AppendText(pBuffer,NULL);
return S_OK;
}