home *** CD-ROM | disk | FTP | other *** search
/ Developing for Microsoft …tive Animated Characters / DEV_AGENTA.ISO / Examples / c / hello2 / Hello2.cpp next >
C/C++ Source or Header  |  1997-08-19  |  7KB  |  304 lines

  1. #include "Hello2.h"
  2. #include "AgtSvr_i.c"
  3. #include "Notify.h"
  4.  
  5.  
  6. //==========================================================================
  7. //
  8. //  THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
  9. //  KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
  10. //  IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
  11. //  PURPOSE.
  12. //
  13. //  Copyright (C) 1997 Microsoft Corporation.  All Rights Reserved.
  14. //
  15. //--------------------------------------------------------------------------
  16. //
  17. // This sample demonstrates the simplest Microsoft Agent application that
  18. // uses a notification sink.
  19. //
  20. //==========================================================================
  21.  
  22.  
  23. static const LPWSTR kpwszCharacter = L"\\Program Files\\Microsoft Agent\\characters\\genie.acs";
  24. static const LPTSTR kpszAppTitle = _T("Microsoft Agent Samples");
  25.  
  26. extern long g_lDone = 0;
  27.  
  28.  
  29. // This function checks to see if the version of Microsoft Agent
  30. // installed on the user's system is compatible with the version
  31. // we compiled with, i.e. it's version is greater than or equal to
  32. // constants defined in AgentServer.h.  Microsoft Agent guarantees
  33. // backward compatibility.
  34.  
  35. BOOL IsValidAgentVersion(IAgent *pAgent) {
  36.  
  37.     HRESULT hRes;
  38.     IDispatch *pdAgent = NULL;
  39.     ITypeInfo *pTypeInfo = NULL;
  40.     ITypeLib *pTypeLib = NULL;
  41.     TLIBATTR *pTypeLibAttr = NULL;
  42.     BOOL bValid = FALSE;
  43.     UINT uiIndex;
  44.  
  45.     __try {
  46.  
  47.         // Query for IDispatch
  48.  
  49.         hRes = pAgent->QueryInterface(IID_IDispatch, (LPVOID *)&pdAgent);
  50.  
  51.         if (FAILED(hRes))
  52.             __leave;
  53.  
  54.         // Get the TypeInfo
  55.  
  56.         hRes = pdAgent->GetTypeInfo(0, 0, &pTypeInfo);
  57.  
  58.         if (FAILED(hRes))
  59.             __leave;
  60.  
  61.         // Get it's containing TypeLib
  62.  
  63.         hRes = pTypeInfo->GetContainingTypeLib(&pTypeLib, &uiIndex);
  64.  
  65.         if (FAILED(hRes))
  66.             __leave;
  67.  
  68.         // Get the attributes of the TypeLib
  69.  
  70.         hRes = pTypeLib->GetLibAttr(&pTypeLibAttr);
  71.  
  72.         if (FAILED(hRes))
  73.             __leave;
  74.  
  75.         // Check the major and minor versions of the type library
  76.         // to those in AgentServer.h.
  77.  
  78.         if ((pTypeLibAttr->wMajorVerNum > AGENT_VERSION_MAJOR) ||
  79.             ((pTypeLibAttr->wMajorVerNum == AGENT_VERSION_MAJOR) &&
  80.              (pTypeLibAttr->wMinorVerNum >= AGENT_VERSION_MINOR)))
  81.             bValid = TRUE;
  82.  
  83.     }
  84.     __finally {
  85.     }
  86.  
  87.     if (pTypeLib) {
  88.  
  89.         if (pTypeLibAttr)
  90.             pTypeLib->ReleaseTLibAttr(pTypeLibAttr);
  91.  
  92.         pTypeLib->Release();
  93.     }
  94.  
  95.     if (pTypeInfo)
  96.         pTypeInfo->Release();
  97.  
  98.     if (pdAgent)
  99.         pdAgent->Release();
  100.  
  101.     return bValid;
  102. }
  103.  
  104.  
  105. extern "C" int PASCAL WinMain(HINSTANCE hInst,
  106.                               HINSTANCE hInstPrev,
  107.                               LPSTR lpCmdLine,
  108.                               int nCmdShow) {
  109.  
  110.     HRESULT                hRes;
  111.     _TCHAR                szError[256];
  112.     VARIANT                vPath;
  113.     BSTR                bszSpeak;
  114.     MSG                    msg;
  115.     long                lCharID;
  116.     long                lRequestID;
  117.     long                lNotifySinkID = -1;
  118.     IAgent               *pAgent;
  119.     IDispatch           *pdCharacter;
  120.     IAgentCharacter    *pCharacter = NULL;
  121.     AgentNotifySink       *pSink = NULL;
  122.     
  123.     // Initialize OLE
  124.  
  125.     if (FAILED(OleInitialize(NULL))) {
  126.         MessageBox(NULL, 
  127.                    _T("There was an error initializing OLE."), 
  128.                    kpszAppTitle, 
  129.                    MB_OK | MB_ICONERROR);
  130.         return -1;
  131.     }
  132.  
  133.     // Create an instance of the Agent server
  134.  
  135.     hRes = CoCreateInstance(CLSID_AgentServer,
  136.                             NULL,
  137.                             CLSCTX_SERVER,
  138.                             IID_IAgent,
  139.                             (LPVOID *)&pAgent);
  140.     if (FAILED(hRes)) {
  141.  
  142.         wsprintf(szError, _T("There was an error initializing Microsoft Agent, code = 0x%x"), hRes);
  143.  
  144.         MessageBox(NULL, 
  145.                    szError, 
  146.                    kpszAppTitle, 
  147.                    MB_OK | MB_ICONERROR);
  148.         return -1;
  149.     }
  150.  
  151.     // Check to see if it is a compatible version
  152.  
  153.     if (!IsValidAgentVersion(pAgent)) {
  154.  
  155.         pAgent->Release();
  156.  
  157.         MessageBox(NULL,
  158.                    _T("The version of Microsoft Agent installed on this system is out of date.\nUpgrade to a new version of Microsoft Agent."),
  159.                    kpszAppTitle,
  160.                    MB_OK | MB_ICONEXCLAMATION | MB_TOPMOST);
  161.         return -1;
  162.     }
  163.  
  164.     // Create a notify sink
  165.  
  166.     pSink = new AgentNotifySink;
  167.  
  168.     if (pSink == NULL) {
  169.  
  170.         MessageBox(NULL, 
  171.                    _T("Out of memory!"), 
  172.                    kpszAppTitle, 
  173.                    MB_OK | MB_ICONERROR);
  174.  
  175.         return -1;
  176.     }
  177.  
  178.     pSink->AddRef();
  179.  
  180.     // And register it with Microsoft Agent
  181.  
  182.     hRes = pAgent->Register((IUnknown *)pSink, &lNotifySinkID);
  183.  
  184.     if (FAILED(hRes))
  185.         return -1;
  186.  
  187.     // Create a variant to store the full path of the character to load
  188.  
  189.     VariantInit(&vPath);
  190.  
  191.     vPath.vt = VT_BSTR;
  192.     vPath.bstrVal = SysAllocString(kpwszCharacter);
  193.  
  194.     if (vPath.bstrVal == NULL) {
  195.  
  196.         MessageBox(NULL, 
  197.                    _T("Out of memory!"), 
  198.                    kpszAppTitle, 
  199.                    MB_OK | MB_ICONERROR);
  200.  
  201.         return -1;
  202.     }
  203.  
  204.     try {
  205.  
  206.         // Load the character
  207.  
  208.         hRes = pAgent->Load(vPath, &lCharID, &lRequestID);
  209.  
  210.         if (FAILED(hRes))
  211.             throw hRes;
  212.  
  213.         // Get it's dispinterface
  214.  
  215.         hRes = pAgent->GetCharacter(lCharID, &pdCharacter);
  216.  
  217.         if (FAILED(hRes))
  218.             throw hRes;
  219.  
  220.         // Query for IAgentCharacter
  221.  
  222.         hRes = pdCharacter->QueryInterface(IID_IAgentCharacter, (LPVOID *)&pCharacter);
  223.  
  224.         // Release the IDispatch
  225.  
  226.         pdCharacter->Release();
  227.  
  228.         // Did we get the IAgentCharacter interface?
  229.  
  230.         if (FAILED(hRes))
  231.             throw hRes;
  232.  
  233.         // Show the character.  The first parameter tells Microsoft
  234.         // Agent to show the character by playing an animation.
  235.  
  236.         hRes = pCharacter->Show(FALSE, &lRequestID);
  237.  
  238.         if (FAILED(hRes))
  239.             throw hRes;
  240.  
  241.         // Make the character speak
  242.  
  243.         bszSpeak = SysAllocString(L"Hello World!");
  244.  
  245.         hRes = pCharacter->Speak(bszSpeak, NULL, &g_lDone);
  246.  
  247.         SysFreeString(bszSpeak);
  248.  
  249.         if (FAILED(hRes))
  250.             throw hRes;
  251.  
  252.     }
  253.     catch (HRESULT) {
  254.  
  255.         wsprintf(szError, _T("An error occurred in Microsoft Agent, code = 0x%x"), hRes);
  256.  
  257.         MessageBox(NULL, 
  258.                    szError, 
  259.                    kpszAppTitle, 
  260.                    MB_OK | MB_ICONERROR);
  261.     }
  262.  
  263.     // Start the message loop.  A WM_QUIT message will be posted
  264.     // when we get the RequestComplete notification from Microsoft Agent.
  265.  
  266.     if (SUCCEEDED(hRes)) {
  267.         while (GetMessage(&msg, NULL, 0, 0) > 0)
  268.             DispatchMessage(&msg);
  269.     }
  270.  
  271.     // Clean up
  272.  
  273.     if (pCharacter) {
  274.  
  275.         // Release the character interface
  276.  
  277.         pCharacter->Release();
  278.  
  279.         // Unload the character.  NOTE:  releasing the character
  280.         // interface does NOT make the character go away.  You must
  281.         // call Unload.
  282.  
  283.         pAgent->Unload(lCharID);
  284.     }
  285.     
  286.     // Release objects
  287.  
  288.     if (pSink) {
  289.  
  290.         if (lNotifySinkID != -1)
  291.             pAgent->Unregister(lNotifySinkID);
  292.  
  293.         pSink->Release();
  294.     }
  295.  
  296.     pAgent->Release();
  297.  
  298.     VariantClear(&vPath);
  299.  
  300.     OleUninitialize();
  301.  
  302.     return 0;
  303. }
  304.