Microsoft Agent Technology Application

zhaozj2021-02-08  230

Microsoft Agent Technology Application

Realization principle of at theAgentshell

[Summary]

This article describes how to apply Agent and the implementation principle of AgentShell and several important technical processes.

[Key words]

Agent, COM, Role, Speech Recognition, Speech Synthesis.

The method for programming the Agent mainly uses the language of VB, VC and other languages, in addition to this, COM directly through VC

Programming call. Adding Agent in VB is the simplest, but because the VB program itself has many defects, it is difficult to apply in practice.

In VC, since the internal Unicode encoding is completely used, it also handles a variety of complicated COM interfaces, thereby also exists.

Problem. AgentShell is a shell bundle between Agent and applications, which can connect Agent complex COM.

The mouth is encapsulated, transforming into a simple function call, which is a good implementation of the Agent control. At the same time, AgentShell also acts as an independent process.

In order to handle English automatic reading, this article will detail its implementation principle.

(1) Principle introduction

The connection of AgentShell and Agent Server is implemented through COM calls, and communication with the application is through WM_COPYDATA

The message is implemented, the following figure shows the relationship between AgentShell and other programs:

[Agent Server]

|

[COM call]

|

[Agentshell]

|

[Message]

|

[ application ]

Load an Agent Control We call "role", usually use COM call to create an Agent role,

To pass through the following procedures:

[Initialization COM]

|

[Connect Agent COM Sever, create an Agent Control]

|

[Register Agent Control Message Reactor (Notify Sink)]

|

[Load role data file, create a role (character)]

|

[Set the language, initial position, and other properties]

|

[Display role]

The following global variables are defined in the AgentShell to control the properties and action of the role:

Role Message ID: long g_lnotifysinkid.

Role ID: long g_lmyagentid.

Agent Control Pointer: IAGENTEX * G_PAGENTEX.

Role pointer: IAGENTCHARACTEREX * G_PMYAGENT.

Role Message Reactor Pointer: AgentNotifyInsink * g_psink.

Use the above variables to easily call the Agent function, such as displaying the role:

Bool agentshow ()

{

HRESULT HRES;

Long Lrequestid;

IF (! g_pmyagent)

Return False;

HRES = g_pmyagent-> show (false, & lrequestid);

IF (Failed (HRES))

Return False;

Return True;

}

(2) Language processing of roles

At present, Agent supports many languages, not only shows, but also speech synthesis and speech recognition (for Chinese, currently only supports).

Language is also divided into primary language and subordinates (or subordinates), such as Chinese's primary language is Chinese (lang_chinese), and subordinates can be

Simplified (SUBLANG_CHINESE_SIMPLIFIED) and traditional. Two global variables are defined in the AgentShell:

Main language: DWORD G_NMAINLANG.

Sub-language: DWORD G_NSUBLANG.

In this way, different information must be displayed in accordance with the different language, such as the program exiting the greeting letter:

First define different language information, you can define or resource data for macro: #define mes_goodbyel "goodbye!"

#define mes_goodbye_ch L "Goodbye!"

#define mes_goodnightl "good night!"

#define mes_goodnight_ch L "I wish you good night!"

The following is an exit prompt code:

void goodbye ()

{

IF (g_bagentok)

{

SystemTime Time;

AgentStop ();

Agentshow ();

AgentPlay (L "Wave");

GetLocalTime (& Time);

/ / Different information according to time

IF (g_nmainlang == lang_english)

{

/ / Tip English information

IF (Time.Whour <19)

AgentSpeak (Mes_Goodbye);

Else

Agentspeak (MES_GOODNIGHT);

}

Else

{

/ / Tips Chinese information

IF (Time.Whour <19)

AgentSpeak (MES_GOODBYE_CH);

Else

AgentSpeak (MES_GOODNIGHT_CH);

}

Agenethide ();

// Wait for several times

Sleep (max_quit_time);

}

}

Of course, it is only a simple method described above, and is only to describe this principle.

(3) Realizing automatic reading English

Automatic reading is actually responding to the process of clipboard messages, when copying the selected text information, the system automatically sends WM_DRAWCLIPBOARD

The message gives all the windows in all clipboard monitor queues. The corresponding window will read it aloud as soon as you read the information in the current clipboard. The specific implementation is as follows:

Install clipboard monitoring:

void installclipspy ()

{

g_hnextwnd = setClipboardViewer (g_hmainwnd);

}

The corresponding clipboard message in the callback function of the main window:

Lresult Callback WndProc (HWND HWND, UINT MESSAGE, WPARAM WPARAM, LPARAM LPARAM)

{

// Clipboard window queue changes

Case WM_CHANGECBCHAIN:

HWndremove = (hwnd) wparam; // handle of window being removed

HWndNext = (hwnd) LPARAM;

IF (hwndremove == g_hnextwnd)

{

g_hnextwnd = hwndNext;

}

IF (g_hnextwnd)

{

SendMessage (HwndNext, WM_Changecbchain, WPARAM, LPARAM);

}

// Scrapped data changes

Case WM_DRAWCLIPBOARD:

/ / Do you automatically read

IF (g_benableread)

{

// Read clipboard information

Readcliptext ();

}

IF (g_hnextwnd)

{

SendMessage (G_HNEXTWND, WM_DRAWCLIPBOARD, WPARAM, LPARAM);

}

Get the clipboard information and read it carefully:

Void ReadCliptext ()

{

IF (g_bagentok)

{

// Read only text files

IF (IsclipboardFormatavailable (cf_text))

{

IF (OpenClipboard (g_hmainwnd))

{

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];

MultibyToWideChar (CP_ACP, 0, LPSTR, -1, PWSZ, CCH);

PWSZ [CCH] = '/ 0';

Agentsavestate ();

AgentPlay (L "read");

AgentSpeak (PWSZ);

AgentPlay (l "readreturn");

AgentRestorestate ();

DELETE PWSZ;

}

GlobalUnlock (HGLB);

CloseClipboard ();

}

}

}

}

Finally, you must move the current window handle from the clipboard monitor queue when you quit:

Void RemoveClipspy ()

{

ChangeClipboardchain (g_hmainwnd, g_hnextwnd);

}

(4) Interface with external programs

The transfer data between the application and the AgentShell is mainly implemented by the WM_COPYDATA message, due to the passed data type

There is different, so you need to define a data structure to describe:

Struct AgentActionstruct

{

Word naction;

DWORD ND1;

DWORD ND2;

Wchar SDATA [MAX_DATA_LEN];

}

NACTION is used to indicate an operation that Agent should perform, such as display, performance, etc. ND1, ND2, and SDATA are used to record passed data.

Passing messages must get the handle of the AgentShell main window, as follows:

HWnd getAgentMainWnd ()

{

Return FindWindow (Agent_Class_name, NULL);

}

Since Agent uses Unicode, the ANSI character must be converted to a Unicode character:

Bool SendmestoAgent (Word ND2, DWORD ND1, DWORD ND2, LPCSTR SDATA)

{

Uint nsize;

HWND HWND = GetagentMainWnd ();

IF (hwnd)

{

Action.nAction = nAction;

Action.nd1 = (dword) ND1;

Action.nd2 = (DWORD) ND2;

// Convert ANSI to Unicode characters

nsize = multibytetowideChar (CP_ACP, 0, SDATA, LSTRLEN (SDATA) 1,

Action.sdata, Max_Data_Len;

Action.sdata [nsize] = '/ 0';

//

CopyDataStruct CDS;

Cds.dwdata = (dword) 0;

Cds.cbdata = (dword) sizeof (action);

Cds.lpdata = (void *) & Action;

// Exchange data with AgentShell via WM_COPYDATA message

SendMessage (HWND, WM_COPYDATA, (WPARAM) NULL, (LPARAM) & CDS);

Return True;

}

Return False;

}

The function provided by AgentShell is mainly:

// Start the role shell (agentshell) BRUN is executed

Bool Agentapirun (Bool Brun = True); // Exit Role Housing (AgentShell)

Bool agentapiExit ();

// Create a new role (Spath Role Data File Path, NSUBLANG Language)

Bool AgentApicreate (LPCSTR Spath, Uint NLANG, UINT NSUBLANG);

/ / Set the role name (Sname role name)

Bool AgentapiSetName (LPCSTR sname);

// Uninstall the role

Bool agentapiunload ();

// Display role

Bool ageapishow ();

// Hide role

Bool agentapihide ();

// Show or hide the role

Bool agentapishoworhide ();

// Stop role performance

Bool ageapistop ();

// Role show (SACTION action name)

Bool AgentapiPlay (LPCSTR SACTION);

// Role Speech (Stext sentence)

Bool Agentapispeak (LPCSTR Stext);

// Role 鞠 (x, y "direction)

Bool Agentapigesat (Word X, Word Y);

/ / Mobile role to the specified location (coordinate of x, y)

Bool Agentapimoveto (Word X, Word Y);

/ / Save the current role display status

Bool ageapisavestate ();

// Restore the status of the role

Bool agentapirestorestate ();

// Allow automatic reading

Bool agentapienableautoread ();

// Do not automatically read

Bool ageapidisableautoread ();

Note that the data passed to the AgentShell should not exceed 1K (actually generally not more than 1k).

2) Use the interface

With the interface functions described above, the control of the Agent is very simple, the following is an example of a simple greeting:

// Start AgentShell

IF (Agentapirun (TRUE))

{

/ / Save the status of the current Agent

Agentapisavestate ();

// Start performance

AgentapiPlay (_T ("Greet"));

// Speech

Agentapispeak (_T ("Hello, My Friend."));

// End of performance

AgentapiPlay (_T ("GreetReturn"));

// Restore the original state

AgentapiRestorestate ();

// drop out

AgentapiExit ();

}

AgentShell has been very good in the author's free software "My Assistant", of course, is currently only a small part of the Agent, as well as speech recognition, nothing to do, and to be improved. The above programs are compiled by Visual C 6.0, and the source code can be downloaded to the House of Assistant (http://www.helperhome.com).

转载请注明原文地址:https://www.9cbs.com/read-2307.html

New Post(0)