📄 agent.cpp
字号:
// Agent.cpp: implementation of the CAgent class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include <atlbase.h>
#include "Agent.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
#pragma warning( disable : 4244 ) // Disable warning no. 4244
//-------------------------------------------
// Consts/Macros and other stuff
//-------------------------------------------
#define SAFE_RELEASE(p) { if(p) { (p)->Release(); (p)=NULL; } }
//-------------------------------------------
// Constructor/Destructor
//-------------------------------------------
CAgent::CAgent()
{
m_pAgentEx = NULL;
m_pNotifySink = NULL;
m_lNotifySinkID = -1;
}
CAgent::~CAgent()
{
Close(); // NOTE: You will get an error if you call CoUninitialize() before
// the destructor of this class is called
// There are some solutions for this
// 1) Close MsAgent manually (CAgent::Close)
// 2) If you are using MFC call CoUninitialize() in the destructor of the
// CWinApp derived class
}
//-------------------------------------------
// Error functions
//-------------------------------------------
void CheckAndThrow(int nCode)
{
if ( SUCCEEDED (nCode) )
return; // No error
// Otherwise throw an exception
int* pError = new int; // Alloc int
*pError = nCode; // Set error
throw pError; // Throw
}
void Throw(int nCode)
{
int* pError = new int; // Alloc int
*pError = nCode; // Set error
throw pError; // Throw
}
//-------------------------------------------
// Initialize/uninitialize functions
//-------------------------------------------
void CAgent::Init( CAgent::CNotifySink* pNotifySink )
{
Close();
CheckAndThrow ( CoCreateInstance(CLSID_AgentServer, NULL, CLSCTX_SERVER,
IID_IAgentEx, (LPVOID *)&m_pAgentEx) );
if ( pNotifySink )
{
// Register NotifySink
try
{
pNotifySink->AddRef();
CheckAndThrow ( m_pAgentEx->Register( pNotifySink, &m_lNotifySinkID ) ); // Register
m_pNotifySink = pNotifySink; // Store pointer
m_pNotifySink->m_pAgent = this;
}
catch (int *pErr)
{
// An error
pNotifySink->Release();
throw pErr;
}
}
}
void CAgent::Close()
{
// Close all characters
while (m_arChars.GetSize() > 0)
UnloadCharacter( m_arChars[0].lCharID );
// Then Unregister NotifySink and close MsAgent
if ( m_pNotifySink )
{
m_pNotifySink->m_pAgent = NULL;
m_pAgentEx->Unregister( m_lNotifySinkID );
m_pNotifySink->Release();
m_pNotifySink = NULL;
}
SAFE_RELEASE( m_pAgentEx );
}
BOOL CAgent::IsInit()
{
return (m_pAgentEx ? TRUE : FALSE );
}
void CAgent::LoadCharacter(CString strChar, long *pCharID)
{
// Declare variables
VARIANT vPath;
long lCharID = -1, lReqID;
IAgentCharacterEx* pCharacterEx = NULL;
int nPos = -1;
// Prepare character's definition file
VariantInit(&vPath);
vPath.vt = VT_BSTR;
vPath.bstrVal = strChar.AllocSysString();
#ifdef TIP
CTipWnd* pTip = NULL;
#endif
#ifdef BALLOONINPUT
CInputBalloon* pInputBalloon = NULL;
#endif
try
{
// Load character
CheckAndThrow ( m_pAgentEx->Load( vPath, &lCharID, &lReqID) );
// Get it's interface
CheckAndThrow ( m_pAgentEx->GetCharacterEx( lCharID, &pCharacterEx ) );
///////////////////////////////////
// If we are here everything is ok.
// Create tagCHAR struct and fill it
tagCHAR tagChar;
tagChar.lCharID = lCharID;
tagChar.lReqID = lReqID;
tagChar.pCharacterEx = pCharacterEx;
// Create CBalloon
tagChar.pBalloon = new CBalloon;
if ( !tagChar.pBalloon )
Throw( E_FAIL );
// Query BalloonEx interface
CheckAndThrow( pCharacterEx->QueryInterface( IID_IAgentBalloonEx, (void**)&tagChar.pBalloon->m_pBalloon ) );
RECT rectAgent;
CheckAndThrow( pCharacterEx->GetPosition( &rectAgent.left, &rectAgent.top ) );
CheckAndThrow( pCharacterEx->GetSize( &rectAgent.right, &rectAgent.bottom ) );
rectAgent.right += rectAgent.left;
rectAgent.bottom += rectAgent.top;
#ifdef TIP
pTip = new CTipWnd;
if ( !pTip->Create( "TipWnd", &(m_pNotifySink->TipProc), (long)this, lCharID ) )
Throw( E_FAIL );
pTip->Move( rectAgent );
tagChar.pTipWnd = pTip;
#endif
#ifdef BALLOONINPUT // Create MFC input ballon
pInputBalloon = new CInputBalloon;
if ( !pInputBalloon->Create( "InputBalloon", CRect(100, 100, 200, 200) ) )
Throw( E_FAIL );
pInputBalloon->Move( rectAgent );
pInputBalloon->InputNoModal = CAgent::CNotifySink::InputBalloonProc;
pInputBalloon->m_lExtra = (long)this;
pInputBalloon->m_lExtra2 = lCharID;
tagChar.pInputBalloon = pInputBalloon;
#endif
// Add struct to the array
nPos = m_arChars.Add ( tagChar );
// Return CharID
*pCharID = lCharID;
// Clean up
SysFreeString( vPath.bstrVal );
VariantClear( &vPath );
return;
}
catch (int *pErr)
{
// CleanUp
SysFreeString( vPath.bstrVal );
VariantClear( &vPath );
// Delete the struct from array if it was added
if ( nPos != -1)
m_arChars.RemoveAt ( nPos );
// Unload the character if it was loaded
if (lCharID != -1)
m_pAgentEx->Unload ( lCharID );
// Release the pointer if it is correct
SAFE_RELEASE( pCharacterEx );
#ifdef TIP
if ( pTip )
{
pTip->DestroyWindow();
pTip->~CTipWnd();
delete pTip;
}
#endif
#ifdef BALLOONINPUT
if ( pInputBalloon )
{
pInputBalloon->DestroyWindow();
pInputBalloon->~CInputBalloon();
delete pInputBalloon;
}
#endif
*pCharID = -1;
throw pErr;
}
}
// Close the character
void CAgent::UnloadCharacter(long lCharID)
{
long lIndex = GetIndexFromID( lCharID );
tagCHAR tagChar = m_arChars.GetAt( lIndex );
#ifdef TIP
// Destroy window
tagChar.pTipWnd->DestroyWindow();
delete tagChar.pTipWnd;
#endif
#ifdef BALLOONINPUT
// Destroy window
tagChar.pInputBalloon->DestroyWindow();
delete tagChar.pInputBalloon;
#endif
// Release pointers
SAFE_RELEASE( tagChar.pBalloon->m_pBalloon ); // BalloonEx
SAFE_RELEASE( tagChar.pCharacterEx ); // CharacterEx
if ( tagChar.pBalloon )
delete tagChar.pBalloon;
// And unload the character
m_pAgentEx->Unload( tagChar.lCharID );
m_arChars.RemoveAt( lIndex );
}
// If you do not set the language ID for the character, its language ID will be the current
// system language ID if the corresponding Agent language DLL is installed; otherwise,
// the character's language will be English (US).
// NOTE: all ID are enum at the beginning of the header file
// If the server finds an appropriate speech engine it will be used
void CAgent::SetLanguageID(long lLangID, long lCharID)
{
long lIndex = GetIndexFromID( lCharID );
CheckAndThrow( m_arChars[lIndex].pCharacterEx->SetLanguageID( lLangID ) );
}
long CAgent::GetLanguageID(long lCharID)
{
long lIndex = GetIndexFromID( lCharID );
long lLangID;
CheckAndThrow( m_arChars[lIndex].pCharacterEx->GetLanguageID( &lLangID ) );
return lLangID;
}
void CAgent::ShowDefaultCharacterProperties( long x, long y, BOOL bUseDefault )
{
//AllowSetForegroundWindow();
CheckAndThrow( m_pAgentEx->ShowDefaultCharacterProperties( x, y, (long)bUseDefault ) );
}
void CAgent::ShowAgentPropertySheet( BOOL bShow )
{
IAgentPropertySheet *pPropertySheet;
CheckAndThrow( m_pAgentEx->QueryInterface( IID_IAgentPropertySheet, (void**)&pPropertySheet ) );
CheckAndThrow( pPropertySheet->SetVisible( bShow ) );
pPropertySheet->Release();
}
void CAgent::GetVersion( short* pMajor, short* pMinor )
{
CheckAndThrow( m_pAgentEx->GetVersion( pMajor ,pMinor ) );
}
long CAgent::GetIndexFromID (long lID, BOOL bThrow)
{
if ( lID == -1 )
{
// The default character is wanted to be used
return GetIndexFromID( m_lDefaultCharID );
}
// Then search the array
for (int i=0; i<m_arChars.GetSize(); i++)
{
if ( m_arChars[i].lCharID == lID )
return i;
}
if ( bThrow )
Throw( -2147213310 ); // The character ID is not valid
return -1; // Return
}
void CAgent::Show(BOOL bShow, BOOL bAnimation, long lCharID)
{
long lIndex = GetIndexFromID( lCharID );
if (bShow)
CheckAndThrow( m_arChars[lIndex].pCharacterEx->Show ( !bAnimation, &m_arChars[lIndex].lReqID ) );
else
CheckAndThrow( m_arChars[lIndex].pCharacterEx->Hide ( !bAnimation, &m_arChars[lIndex].lReqID ) );
}
//-------------------------------------------
// Animation
//-------------------------------------------
void CAgent::Play(BSTR bstrAnimation, long lCharID)
{
long lIndex = GetIndexFromID( lCharID );
CheckAndThrow ( m_arChars[lIndex].pCharacterEx->Play( bstrAnimation,
&m_arChars[lIndex].lReqID ) );
}
void CAgent::Play(CString strAnimation, long lCharID)
{
CComBSTR bstrAnimation = strAnimation;
Play( bstrAnimation );
}
void CAgent::Stop(long lReqID, long lCharID)
{
long lIndex = GetIndexFromID( lCharID );
CheckAndThrow ( m_arChars[lIndex].pCharacterEx->Stop( lReqID ) );
}
void CAgent::StopAll ( long lType, long lCharID)
{
long lIndex = GetIndexFromID( lCharID );
CheckAndThrow ( m_arChars[lIndex].pCharacterEx->StopAll( lType ) );
}
void CAgent::GestureAt(int x, int y, long lCharID)
{
long lIndex = GetIndexFromID( lCharID );
CheckAndThrow ( m_arChars[lIndex].pCharacterEx->GestureAt(x, y,
&m_arChars[lIndex].lReqID ) );
}
void CAgent::GetAnimationNames(BSTR* pAnimations, long lCharID)
{
CString strAnimations;
GetAnimationNames( &strAnimations, lCharID );
*pAnimations = strAnimations.AllocSysString();
}
void CAgent::GetAnimationNames(CString* pAnimations, long lCharID)
{
IEnumVARIANT *pEnum;
VARIANT vAnimName;
DWORD dwRetrieved;
CString strAnimation;
IUnknown *punkEnum;
long lIndex = GetIndexFromID( lCharID );
// Obtain enum interface pointers
CheckAndThrow ( m_arChars[lIndex].pCharacterEx->GetAnimationNames(&punkEnum) );
CheckAndThrow ( punkEnum->QueryInterface(IID_IEnumVARIANT, (LPVOID *)&pEnum) );
while (TRUE)
{
HRESULT hRes = pEnum->Next(1, &vAnimName, &dwRetrieved);
if (hRes != NOERROR)
break;
else
CheckAndThrow( hRes );
// vAnimName.bstrVal is the animation name
strAnimation += vAnimName.bstrVal;
strAnimation += char(59);
VariantClear(&vAnimName);
}
SAFE_RELEASE( pEnum );
SAFE_RELEASE( punkEnum );
*pAnimations = strAnimation;//2.AllocSysString();
}
void CAgent::MoveTo(int x, int y, int nSpeed, long lCharID)
{
long lIndex = GetIndexFromID( lCharID );
CheckAndThrow ( m_arChars[lIndex].pCharacterEx->MoveTo(x, y, nSpeed,
&m_arChars[lIndex].lReqID ) );
}
POINT CAgent::GetPosition(long lCharID)
{
POINT point;
long lIndex = GetIndexFromID( lCharID );
CheckAndThrow ( m_arChars[lIndex].pCharacterEx->GetPosition( &point.x, &point.y ) );
return point;
}
SIZE CAgent::GetSize ( long lCharID )
{
long lIndex = GetIndexFromID( lCharID );
SIZE size;
CheckAndThrow ( m_arChars[lIndex].pCharacterEx->GetSize( &size.cx, &size.cy ) );
return size;
}
BOOL CAgent::GetVisible(long lCharID)
{
BOOL bVisible;
long lIndex = GetIndexFromID( lCharID );
CheckAndThrow ( m_arChars[lIndex].pCharacterEx->GetVisible( (long*)&bVisible ) );
return bVisible;
}
void CAgent::GetCharacterInfo(BSTR* pName, BSTR* pDescription, long lCharID)
{
long lIndex = GetIndexFromID( lCharID );
// First get the name
if ( pName )
CheckAndThrow ( m_arChars[lIndex].pCharacterEx->GetName( pName ) );
// And then the description
if ( pDescription )
CheckAndThrow ( m_arChars[lIndex].pCharacterEx->GetDescription( pDescription ) );
}
void CAgent::GetCharacterInfo(CString* pName, CString* pDescription, long lCharID)
{
BSTR bstrName, bstrDescription;
GetCharacterInfo( ( pName ? &bstrName : NULL), ( pDescription ? &bstrDescription : NULL), lCharID);
if ( pName ) *pName = bstrName;
if ( pDescription ) *pDescription = bstrDescription;
}
void CAgent::Speak(BSTR bstrText, BSTR bstrURL, long lCharID)
{
// Standart balloon
long lIndex = GetIndexFromID( lCharID );
CheckAndThrow ( m_arChars[lIndex].pCharacterEx->Speak(bstrText, bstrURL,
&m_arChars[lIndex].lReqID ) );
}
void CAgent::Speak(CString strText, CString strURL, long lCharID)
{
// Standart balloon
CComBSTR bstrText = strText, bstrURL = strURL;
Speak( bstrText, bstrURL, lCharID );
}
void CAgent::SetSoundEffects(BOOL bEnable, long lCharID)
{
long lIndex = GetIndexFromID( lCharID );
CheckAndThrow ( m_arChars[lIndex].pCharacterEx->SetSoundEffectsOn( bEnable ) );
}
BOOL CAgent::GetSoundEffects(long lCharID)
{
long lIndex = GetIndexFromID( lCharID );
BOOL bEnable;
CheckAndThrow ( m_arChars[lIndex].pCharacterEx->GetSoundEffectsOn( (long*)&bEnable ) );
return bEnable;
}
void CAgent::SetIdle(BOOL bEnable, long lCharID)
{
long lIndex = GetIndexFromID( lCharID );
CheckAndThrow ( m_arChars[lIndex].pCharacterEx->SetIdleOn( bEnable ) );
}
BOOL CAgent::GetIdle(long lCharID)
{
long lIndex = GetIndexFromID( lCharID );
BOOL bEnable;
CheckAndThrow ( m_arChars[lIndex].pCharacterEx->GetIdleOn( (long*)&bEnable ) );
return bEnable;
}
void CAgent::SetAutoPopupMenu(BOOL bEnable, long lCharID)
{
long lIndex = GetIndexFromID( lCharID );
CheckAndThrow ( m_arChars[lIndex].pCharacterEx->SetAutoPopupMenu( bEnable ) );
}
BOOL CAgent::GetAutoPopupMenu(long lCharID)
{
long lIndex = GetIndexFromID( lCharID );
BOOL bEnable;
CheckAndThrow ( m_arChars[lIndex].pCharacterEx->GetAutoPopupMenu( (long*)&bEnable ) );
return bEnable;
}
// ReqID && CBalloon && CInputBalloon
long CAgent::GetLastReqID ( long lCharID )
{
long lIndex = GetIndexFromID( lCharID );
return m_arChars[lIndex].lReqID;
}
CAgent::CBalloon* CAgent::GetBalloon ( long lCharID )
{
long lIndex = GetIndexFromID( lCharID );
return m_arChars[lIndex].pBalloon;
}
#ifdef TIP
CTipWnd* CAgent::GetTip ( long lCharID )
{
long lIndex = GetIndexFromID( lCharID );
return m_arChars[lIndex].pTipWnd;
}
#endif
#ifdef BALLOONINPUT
CInputBalloon* CAgent::GetInputBalloon ( long lCharID )
{
long lIndex = GetIndexFromID( lCharID );
return m_arChars[lIndex].pInputBalloon;
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -