📄 csdn_文档中心_microsoft agent技术应用.htm
字号:
Agent控制指针: IAgentEx *g_pAgentEx。<BR> 角色指针: IAgentCharacterEx
*g_pMyAgent。<BR> 角色消息反应器指针: AgentNotifySink
*g_pSink。<BR><BR> 使用以上变量可很容易的调用Agent的功能,如显示角色:<BR>
BOOL agentShow()<BR> {<BR>
HRESULT hRes;<BR> long
lRequestID;<BR><BR> if(
!g_pMyAgent)<BR> return
FALSE;<BR> hRes =
g_pMyAgent->Show(FALSE, &lRequestID);<BR>
if (FAILED(hRes))<BR>
return FALSE;<BR> return
TRUE;<BR> }<BR><BR> (二) 角色的语言处理<BR>
目前Agent支持很多种语言,不仅是显示,还有语音合成和语音识辨(对于中文,目前仅支持显示)。<BR>语言又分为主语言和子语言(或为副语言),如中文的主语言为中文(LANG_CHINESE),子语言则可为<BR>简体(SUBLANG_CHINESE_SIMPLIFIED)和繁体等。AgentShell中定义两个全局变量表达角色的语种:<BR><BR>
主语言:DWORD g_nMainLang。<BR> 子语言:DWORD g_nSubLang。<BR>
这样程序内必须根据当前语言的不同来显示不同的信息,如程序退出时的问候信:<BR>
首先定义不同的语言信息,可以为宏定义或资源数据:<BR> #define
MES_GOODBYEL"Goodbye!"<BR> #define MES_GOODBYE_CH
L"再见!"<BR> #define MES_GOODNIGHTL"Good night!"<BR>
#define MES_GOODNIGHT_CH L"祝您晚安!"<BR> 以下为实现退出提示代码:<BR>
void Goodbye()<BR> {<BR> if(
g_bAgentOK)<BR> {<BR>
SYSTEMTIME time;<BR>
agentStop();<BR>
agentShow();<BR>
agentPlay(L"Wave");<BR>
GetLocalTime(&time);<BR> //
根据时间不同提示不同信息<BR> if( g_nMainLang
== LANG_ENGLISH)<BR> {<BR>
// 提示英文信息<BR>
if( time.wHour <
19)<BR>
agentSpeak(MES_GOODBYE);<BR>
else<BR>
agentSpeak(MES_GOODNIGHT);<BR>
}<BR> else<BR>
{<BR>
// 提示中文信息<BR>
if( time.wHour < 19)<BR>
agentSpeak(MES_GOODBYE_CH);<BR>
else<BR>
agentSpeak(MES_GOODNIGHT_CH);<BR>
}<BR> agentHide();<BR>
// 等待若干时间<BR>
Sleep(MAX_QUIT_TIME);<BR>
}<BR> }<BR> 当然以上介绍的只是一种较为简单的方法,仅在于描述这种原理。<BR><BR>
(三) 实现自动朗读英文<BR>
实现自动朗读实际上是响应剪贴板消息的过程,当复制选种的文本信息时,系统自动发送WM_DRAWCLIPBOARD<BR>消息给所有剪贴板监视队列中的窗口,相应的窗口只要读取当前剪贴板内的信息进行朗读即可,具体实现如下:<BR><BR>
安装剪贴板监视:<BR> void InstallClipSpy()<BR> {<BR>
g_hNextWnd =
SetClipboardViewer(g_hMainWnd);<BR> }<BR> <BR>
主窗口的回调函数中相应剪贴板消息:<BR> LRESULT CALLBACK WndProc(HWND hWnd, UINT
message, WPARAM wParam, LPARAM lParam)<BR> {<BR>
// 剪贴板窗口队列发生变化<BR> case WM_CHANGECBCHAIN:<BR>
hwndRemove = (HWND)wParam; // handle of window being removed
<BR> hwndNext = (HWND) lParam; <BR> if(
hwndRemove == g_hNextWnd)<BR> {<BR>
g_hNextWnd = hwndNext;<BR> }<BR>
if( g_hNextWnd)<BR> {<BR>
SendMessage(hwndNext, WM_CHANGECBCHAIN, wParam, lParam);<BR>
}<BR> // 剪贴数据发生变化<BR> case
WM_DRAWCLIPBOARD:<BR> // 是否自动阅读<BR> if(
g_bEnableRead)<BR> {<BR> //
阅读剪贴板信息<BR> ReadClipText();<BR>
}<BR> if( g_hNextWnd)<BR> {<BR>
SendMessage(g_hNextWnd,WM_DRAWCLIPBOARD,wParam,
lParam);<BR> }<BR> 获取剪贴板信息并且朗读:<BR> void
ReadClipText()<BR> {<BR> if(
g_bAgentOK)<BR> { <BR>
// 只有文本文件才朗读<BR>
if( IsClipboardFormatAvailable(CF_TEXT))<BR>
{<BR>
if (OpenClipboard(g_hMainWnd)) <BR>
{<BR>
LPWSTR pwsz;<BR>
UINT
cch;<BR>
HGLOBAL hglb;<BR>
LPSTR lpstr;<BR><BR>
hglb =
GetClipboardData(CF_TEXT);<BR>
lpstr =
(LPSTR)GlobalLock(hglb);<BR>
cch = lstrlen(lpstr);<BR>
if( cch >
0)<BR>
{<BR>
pwsz = new WCHAR[cch + 1];<BR>
MultiByteToWideChar(CP_ACP, 0, lpstr, -1, pwsz, cch);<BR>
pwsz[cch] = '\0';<BR>
agentSaveState();<BR>
agentPlay(L"Read");<BR>
agentSpeak(pwsz);<BR>
agentPlay(L"ReadReturn");<BR>
agentRestoreState();<BR>
delete pwsz;<BR>
}<BR>
GlobalUnlock(hglb);<BR>
CloseClipboard();<BR>
}<BR>
}<BR> }<BR>
}<BR> 最后还须在程序退出时将当前窗口句柄从剪贴板监视队列移走:<BR> void
RemoveClipSpy()<BR> {<BR>
ChangeClipboardChain(g_hMainWnd, g_hNextWnd);<BR>
}<BR><BR> (四) 与外部程序的接口<BR>
应用程序和AgentShell之间传递数据主要通过WM_COPYDATA消息实现,由于传递的数据类型各<BR>有不同,所以需要定义一个数据结构来描述:<BR>
struct AgentActionSTRUCT<BR> {<BR>
WORD nAction;<BR> DWORD
nD1;<BR> DWORD nD2;<BR>
WCHAR sData[MAX_DATA_LEN];<BR>
};<BR>
nAction用来表示Agent应该执行的操作,如显示、表演等。nD1,nD2,sData用来记录传递的数据。<BR>传递消息必须获取AgentShell主窗口的句柄,实现如下:<BR>
HWND GetAgentMainWnd()<BR> {<BR>
return FindWindow(AGENT_CLASS_NAME, NULL);<BR>
}<BR> 由于Agent采用了UNICODE,
必须将ANSI字符转化为UNICODE字符:<BR> BOOL SendMesToAgent(WORD
nAction, DWORD nD1, DWORD nD2, LPCSTR sData)<BR>
{<BR> UINT nSize;<BR>
HWND hWnd = GetAgentMainWnd();<BR>
if( hWnd)<BR> {<BR>
action.nAction = nAction;<BR>
action.nD1 = (DWORD)nD1;<BR> action.nD2 =
(DWORD)nD2;<BR> //
将ANSI符转换为UNICODE的字符<BR> nSize =
MultiByteToWideChar(CP_ACP, 0, sData, lstrlen(sData) + 1, <BR>
action.sData, MAX_DATA_LEN);<BR>
action.sData[nSize] = '\0';<BR>
//<BR> COPYDATASTRUCT
cds;<BR> cds.dwData = (DWORD)0;<BR>
cds.cbData = (DWORD)sizeof(action);<BR>
cds.lpData = (VOID *)&action;<BR>
// 通过WM_COPYDATA消息与AgentShell交换数据<BR>
SendMessage(hWnd, WM_COPYDATA, (WPARAM)NULL,
(LPARAM)&cds);<BR> return
TRUE;<BR> }<BR>
return FALSE; <BR> }<BR>
目前AgentShell提供的函数主要有:<BR> // 启动角色外壳程序(AgentShell)
bRun是否执行<BR> BOOL agentAPIRun(BOOL bRun =
TRUE);<BR> // 退出角色外壳程序(AgentShell)<BR>
BOOL agentAPIExit();<BR> // 创建一个新角色(sPath角色数据文件路径,
nLang主语言, nSubLang子语言)<BR> BOOL agentAPICreate(LPCSTR
sPath, UINT nLang, UINT nSubLang);<BR> //
设置角色名字(sName角色名字)<BR> BOOL agentAPISetName(LPCSTR
sName);<BR> // 将角色卸载<BR> BOOL
agentAPIUnload();<BR> // 显示角色<BR> BOOL
agentAPIShow();<BR> // 隐藏角色<BR> BOOL
agentAPIHide();<BR> // 显示或隐藏角色<BR> BOOL
agentAPIShowORHide();<BR> // 停止角色表演<BR>
BOOL agentAPIStop();<BR> // 角色表演(sAction动作名称)<BR>
BOOL agentAPIPlay(LPCSTR sAction);<BR> //
角色讲话(sText句子)<BR> BOOL agentAPISpeak(LPCSTR
sText);<BR> // 角色鞠躬(x,y 指方向)<BR> BOOL
agentAPIGesAt(WORD x, WORD y);<BR> //
移动角色到指定的位置(x,y移动的坐标)<BR> BOOL agentAPIMoveTo(WORD x,
WORD y);<BR> // 保存当前角色显示状态<BR> BOOL
agentAPISaveState();<BR> // 恢复角色的状态<BR>
BOOL agentAPIRestoreState();<BR> // 允许自动阅读<BR>
BOOL agentAPIEnableAutoRead();<BR> //
禁止自动阅读<BR> BOOL agentAPIDisableAutoRead();<BR>
注意传递给AgentShell的数据长度不要超过1K(实际上一般不会大于1K)。<BR> 2)
使用接口<BR>
有了以上介绍的接口函数,对Agent的控制变的很简单,以下是一个简单的问候示例:<BR> //
启动AgentShell<BR> if( agentAPIRun(TRUE))<BR>
{<BR> // 保存当前Agent的状态<BR>
agentAPISaveState();<BR> //
开始表演<BR> agentAPIPlay(_T("Greet"));<BR>
// 讲话<BR> agentAPISpeak(_T("hello,
my friend."));<BR> // 表演结束<BR>
agentAPIPlay(_T("GreetReturn"));<BR> //
恢复原来状态<BR> agentAPIRestoreState(); <BR>
// 退出<BR>
agentAPIExit();<BR> }<BR><BR>
AgentShell在笔者的免费软件"我的助手"中得到很好的利用,当然目前其仅涉及了Agent的一小部分内容,还有如语音识辨等,未做处理,还有待一步改进。以上程序在Visual
C++
6.0编译通过,源代码可到助手之家(http://www.helperHome.com)下载。<BR><BR><BR></TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE><BR>
<TABLE align=center bgColor=#006699 border=0 cellPadding=0 cellSpacing=0
width=770>
<TBODY>
<TR bgColor=#006699>
<TD align=middle bgColor=#006699 id=white><FONT
color=#ffffff>对该文的评论</FONT></TD>
<TD align=middle>
<SCRIPT src="CSDN_文档中心_Microsoft Agent技术应用.files/readnum.htm"></SCRIPT>
</TD></TR></TBODY></TABLE><BR>
<DIV align=center>
<TABLE align=center bgColor=#cccccc border=0 cellPadding=2 cellSpacing=1
width=770>
<TBODY>
<TR>
<TH bgColor=#006699 id=white><FONT
color=#ffffff>我要评论</FONT></TH></TR></TBODY></TABLE></DIV>
<DIV align=center>
<TABLE border=0 width=770>
<TBODY>
<TR>
<TD>你没有登陆,无法发表评论。 请先<A
href="http://www.csdn.net/member/login.asp?from=/Develop/read_article.asp?id=310">登陆</A>
<A
href="http://www.csdn.net/expert/zc.asp">我要注册</A><BR></TD></TR></TBODY></TABLE></DIV><BR>
<HR noShade SIZE=1 width=770>
<TABLE border=0 cellPadding=0 cellSpacing=0 width=500>
<TBODY>
<TR align=middle>
<TD height=10 vAlign=bottom><A
href="http://www.csdn.net/intro/intro.asp?id=2">网站简介</A> - <A
href="http://www.csdn.net/intro/intro.asp?id=5">广告服务</A> - <A
href="http://www.csdn.net/map/map.shtm">网站地图</A> - <A
href="http://www.csdn.net/help/help.asp">帮助信息</A> - <A
href="http://www.csdn.net/intro/intro.asp?id=2">联系方式</A> - <A
href="http://www.csdn.net/english">English</A> </TD>
<TD align=middle rowSpan=3><A
href="http://www.hd315.gov.cn/beian/view.asp?bianhao=010202001032100010"><IMG
border=0 height=48 src="CSDN_文档中心_Microsoft Agent技术应用.files/biaoshi.gif"
width=40></A></TD></TR>
<TR align=middle>
<TD vAlign=top>百联美达美公司 版权所有 京ICP证020026号</TD></TR>
<TR align=middle>
<TD vAlign=top><FONT face=Verdana>Copyright © CSDN.net, Inc. All rights
reserved</FONT></TD></TR>
<TR>
<TD height=15></TD>
<TD></TD></TR></TBODY></TABLE></DIV>
<DIV></DIV><!--内容结束//--><!--结束//--></BODY></HTML>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -