HELLO2.CPP

#include "Hello2.h" 
#include "AgtSvr_i.c"
#include "Notify.h"


//==========================================================================
//
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
// KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
// PURPOSE.
//
// Copyright (C) 1997 Microsoft Corporation. All Rights Reserved.
//
//--------------------------------------------------------------------------
//
// This sample demonstrates the simplest Microsoft Agent application that
// uses a notification sink.
//
//==========================================================================


static const LPWSTR kpwszCharacter = L"\\Program Files\\Microsoft Agent\\characters\\genie.acs";
static const LPTSTR kpszAppTitle = _T("Microsoft Agent Samples");

extern long g_lDone = 0;


// This function checks to see if the version of Microsoft Agent
// installed on the user's system is compatible with the version
// we compiled with, i.e. it's version is greater than or equal to
// constants defined in AgentServer.h. Microsoft Agent guarantees
// backward compatibility.

BOOL IsValidAgentVersion(IAgent *pAgent) {

HRESULT hRes;
IDispatch *pdAgent = NULL;
ITypeInfo *pTypeInfo = NULL;
ITypeLib *pTypeLib = NULL;
TLIBATTR *pTypeLibAttr = NULL;
BOOL bValid = FALSE;
UINT uiIndex;

__try {

// Query for IDispatch

hRes = pAgent->QueryInterface(IID_IDispatch, (LPVOID *)&pdAgent);

if (FAILED(hRes))
__leave;

// Get the TypeInfo

hRes = pdAgent->GetTypeInfo(0, 0, &pTypeInfo);

if (FAILED(hRes))
__leave;

// Get it's containing TypeLib

hRes = pTypeInfo->GetContainingTypeLib(&pTypeLib, &uiIndex);

if (FAILED(hRes))
__leave;

// Get the attributes of the TypeLib

hRes = pTypeLib->GetLibAttr(&pTypeLibAttr);

if (FAILED(hRes))
__leave;

// Check the major and minor versions of the type library
// to those in AgentServer.h.

if ((pTypeLibAttr->wMajorVerNum > AGENT_VERSION_MAJOR) ||
((pTypeLibAttr->wMajorVerNum == AGENT_VERSION_MAJOR) &&
(pTypeLibAttr->wMinorVerNum >= AGENT_VERSION_MINOR)))
bValid = TRUE;

}
__finally {
}

if (pTypeLib) {

if (pTypeLibAttr)
pTypeLib->ReleaseTLibAttr(pTypeLibAttr);

pTypeLib->Release();
}

if (pTypeInfo)
pTypeInfo->Release();

if (pdAgent)
pdAgent->Release();

return bValid;
}


extern "C" int PASCAL WinMain(HINSTANCE hInst,
HINSTANCE hInstPrev,
LPSTR lpCmdLine,
int nCmdShow) {

HRESULThRes;
_TCHARszError[256];
VARIANTvPath;
BSTRbszSpeak;
MSGmsg;
longlCharID;
longlRequestID;
longlNotifySinkID = -1;
IAgent *pAgent;
IDispatch *pdCharacter;
IAgentCharacter *pCharacter = NULL;
AgentNotifySink *pSink = NULL;

// Initialize OLE

if (FAILED(OleInitialize(NULL))) {
MessageBox(NULL,
_T("There was an error initializing OLE."),
kpszAppTitle,
MB_OK | MB_ICONERROR);
return -1;
}

// Create an instance of the Agent server

hRes = CoCreateInstance(CLSID_AgentServer,
NULL,
CLSCTX_SERVER,
IID_IAgent,
(LPVOID *)&pAgent);
if (FAILED(hRes)) {

wsprintf(szError, _T("There was an error initializing Microsoft Agent, code = 0x%x"), hRes);

MessageBox(NULL,
szError,
kpszAppTitle,
MB_OK | MB_ICONERROR);
return -1;
}

// Check to see if it is a compatible version

if (!IsValidAgentVersion(pAgent)) {

pAgent->Release();

MessageBox(NULL,
_T("The version of Microsoft Agent installed on this system is out of date.\nUpgrade to a new version of Microsoft Agent."),
kpszAppTitle,
MB_OK | MB_ICONEXCLAMATION | MB_TOPMOST);
return -1;
}

// Create a notify sink

pSink = new AgentNotifySink;

if (pSink == NULL) {

MessageBox(NULL,
_T("Out of memory!"),
kpszAppTitle,
MB_OK | MB_ICONERROR);

return -1;
}

pSink->AddRef();

// And register it with Microsoft Agent

hRes = pAgent->Register((IUnknown *)pSink, &lNotifySinkID);

if (FAILED(hRes))
return -1;

// Create a variant to store the full path of the character to load

VariantInit(&vPath);

vPath.vt = VT_BSTR;
vPath.bstrVal = SysAllocString(kpwszCharacter);

if (vPath.bstrVal == NULL) {

MessageBox(NULL,
_T("Out of memory!"),
kpszAppTitle,
MB_OK | MB_ICONERROR);

return -1;
}

try {

// Load the character

hRes = pAgent->Load(vPath, &lCharID, &lRequestID);

if (FAILED(hRes))
throw hRes;

// Get it's dispinterface

hRes = pAgent->GetCharacter(lCharID, &pdCharacter);

if (FAILED(hRes))
throw hRes;

// Query for IAgentCharacter

hRes = pdCharacter->QueryInterface(IID_IAgentCharacter, (LPVOID *)&pCharacter);

// Release the IDispatch

pdCharacter->Release();

// Did we get the IAgentCharacter interface?

if (FAILED(hRes))
throw hRes;

// Show the character. The first parameter tells Microsoft
// Agent to show the character by playing an animation.

hRes = pCharacter->Show(FALSE, &lRequestID);

if (FAILED(hRes))
throw hRes;

// Make the character speak

bszSpeak = SysAllocString(L"Hello World!");

hRes = pCharacter->Speak(bszSpeak, NULL, &g_lDone);

SysFreeString(bszSpeak);

if (FAILED(hRes))
throw hRes;

}
catch (HRESULT) {

wsprintf(szError, _T("An error occurred in Microsoft Agent, code = 0x%x"), hRes);

MessageBox(NULL,
szError,
kpszAppTitle,
MB_OK | MB_ICONERROR);
}

// Start the message loop. A WM_QUIT message will be posted
// when we get the RequestComplete notification from Microsoft Agent.

if (SUCCEEDED(hRes)) {
while (GetMessage(&msg, NULL, 0, 0) > 0)
DispatchMessage(&msg);
}

// Clean up

if (pCharacter) {

// Release the character interface

pCharacter->Release();

// Unload the character. NOTE: releasing the character
// interface does NOT make the character go away. You must
// call Unload.

pAgent->Unload(lCharID);
}

// Release objects

if (pSink) {

if (lNotifySinkID != -1)
pAgent->Unregister(lNotifySinkID);

pSink->Release();
}

pAgent->Release();

VariantClear(&vPath);

OleUninitialize();

return 0;
}