www.pudn.com > agentnet.zip > AgentNetClientDlg.cpp
// AgentNetClientDlg.cpp : implementation file
//
#include "stdafx.h"
#include "AgtSvr.h"
#include "AgtSvr_i.c"
#include "AgentNetClient.h"
#include "AgentNetClientDlg.h"
#include "logindlg.h"
#include "toserversocket.h"
#include "msg.h"
#include "sendgeneralmsgdlg.h"
#include "receivegeneralmsgdlg.h"
#include "notify.h"
#include "common.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
//agent 定义
long g_lNotifySinkID = -1;
/////////////////////////////////////////////////////////////////////////////
// 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()
/////////////////////////////////////////////////////////////////////////////
// CAgentNetClientDlg dialog
CAgentNetClientDlg::CAgentNetClientDlg(CWnd* pParent /*=NULL*/)
: CDialog(CAgentNetClientDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CAgentNetClientDlg)
// 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);
}
void CAgentNetClientDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CAgentNetClientDlg)
DDX_Control(pDX, IDC_TREE, m_TreeCtrl);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CAgentNetClientDlg, CDialog)
//{{AFX_MSG_MAP(CAgentNetClientDlg)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_WM_DESTROY()
ON_WM_TIMER()
ON_NOTIFY(NM_DBLCLK, IDC_TREE, OnDblclkTree)
ON_COMMAND(ID_MENUITEM_AGENT_HIDE, OnMenuitemAgentHide)
ON_COMMAND(ID_MENUITEM_AGENT_READ_NEWS, OnMenuitemAgentReadNews)
ON_COMMAND(ID_MENUITEM_EXIT_AGENT_NET, OnMenuitemExitAgentNet)
ON_COMMAND(ID_MENUITEM_READ_CLIPBORAD, OnMenuitemReadClipborad)
ON_COMMAND(ID_MENUITEM_STOP_ALL, OnMenuitemStopAll)
ON_COMMAND(ID_MENUITEM_SET_CAN_SPEAK, OnMenuitemSetCanSpeak)
ON_COMMAND(ID_MENUITEM_SET_CANNOT_SPEAK, OnMenuitemSetCannotSpeak)
ON_COMMAND(ID_MENUITEM_GET_MAIL, OnMenuitemGetMail)
ON_COMMAND(ID_MENUITEM_READ_MAIL, OnMenuitemReadMail)
//}}AFX_MSG_MAP
//语音识别事件消息处理
ON_MESSAGE(WM_RECOEVENT,ProcessRecoEvent)
//在AGENT上弹出右键菜单
ON_MESSAGE(WM_SHOW_POP_MENU,ShowPopupMenu)
//邮件账号没设定事件消息处理
ON_MESSAGE(WM_MAIL_ACCOUNT_NOT_SET,ProcessMailAccountNotSet)
//邮件账号没设定事件消息处理
ON_MESSAGE(WM_MAIL_CANNOT_LOGIN,ProcessMailCannotLogin)
//有邮件要处理事件消息处理
ON_MESSAGE(WM_MAIL_PROCESS,ProcessReadMail)
//没有新邮件要处理事件消息处理
ON_MESSAGE(WM_MAIL_NO_NEW_MAIL,ProcessNoMail)
//邮件处理完成事件消息处理
ON_MESSAGE(WM_MAIL_PROCESS_DONE,ProcessMailDone)
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CAgentNetClientDlg message handlers
BOOL CAgentNetClientDlg::OnInitDialog()
{
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);
if (pSysMenu != NULL)
{
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
InitSetup(); //初始化设置
InitOthers(); //初始化好友烈表时钟
InitSocket(); //初始化网络socket
InitTree(); //初始化好友树
InitSR(); //初始化SR语音识别引擎
InitTTS(); //初始化TTS语音合成引擎
InitAgent(); //初始化agent接口
InitMailAccount(); //初始化邮件账号
return TRUE; // return TRUE unless you set the focus to a control
}
void CAgentNetClientDlg::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 CAgentNetClientDlg::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 CAgentNetClientDlg::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
}
void CAgentNetClientDlg::OnReceive()
{
do
{
//接收消息
ReceiveMsg();
if (m_pSocket==NULL)
return;
}
while (!m_pArchiveIn->IsBufferEmpty());
}
void CAgentNetClientDlg::InitSocket()
{
//初始化socket
m_pSocket=m_pLoginDlg->m_pSocket;
//创建CSocketFile类对象
m_pFile=new CSocketFile(m_pSocket);
//创建CArchive类对象
m_pArchiveIn=new CArchive(m_pFile,CArchive::load);
m_pArchiveOut=new CArchive(m_pFile,CArchive::store);
//设定socket为online 可以让socket调用主对话框
m_pSocket->SetOnLine();
m_pSocket->SetMainDlg(this);
}
void CAgentNetClientDlg::InitTree()
{
CAgentNetClientApp *pApp=(CAgentNetClientApp *)AfxGetApp();//取得控制程序
m_ImageList.Create(16,16,ILC_COLOR,0,1); //建立16*16图像控制
m_ImageList.SetBkColor(RGB(255,255,255));
m_ImageList.Add(pApp->LoadIcon(IDI_ICON_MEMBER1)); //增加好友图像
//树控件
m_TreeCtrl.SetImageList(&m_ImageList,TVSIL_NORMAL); //设置图像控制列表
m_TreeCtrl.DeleteAllItems();
AskServerListOnlineBuddy();
}
void CAgentNetClientDlg::InitOthers()
{
m_strUserName=m_pLoginDlg->m_strUserName;
m_bProcessMailThread=FALSE;
//改变对话框标题为用户名
SetWindowText(m_strUserName);
//开列好友时钟 8秒钟更新
SetTimer(1,8*1000,NULL);
}
void CAgentNetClientDlg::AskServerListOnlineBuddy()
{
CMsg* pMsg=new CMsg;
pMsg->m_strCommand="ask_server_list_online_buddy";
pMsg->m_strUser=m_strUserName;
SendMsg(pMsg);
}
void CAgentNetClientDlg::SendMsg(CMsg *pMsg)
{
if (m_pArchiveOut!=NULL)
{
TRY
{
//发送消息
pMsg->Serialize(*m_pArchiveOut);
//将CArchive对象中数据强制存储到CSocketFile对象中
m_pArchiveOut->Flush();
}
CATCH(CFileException,e)
{
//错误处理
m_pArchiveOut->Abort();
delete m_pArchiveOut;
m_pArchiveOut=NULL;
CString strTemp;
strTemp="服务器重置连接!";
AfxMessageBox(strTemp);
}
END_CATCH
}
}
void CAgentNetClientDlg::ReceiveMsg()
{
CMsg msg;
TRY
{
//接收消息
msg.Serialize(*m_pArchiveIn);
if (msg.m_strCommand!="")
{
if (msg.m_strToUser==m_strUserName)
{
if (msg.m_strCommand=="reply_server_list_online_buddy")
{
//处理更新好友列表信息
ProcessReplyListOnlineBuddy(msg.m_strText);
}
if (msg.m_strCommand=="buddy_logout")
{
//处理好友下线信息
ProcessBuddyLogout(msg.m_strText);
}
if (msg.m_strCommand=="receive_general_message")
{
//处理好友信息
ProcessReceiveGeneralMsg(msg.m_strUser,msg.m_strText);
}
if (msg.m_strCommand=="request_read_news")
{
//处理好友下线信息
ProcessRequestReadNews(msg.m_strText);
}
}
}
}
CATCH(CFileException,e)
{
//错误处理
m_pArchiveOut->Abort();
CString strTemp;
strTemp="连接关闭!";
AfxMessageBox(strTemp);
}
END_CATCH
}
void CAgentNetClientDlg::OnDestroy()
{
// TODO: Add your message handler code here
LogOut();
ReleaseAgent();
ReleaseTTS();
ReleaseSR();
CoUninitialize();
CDialog::OnDestroy();
}
void CAgentNetClientDlg::OnTimer(UINT nIDEvent)
{
// TODO: Add your message handler code here and/or call default
//好友列表更新
if (nIDEvent==1)
{
AskServerListOnlineBuddy();
}
//语音命令
if (nIDEvent==2)
{
KillTimer(2);
SetHearCommand(FALSE);
m_bWantExit=FALSE;
m_bAnswer=FALSE;
AgentStop();
}
CDialog::OnTimer(nIDEvent);
}
void CAgentNetClientDlg::ProcessReplyListOnlineBuddy(CString strUserName)
{
//处理更新好友列表信息
int nTreeCount;
int nTemp;
CString strTempUserName;
strTempUserName="";
BOOL bFound=FALSE;
HTREEITEM tempItem=m_TreeCtrl.GetRootItem();
//若客户端没有,添加
nTreeCount=m_TreeCtrl.GetCount();
for (nTemp=1;nTemp<=nTreeCount;nTemp++)
{
strTempUserName=m_TreeCtrl.GetItemText(tempItem);
if (strUserName==strTempUserName)
bFound=TRUE;
tempItem=m_TreeCtrl.GetNextItem(tempItem,TVGN_NEXT);
}
if (bFound==FALSE)
{
//添加到树上
HTREEITEM hRoot = m_TreeCtrl.InsertItem(strUserName, 0, 0, TVI_ROOT, TVI_LAST);
m_TreeCtrl.Expand(hRoot, TVE_EXPAND);
//通知用户
AgentPlay("Pleased");
AgentSpeak("你的好友 "+strUserName+" 登陆了!");
}
}
void CAgentNetClientDlg::ProcessBuddyLogout(CString strUserName)
{
//若此好友以前在线,删除他
int nTreeCount;
int nTemp;
CString strTempUserName;
strTempUserName="";
BOOL bFound=FALSE;
HTREEITEM tempItem=m_TreeCtrl.GetRootItem();
nTreeCount=m_TreeCtrl.GetCount();
for (nTemp=1;nTemp<=nTreeCount;nTemp++)
{
strTempUserName=m_TreeCtrl.GetItemText(tempItem);
if (strUserName==strTempUserName)
{
bFound=TRUE;
break;
}
tempItem=m_TreeCtrl.GetNextItem(tempItem,TVGN_NEXT);
}
if (bFound==TRUE)
{
//从树上删除
m_TreeCtrl.DeleteItem(tempItem);
}
}
void CAgentNetClientDlg::LogOut()
{
//退出网络
if ((m_pSocket!=NULL)&&(m_pFile!=NULL)&&(m_pArchiveOut!=NULL))
{
//发送客户离开的消息
CMsg msg;
msg.m_strCommand="logout_agent_net";
msg.m_strUser=m_strUserName;
msg.m_strToUser=SERVER_AGENT_NAME;
msg.Serialize(*m_pArchiveOut);
m_pArchiveOut->Flush();
}
//删除CArchive对象
delete m_pArchiveOut;
m_pArchiveOut=NULL;
//删除CArchive对象
delete m_pArchiveIn;
m_pArchiveIn=NULL;
delete m_pFile;
//删除CSOcketFile对象
m_pFile=NULL;
if (m_pSocket!=NULL)
{
BYTE Buffer[50];
m_pSocket->ShutDown();
while (m_pSocket->Receive(Buffer,50)>0);
}
delete m_pSocket;
m_pSocket=NULL;
}
void CAgentNetClientDlg::OnDblclkTree(NMHDR* pNMHDR, LRESULT* pResult)
{
// TODO: Add your control notification handler code here
HTREEITEM SelItem=m_TreeCtrl.GetSelectedItem( );
CString strToUserName;
strToUserName=m_TreeCtrl.GetItemText(SelItem);
CSendGeneralMsgDlg dlg;
dlg.m_strToUserName=strToUserName;
if (dlg.DoModal()==IDOK)
{
ProcessSendGeneralMsg(strToUserName,dlg.m_strText);
}
*pResult = 0;
}
void CAgentNetClientDlg::ProcessSendGeneralMsg(CString strToUserName, CString strText)
{
//发送一般消息到好友
CMsg* pMsg=new CMsg;
pMsg->m_strCommand="send_general_message";
pMsg->m_strUser=m_strUserName;
pMsg->m_strToUser=strToUserName;
pMsg->m_strText=strText;
SendMsg(pMsg);
}
void CAgentNetClientDlg::ProcessReceiveGeneralMsg(CString strUserName, CString strText)
{
/*
CReceiveGeneralMsgDlg RevDlg;
RevDlg.m_strText=strText;
RevDlg.m_strFromUserName=strUserName;
RevDlg.DoModal();
if (RevDlg.m_bReply==TRUE)
{
//回复
CSendGeneralMsgDlg SendDlg;
SendDlg.m_strToUserName=strUserName;
if (SendDlg.DoModal()==IDOK)
{
ProcessSendGeneralMsg(strUserName,SendDlg.m_strText);
}
}
*/
//提示有消息
AgentPlay("GetAttentionContinued");
AgentSpeak(strUserName+" 对你说:");
Sleep(100);
// AgentPlay("GetAttentionReturn");
AgentSpeak(strText);
}
BOOL CAgentNetClientDlg::InitAgent()
{
//初始化agent
HRESULT hRes;
VARIANT vPath;
_TCHAR szError[256];
m_pCharacterEx=NULL;
if (FAILED(CoInitialize(NULL)))
{
MessageBox(_T("There was an error initializing COM."));
}
hRes = CoCreateInstance(CLSID_AgentServer,
NULL,
CLSCTX_SERVER,
IID_IAgentEx,
(LPVOID *)&m_pAgentEx);
if (FAILED(hRes))
{
MessageBox(_T("There was an error initializing Microsoft Agent, code = 0x%x"));
CoUninitialize();
return -1;
}
CString strPath = m_stuSetup.strAgentCharPath;
VariantInit(&vPath);
vPath.vt = VT_BSTR;
vPath.bstrVal = SysAllocString(strPath.AllocSysString());
// Load the character
hRes = m_pAgentEx->Load(vPath, &m_lCharID, &m_lRequestID);
if (FAILED(hRes))
{
AfxMessageBox("装入agent人物数据时出错!");
return FALSE;
}
// Get its IAgentCharacterEx interface
hRes = m_pAgentEx->GetCharacterEx(m_lCharID, &m_pCharacterEx);
hRes = m_pCharacterEx->SetLanguageID(MAKELANGID(LANG_CHINESE,SUBLANG_CHINESE_SIMPLIFIED));
//装入notify sink
try
{
// Create a notify sink
m_pSink = new AgentNotifySink;
if (m_pSink == NULL) {
hRes = E_OUTOFMEMORY;
return FALSE;
}
// AddRef it
m_pSink->AddRef();
// And register it with Microsoft Agent
hRes = m_pAgentEx->Register(m_pSink, &g_lNotifySinkID);
if (FAILED(hRes))
return FALSE;
}
catch(...)
{
if (FAILED(hRes))
{
wsprintf(szError, _T("注册Agent时发生错误, 错误代码:0X%x.\r请检查Agent 2.0安装是否正确."), hRes);
::MessageBox(NULL,
szError,
_T("AgentNetClient"),
MB_OK | MB_ICONERROR | MB_TOPMOST);
return FALSE;
}
}
//设置在notify sink 对像内的dlg 指针
m_pSink->SetDlgHwnd(GetSafeHwnd());
m_pCharacterEx->SetAutoPopupMenu(FALSE);
// Show the character. The first parameter tells Microsoft
// Agent to show the character by playing an animation.
//gentSpeak("hello"):
hRes = m_pCharacterEx->Show(FALSE, &m_lRequestID);
AgentPlay("Greet");
AgentSpeak("你好"+m_strUserName);
//清除OLE变量
VariantClear(&vPath);
return TRUE;
}
void CAgentNetClientDlg::ReleaseAgent()
{
if (m_pCharacterEx)
{
//所再见
m_pCharacterEx->Stop(m_lRequestID);
AgentPlay("Wave");
AgentSpeak("再见!");
Sleep(3000);
//释放IAgentCharacter接口
m_pCharacterEx->Release();
m_pCharacterEx = NULL;
//卸载动画人物数据
m_pAgentEx->Unload(m_lCharID);
}
if (m_pSink)
{
if (g_lNotifySinkID != -1)
m_pAgentEx->Unregister(g_lNotifySinkID);
m_pSink->Release();
m_pSink = NULL;
}
//释放Agent对象
m_pAgentEx->Release();
CoUninitialize();
}
void CAgentNetClientDlg::AgentPlay(CString strAnimation)
{
//放agent动画
HRESULT hRes;
BSTR bszPlay;
//bszPlay =strAnimation.AllocSysString();
bszPlay=SysAllocString(strAnimation.AllocSysString());
hRes=m_pCharacterEx->Play(bszPlay,&m_lRequestID);
SysFreeString(bszPlay);
}
void CAgentNetClientDlg::AgentSpeak(CString strSpeak)
{
// Make the character speak
HRESULT hRes;
BSTR bszSpeak;
bszSpeak =strSpeak.AllocSysString();
// AgentPlay("Explain");
//语言合成
if( m_cpTTSVoice != NULL )
{
m_cpTTSVoice->Speak(bszSpeak, SPF_ASYNC,NULL );
}
//显示有说的话
hRes = m_pCharacterEx->Think(bszSpeak, &m_lRequestID);
SysFreeString(bszSpeak);
}
void CAgentNetClientDlg::InitTTS()
{
if( FAILED(CoInitialize(NULL)) )
{
AfxMessageBox("初始化TTS引擎是出错!");
// Terminate the application
} // Else full speed ahead!
//初始化TTS
if( SUCCEEDED( CoCreateInstance( CLSID_SpVoice, NULL, CLSCTX_INPROC, IID_ISpVoice, (void**)&m_cpTTSVoice)))
{
m_cpTTSVoice->AddRef();
}
else
{
m_cpTTSVoice = NULL;
}
if( m_cpTTSVoice != NULL )
{
m_cpTTSVoice->SetRate( 2 );
}
//
m_bEnableTTS=TRUE;
}
void CAgentNetClientDlg::ReleaseTTS()
{
if (m_cpTTSVoice!=NULL)
{
m_cpTTSVoice->Release();
m_cpTTSVoice = NULL;
}
}
void CAgentNetClientDlg::InitSR()
{
// test is COM is successfully initialized
if (FAILED( CoInitialize( NULL ) ) )
{
AfxMessageBox("CoInitialize 初始化失败!");
return;
}
HRESULT hr = S_OK;
// create a recognition engine
hr = m_cpEngine.CoCreateInstance(CLSID_SpSharedRecognizer);
if ( FAILED(hr) )
{
AfxMessageBox("CoCreateInstance 初始化失败!");
return;
}
// create the command recognition context
hr = m_cpEngine->CreateRecoContext( &m_cpRecoCtxt );
if ( FAILED( hr ) )
{
AfxMessageBox("CreateRecoContext 初始化失败!");
return;
}
// Let SR know that window we want it to send event information to, and using
// what message
hr = m_cpRecoCtxt->SetNotifyWindowMessage(m_hWnd, WM_RECOEVENT, 0, 0 );
if ( FAILED( hr ) )
{
AfxMessageBox("SetNotifyWindowMessage初始化失败!");
return;
}
// Tell SR what types of events interest us. Here we only care about command
// recognition.
hr = m_cpRecoCtxt->SetInterest( SPFEI(SPEI_RECOGNITION), SPFEI(SPEI_RECOGNITION) );
if ( FAILED( hr ) )
{
AfxMessageBox("SetInterest 初始化失败!");
return;
}
// Load our grammar, 文件名为 SRGrammar.cfg
hr = m_cpRecoCtxt->CreateGrammar(GRAMMARID1, &m_cpCmdGrammar);
if (FAILED(hr))
{
AfxMessageBox("CreateGrammar 初始化失败!");
return;
}
//从cfg文件装入语法
hr = m_cpCmdGrammar->LoadCmdFromFile(L"srgrammar.cfg",SPLO_DYNAMIC);
if ( FAILED( hr ) )
{
AfxMessageBox("LoadCmdFromFile 装入语法时失败!");
return;
}
// Set rules to active, we are now listening for commands
//使不能接受命令,直到喊agent的名字
SetHearCommand(FALSE);
if ( FAILED( hr ) )
{
AfxMessageBox("SetRuleIdState(MyName) 失败!");
return;
}
m_bWantExit=FALSE;
m_bAnswer=FALSE;
}
void CAgentNetClientDlg::ReleaseSR()
{
// Release grammar, if loaded
if ( m_cpCmdGrammar )
{
m_cpCmdGrammar.Release();
}
// Release recognition context, if created
if ( m_cpRecoCtxt )
{
m_cpRecoCtxt->SetNotifySink(NULL);
m_cpRecoCtxt.Release();
}
// Release recognition engine instance, if created
if ( m_cpEngine )
{
m_cpEngine.Release();
}
}
void CAgentNetClientDlg::ProcessRecoEvent()
{
CSpEvent event; // Event helper class
// Loop processing events while there are any in the queue
while (event.GetFrom(m_cpRecoCtxt) == S_OK)
{
// Look at recognition event only
switch (event.eEventId)
{
case SPEI_RECOGNITION:
ExecuteSRCommand(event.RecoResult());
break;
}
}
}
void CAgentNetClientDlg::ExecuteSRCommand(ISpPhrase *pPhrase)
{
HRESULT hr = S_OK;
WCHAR* pwszText;
// get the phrase's entire text string, including replacements
hr = pPhrase->GetText(SP_GETWHOLEPHRASE,SP_GETWHOLEPHRASE, TRUE, &pwszText, NULL);
SPPHRASE *pElements;
if (SUCCEEDED(pPhrase->GetPhrase(&pElements)))
{
switch(pElements->Rule.ulId)
{
case VID_MyName:
{
// AfxMessageBox("lt");
StartHearing();
}
break;
case VID_ReadNews:
{
switch( pElements->pProperties->vValue.ulVal )
{
case VID_News://看新闻
{
//AfxMessageBox("in");
ProcessReadNews();
}
break;
}
SetHearCommand(FALSE);
}
break;
case VID_GetMail:
{ //收邮件
OnMenuitemGetMail();
SetHearCommand(FALSE);
}
case VID_ReadMail:
{ //读邮件
OnMenuitemReadMail();
SetHearCommand(FALSE);
}
break;
case VID_StopAll:
{
//停止动作
OnMenuitemStopAll();
SetHearCommand(FALSE);
}
case VID_AnswerYes:
{
//回答是
//若问了问题
if (m_bWantExit)
m_bAnswer=TRUE;
//ProcessAnswerExit();
SetHearCommand(FALSE);
}
case VID_AnswerNo:
{
//回答否
//若问了问题
if (m_bWantExit)
m_bAnswer=FALSE;
//ProcessAnswerExit();
SetHearCommand(FALSE);
}
case VID_Exit:
{
//退出程序
//ProcessExit();
}
break;
}
// Free the pElements memory which was allocated for us
::CoTaskMemFree(pElements);
}
}
void CAgentNetClientDlg::ShowPopupMenu()
{
CPoint point;
point = (CPoint) GetMessagePos();
ScreenToClient(&point);
CMenu menu;
CMenu *pPopup;
if (!menu.LoadMenu(IDR_MENU_MAIN))
{
AfxMessageBox("menu error!");
return;
}
pPopup = menu.GetSubMenu(0);
if (m_bEnableTTS==TRUE)
{
pPopup->CheckMenuItem(ID_MENUITEM_SET_CAN_SPEAK,MF_BYCOMMAND | MF_CHECKED);
pPopup->CheckMenuItem(ID_MENUITEM_SET_CANNOT_SPEAK,MF_BYCOMMAND | MF_UNCHECKED);
}
else
{
pPopup->CheckMenuItem(ID_MENUITEM_SET_CAN_SPEAK,MF_BYCOMMAND | MF_UNCHECKED);
pPopup->CheckMenuItem(ID_MENUITEM_SET_CANNOT_SPEAK,MF_BYCOMMAND | MF_CHECKED);
}
ClientToScreen(&point);
pPopup->TrackPopupMenu( TPM_LEFTALIGN|TPM_LEFTBUTTON,point.x, point.y, this);
PostMessage(WM_NULL, 0, 0);
DestroyMenu(menu);
}
void CAgentNetClientDlg::OnMenuitemAgentHide()
{
// TODO: Add your command handler code here
//隐藏AGENT
AgentSpeak("我走了!");
AgentPlay("Hide");
}
void CAgentNetClientDlg::OnMenuitemAgentReadNews()
{
// TODO: Add your command handler code here
ProcessReadNews();
}
void CAgentNetClientDlg::ProcessReadNews()
{
CMsg* pMsg=new CMsg;
pMsg->m_strCommand="ask_read_news";
pMsg->m_strUser=m_strUserName;
// pMsg->m_strText=strText;
SendMsg(pMsg);
}
void CAgentNetClientDlg::ProcessRequestReadNews(CString strNews)
{
AgentStop();
AgentSpeak(strNews);
}
void CAgentNetClientDlg::OnMenuitemExitAgentNet()
{
// TODO: Add your command handler code here
CDialog::OnOK();
}
void CAgentNetClientDlg::StartHearing()
{
AgentStop();
AgentPlay("Hearing_1");
StartHearingTimer();
SetHearCommand(TRUE);
}
void CAgentNetClientDlg::StartHearingTimer()
{
SetTimer(2,3*1000,0);
}
void CAgentNetClientDlg::AgentStop()
{
m_pCharacterEx->StopAll(STOP_TYPE_ALL);
}
void CAgentNetClientDlg::SetHearCommand(BOOL bActive)
{
if (bActive==TRUE)
{
//除了MyName其他都是可以
m_cpCmdGrammar->SetRuleState(NULL,NULL,SPRS_ACTIVE);
m_cpCmdGrammar->SetRuleIdState(VID_MyName,SPRS_INACTIVE);
}
else
{
//除了MyName其他都不可以
m_cpCmdGrammar->SetRuleState(NULL,NULL,SPRS_INACTIVE);
m_cpCmdGrammar->SetRuleIdState(VID_MyName,SPRS_ACTIVE);
}
}
void CAgentNetClientDlg::OnMenuitemReadClipborad()
{
// TODO: Add your command handler code here
if( IsClipboardFormatAvailable(CF_TEXT))
{
if (OpenClipboard())
{
LPWSTR pwsz;
UINT cch;
HGLOBAL hglb;
LPSTR lpstr;
hglb = GetClipboardData(CF_TEXT);
lpstr = (LPSTR)GlobalLock(hglb);
cch = lstrlen(lpstr);
if( cch > 0)
{
pwsz = new WCHAR[cch + 1];
MultiByteToWideChar(CP_ACP, 0, lpstr, -1, pwsz, cch);
pwsz[cch] = '\0';
AgentPlay("Read");
AgentSpeak(pwsz);
AgentPlay("ReadReturn");
delete pwsz;
}
GlobalUnlock(hglb);
CloseClipboard();
}
}
}
void CAgentNetClientDlg::OnMenuitemStopAll()
{
// TODO: Add your command handler code here
AgentStop();
OnMenuitemSetCannotSpeak();
OnMenuitemSetCanSpeak();
}
void CAgentNetClientDlg::OnMenuitemSetCanSpeak()
{
// TODO: Add your command handler code here
//设置tts继续
m_cpTTSVoice->Resume();
}
void CAgentNetClientDlg::OnMenuitemSetCannotSpeak()
{
// TODO: Add your command handler code here
//设置tts暂停
m_cpTTSVoice->Skip(L"SENTENCE",100000,NULL);
m_cpTTSVoice->Pause();
}
UINT GetMailThread(LPVOID pParam)
{
//收有邮件进程处理函数
stuThreadInfo* pstuInfo=(stuThreadInfo*)pParam;
//若用户信息(包括邮箱地址,登陆名,密码)还没设置,退出)
//并发没设置消息
if (pstuInfo->m_bUserSet==FALSE)
{
::PostMessage(pstuInfo->m_hWnd,WM_MAIL_PROCESS_DONE,0,0);
::PostMessage(pstuInfo->m_hWnd,WM_MAIL_ACCOUNT_NOT_SET,0,0);
return 0;
}
//读邮箱信息
CPOP3 pop3(pstuInfo->m_strMailServer);
pop3.SetUserProperties(pstuInfo->m_strMailAccount,pstuInfo->m_strMailPassword);
if (!pop3.Connect())
{
::PostMessage(pstuInfo->m_hWnd,WM_MAIL_PROCESS_DONE,0,0);
::PostMessage(pstuInfo->m_hWnd,WM_MAIL_CANNOT_LOGIN,0,0);
return 0;
}
//取新邮件数量
int iMsgNumber=0;
iMsgNumber=pop3.GetNumMessages();
if (iMsgNumber==0)
{
::PostMessage(pstuInfo->m_hWnd,WM_MAIL_PROCESS_DONE,0,0);
::PostMessage(pstuInfo->m_hWnd,WM_MAIL_NO_NEW_MAIL,0,0);
return 0;
}
//若有邮件,读第一封
CMailMessage msg;
if (!pop3.GetMessage(1,&msg))
{
::PostMessage(pstuInfo->m_hWnd,WM_MAIL_PROCESS_DONE,0,0);
::PostMessage(pstuInfo->m_hWnd,WM_MAIL_CANNOT_LOGIN,0,0);
return 0;
}
if( !pop3.Disconnect() )
{
// AfxMessageBox( pop3.GetLastError() );
return 0;
}
//AfxMessageBox( _T( "Successfully disconnected" ) );
//发消息到主线程,有邮件要处理
pstuInfo->m_strFrom=msg.m_sFrom;
pstuInfo->m_strSubject=msg.m_sSubject;
pstuInfo->m_strBody=msg.m_sBody;
pstuInfo->m_iMsgNumber=iMsgNumber;
::PostMessage(pstuInfo->m_hWnd,WM_MAIL_PROCESS_DONE,0,0);
::PostMessage(pstuInfo->m_hWnd,WM_MAIL_PROCESS,0,0);
return 0;
}
void CAgentNetClientDlg::OnMenuitemGetMail()
{
// TODO: Add your command handler code here
if (m_bProcessMailThread==TRUE)
return;
//表演处理
AgentStop();
AgentPlay("Searching");
AgentSpeak("好的,收邮件");
//收邮件
//使可收邮件
m_bProcessMailThread=TRUE;
m_stuThreadInfo.m_bUserSet=TRUE;
//开新线程首邮件
AfxBeginThread(GetMailThread,&m_stuThreadInfo,THREAD_PRIORITY_NORMAL);
}
void CAgentNetClientDlg::InitMailAccount()
{
HWND hWnd;
hWnd=GetSafeHwnd();
m_stuThreadInfo.m_hWnd=hWnd;
m_stuThreadInfo.m_bUserSet=FALSE;
m_stuThreadInfo.m_iMsgNumber=0;
m_stuThreadInfo.m_strMailServer=m_stuSetup.strMailServer;
m_stuThreadInfo.m_strMailAccount=m_stuSetup.strMailAccount;
m_stuThreadInfo.m_strMailPassword=m_stuSetup.strMailPassword;
m_bProcessMailThread=FALSE;
}
void CAgentNetClientDlg::ProcessMailAccountNotSet()
{
AgentStop();
AgentPlay("Decline");
AgentSpeak("邮件账号没设定!");
}
void CAgentNetClientDlg::ProcessMailCannotLogin()
{
AgentStop();
AgentPlay("Decline");
AgentSpeak("现在登陆不到邮箱!");
}
void CAgentNetClientDlg::ProcessReadMail()
{
if (m_stuThreadInfo.m_iMsgNumber<1)
{
ProcessNoMail();
return;
}
CString strFrom,strSubject,strBody;
strFrom=m_stuThreadInfo.m_strFrom;
strSubject=m_stuThreadInfo.m_strSubject;
strBody=m_stuThreadInfo.m_strBody;
AgentStop();
AgentPlay("Congratulate");
AgentSpeak("你有一封发自 "+strFrom+" 的邮件!");
}
void CAgentNetClientDlg::ProcessNoMail()
{
AgentStop();
AgentPlay("Sad");
AgentPlay("Decline");
AgentSpeak("没有邮件!");
}
void CAgentNetClientDlg::OnMenuitemReadMail()
{
// TODO: Add your command handler code here
if (m_stuThreadInfo.m_iMsgNumber<1)
{
ProcessNoMail();
return;
}
CString strFrom,strSubject,strBody;
strFrom=m_stuThreadInfo.m_strFrom;
strSubject=m_stuThreadInfo.m_strSubject;
strBody=m_stuThreadInfo.m_strBody;
AgentStop();
AgentPlay("Reading");
AgentSpeak(strFrom+" 的邮件!");
AgentSpeak("主题是 "+strSubject);
AgentSpeak("内容是 "+strBody);
AgentStop();
AgentPlay("ReadReturn");
}
void CAgentNetClientDlg::ProcessExit()
{
AgentStop();
AgentPlay("Suggest");
AgentSpeak("真的吗?");
m_bWantExit=TRUE;
}
void CAgentNetClientDlg::ProcessAnswerExit()
{
if (m_bWantExit==FALSE)
return;
if (m_bAnswer==FALSE)
return;
CDialog::OnOK();
}
void CAgentNetClientDlg::InitSetup()
{
m_stuSetup.strAgentCharPath=m_pLoginDlg->m_stuSetup.strAgentCharPath;
m_stuSetup.strServerIpAddress=m_pLoginDlg->m_stuSetup.strServerIpAddress;
m_stuSetup.strMailServer=m_pLoginDlg->m_stuSetup.strMailServer;
m_stuSetup.strMailAccount=m_pLoginDlg->m_stuSetup.strMailAccount;
m_stuSetup.strMailPassword=m_pLoginDlg->m_stuSetup.strMailPassword;
}
void CAgentNetClientDlg::ProcessMailDone()
{
m_bProcessMailThread=FALSE;
Sleep(500);
}